-
-
Save swiftgeek/570d3ff3e700f8699c16 to your computer and use it in GitHub Desktop.
Just for archlinux and still needs heavy testing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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!" | |
[[ "$1" =~ ^[a-z0-9@_+.-]+$ ]] || fail_msg "First arg is not a valid pkgname" | |
pkgname="$1" | |
if [ -n "$2" ] && [[ "$2" =~ ^[a-z0-9@_.]+-[0-9]+$ ]]; then | |
target_pkgver="$2" | |
elif [ -n "$2" ]; then | |
fail_msg "Wrong format of second argument!" | |
fi | |
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