#!/bin/bash # Queries the ABS # License: GPL3 ## TODO # * Add license text # * Create symlinks from pkgbase to pkgname[@] for easy package finding # * Use lastsync to store processed packages ## GOALS # * Have a searchable database of PKGBUILD metadata # * Have an interface for source-only builds # * Possibility to hook up ABS dirs besides ABSROOT (low priority) # * Tell updates and non available binary packages (working on this) source /etc/abs.conf source /etc/libretools.conf source /etc/libretools.d/prtools.conf # Stores the lastsync date lastsync() { [ -e ${lastsyncfile} -a ! -w ${lastsyncfile} ] && { error "The sync date can't be saved. ${lastsyncfile} isn't writable." return 1 } date +%s > "$lastsyncfile" touch "$lastsyncfile" } ## # usage : get_full_version( $epoch, $pkgver, $pkgrel ) # return : full version spec, including epoch (if necessary), pkgver, pkgrel ## get_full_version() { if [[ $1 -eq 0 ]]; then # zero epoch case, don't include it in version echo $2-$3 else echo $1:$2-$3 fi } # Outputs an ordered package-fullpkgver array print_package_array() { echo "$@" | tr " " "\n" | sort -V -u } # Gets repo.db contents # $1 repo get_db_contents() { [ ! -r /var/lib/pacman/sync/$1.db ] && return 0 bsdtar -tf /var/lib/pacman/sync/$1.db | \ cut -d'/' -f1 | \ sort -V -u } extract_pkgname() { echo "$@" | tr " " "\n" | sed "s/^\(.\+\)-[^-]\+-[^-]\+$/\1/" } extract_fullpkgver() { echo "$@" | tr " " "\n" | sed "s/^.\+-\([^-]\+-[^-]\+\)$/\1/" } # Updates the database by finding all PKGBUILDS # Workflow: # * Find all PKGBUILDs on the ABS repo specified # * Get all packages already on package repos # * Compare them # Args: update() { # The PKGBUILDs found local pkgbuilds=() # The list of pkgname-fullpkgver local packages_to_sync=() local packages_in_sync=() local needed_updates=() local old_versions=() # Find all the PKGBUILDs newer than the last update # Update newer, otherwise everything if [ $force ] || [ ! -e ${lastsyncfile} ]; then $quiet || msg "Forcing upgrade" pkgbuilds=($(find ${@} -maxdepth 2 -type f -name 'PKGBUILD')) else pkgbuilds=($(find ${@} -maxdepth 2 -type f -name 'PKGBUILD' -newer ${lastsyncfile})) fi # Inform how many PKGBUILDS were found and quit immediately if none $quiet || msg "Found $((${#pkgbuilds[*]}-1)) packages to update" [ ${#pkgbuilds[*]} -eq 1 ] && { $quiet || msg2 "There's nothing to be done. Phew!" exit 0 } for _pkgbuild in ${pkgbuilds[@]}; do # The repo name is guessed # You *must* use repo/pkgbase structure _pkgpath=$(dirname "${_pkgbuild}") _pkgbase=$(basename "${_pkgpath}") _pkgrepo=$(basename $(dirname "${_pkgpath}")) source ${_pkgbuild} for _pkg in ${pkgname[@]}; do # Fill the list of packages to find packages_to_sync+=($_pkg-$(get_full_version ${epoch:-0} $pkgver $pkgrel)) done unset pkgbase pkgname pkgver pkgrel source epoch done # Get repo database contents packages_in_sync=($(get_db_contents ${_pkgrepo})) print_package_array "${packages_to_sync[@]}" > ${TMPDIR}/packages_to_sync print_package_array "${packages_in_sync[@]}" > ${TMPDIR}/packages_in_sync # We've orderer the files! needed_updates=($(comm --nocheck-order -32 ${TMPDIR}/packages_to_sync ${TMPDIR}/packages_in_sync)) old_versions=($(comm --nocheck-order -31 ${TMPDIR}/packages_to_sync ${TMPDIR}/packages_in_sync)) $quiet || msg "This packages are available to update" for _update in ${needed_updates[@]}; do pkg=$(extract_pkgname $_update) $quiet && echo $pkg $quiet || { ver=$(extract_fullpkgver $_update) oldver=$(extract_fullpkgver $(grep -w $pkg ${TMPDIR}/packages_in_sync)) msg2 "$pkg $oldver => $ver" } done # lastsync } ## MAIN commands=() repos=() quiet=false force=false while getopts 'hqfu' arg; do case $arg in h) usage; exit 0 ;; q) quiet=true ;; f) force=true ;; u) commands+=(update);; esac shift $((OPTIND-1)) done # This is the syncfile, stores the last date as content and mtime lastsyncfile=${ABSROOT}/toru.lastsync TMPDIR=$(mktemp -d) [[ -z ${TMPDIR} ]] && exit 1 ${commands[0]} ${@} rm -rf ${TMPDIR} exit $?