Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@swiftgeek
Last active February 13, 2017 15:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swiftgeek/570d3ff3e700f8699c16 to your computer and use it in GitHub Desktop.
Save swiftgeek/570d3ff3e700f8699c16 to your computer and use it in GitHub Desktop.
Just for archlinux and still needs heavy testing
#!/bin/bash
# Repo desc: Changes pkgver and pkgrel of installed package
#
# Changeling: Changes package ($1) version directly in pacman's db to a version given in $2 or $target_pkgver
# Example uses:
# Just downgrade to 0-0 to force update (default):
# changeling firefox-nightly
# For specific version:
# changeling firefox-nightly 666-666
#
# Author: Swift Geek swiftgeek@gmɐil.com
#TODO: Provide help message for bad amount of args
#TODO: Detect syntax error and write some message to log
# We don't care about epoch till somebody wants it
info_log() {
echo "changeling: $1" # Check if not null ?
echo "changeling: $1" >> /var/log/pacman.log #Disable stderr?
return 0
}
fail_log() {
echo "changeling: $1"
echo "changeling: $1" >> /var/log/pacman.log
exit 1
}
fail_msg() {
echo "changeling: $1"
exit 1
}
# Check for root and if has tty - run sudo
if [ $UID != 0 ]; then
tty -s
if [ $? = 0 ]; then
/usr/bin/sudo -i $(realpath -s $0) $@ && exit 0
exit 1
else
fail_msg "This script needs to be executed as root!"
fi
fi
# Set variables
target_pkgver=0-0
if [ -L "$0" ]; then
# If started from symlink
shname=`basename $0`
if [[ "$shname" =~ ^[a-z0-9@_+.-]+-[a-z0-9@_.]+-[0-9]+$ ]]; then
pkgname="${shname%-[a-z0-9@_.]*-[0-9]*}" # fix this perhaps * instead of + ? nah we know it's right from upper regex
target_pkgver=${shname:${#pkgname}+1}
elif [[ "$shname" =~ ^[a-z0-9@_+.-]+$ ]]; then
pkgname="$shname"
else
fail_msg "Invalid symlink filename - not a package"
fi
else
# If started via script
[ -z "$@" ] && fail_msg "No args were passed!"
[ $# -gt 2 ] && fail_msg "Too many arguments passed!"
pkgname="$1"
[ -n "$2" ] && [[ "$2" =~ ^[0-9]*-[0-9]*$ ]] && target_pkgver="$2"
fi
#Check && query pacman
pgrep -x pacman > /dev/null
[ "$?" = "0" ] && fail_msg "Pacman is up and running"
/usr/bin/pacman -Qsq "$pkgname" > /dev/null
[ "$?" != "0" ] && fail_msg "Package not found?"
orig_pkgver=$(/usr/bin/pacman -Qs "^$pkgname\$" | grep 'local/' | awk '{print $2}')
if [ -z "$orig_pkgver" ] || [ -z $target_pkgver ] ; then
fail_msg "Pacman query failed"
elif [ "$orig_pkgver" = "$target_pkgver" ]; then
echo 'Already downgraded!'
exit 0
fi
pkgdir="/var/lib/pacman/local/${pkgname}" # WARNING: doesn't contain version
# Lock DB
[ -e /var/lib/pacman/db.lck ] && fail_msg "Pacman DB already locked!"
#RW stage
echo "$$" > /var/lib/pacman/db.lck
[ "$?" != 0 ] && fail_msg "Failed to lock pacman db"
info_log "Downgrading $pkgname $orig_pkgver to $target_pkgver"
# Actual changing
if [ -d "${pkgdir}-${orig_pkgver}" ]; then
sed -i '/\%VERSION\%/{n; s/.*/'"$target_pkgver"'/}' "${pkgdir}-${orig_pkgver}/desc"
[ "$?" != 0 ] && fail_log "Failed at sedding desc file. No harm was done"
mv "${pkgdir}-${orig_pkgver}" "${pkgdir}-${target_pkgver}"
[ "$?" != 0 ] && fail_log "Failed at renaming pkgdir. Pacman DB is slightly broken at this point"
else
fail_log "Pacman DB might be broken"
fi
rm /var/lib/pacman/db.lck
# RW stage gone
# Basic RO check
if [ -d "${pkgdir}-${target_pkgver}" ]; then
check_pkgver=$(awk '/^%VERSION%$/ { getline; print $0 }' "${pkgdir}-${target_pkgver}/desc" )
if [ "$check_pkgver" = "$target_pkgver" ]; then
info_log 'Success'
exit 0
else
fail_log "RO check failed."
fi
fi
fail_msg 'Failed wtf'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment