X-Git-Url: https://pd.if.org/git/?p=zpackage;a=blobdiff_plain;f=bin%2Fzpm-update;fp=bin%2Fzpm-update;h=e1accc87393faf4acf73923aa0e8d2b9399c6c6f;hp=0000000000000000000000000000000000000000;hb=0419c62f964b259df1c1816f5870ef62eb97ed7c;hpb=0c2216d1e0dc8565a6bf61c9572e47bb1ae1c1fb diff --git a/bin/zpm-update b/bin/zpm-update new file mode 100755 index 0000000..e1accc8 --- /dev/null +++ b/bin/zpm-update @@ -0,0 +1,388 @@ +#!/bin/sh + +warn() { + echo $* 1>&2 +} + +run_ldconfig() { + if [ $(id -u) -eq 0 ]; then + if [ ! -d $1/etc ]; then + warn "no etc directory in $1, skipping ldconfig" + elif [ -f $1/sbin/ldconfig ]; then + $1/sbin/ldconfig -r ${1:-/} + elif [ -f /sbin/ldconfig ]; then + /sbin/ldconfig -r ${1:-/} + else + true + fi + fi +} + +changeall() { + for pkgid in $(zpm list -s $1); do + zpm pkg $pkgid status=$2 + done +} + +die() { + if [ $# -gt 0 ]; then + echo $* 1>&2 + fi + zpm log -i -a 'aborted install' -t "$pkgid" "$*" + changeall installing + changeall removing installed + changeall updating installed + exit 1 +} + +current_version() ( + zpm list -s installed $(zpm parse -n $1) +) + +maybe_run() ( + phase=$1 + pkgid=$2 + run=${3:-0} + current=$4 + + if [ $run -gt 0 ]; then + zpm script -p $phase $pkgid $current + rv=$? + if [ $rv -ne 0 ]; then + warn "$phase script for $pkgid failed" + exit $rv + fi + else + if zpm script -Fql -p $phase $pkgid; then + zpm note -e -p $pkgid -m "$phase script not run" + fi + fi +) + +validity_check() { + rv=0 + # check if we're installing something already + var=$(zpm list -s installing | wc -l) + if [ $var -gt 0 ]; then + zpm list -v -f $localdb -s installing + warn "already ($localdb) installing $var package(s)" + rv=1 + fi + var=$(zpm list -s removing | wc -l) + if [ $var -gt 0 ]; then + zpm list -v -f $localdb -s removing + warn "already ($localdb) removing $var package(s)" + rv=1 + fi + var=$(zpm list -s updating | wc -l) + if [ $var -gt 0 ]; then + zpm list -v -f $localdb -s updating + warn "already ($localdb) updating $var package(s)" + rv=1 + fi + if [ $rv -ne 0 ]; then + die "aborting update" + fi +} + +dryrun=0 +verbose=0 +runscripts=1 +runconfigure=1 +absorb=0 +overwrite=0 +syncopts='' + +packagepath="/var/lib/zpm/packages" +to_install= +to_remove= +to_update= +install_for_libs='' + +backup=0 +ignorelibdeps=0 +justlist=0 +pullrepos=1 + +# treat un-adorned packages as uninstalls +uninstall=0 + +# TODO option to attempt to resume an ongoing install +# zpm-install [-SCn] [ -d localdb ] [ -f pkgfile ] [ -R installroot ] pkgstr ... +while getopts f:d:R:nSCvAObBLUzpl opt; do + case $opt in + f) pkgfile="$OPTARG" ;; + d) localdb="$OPTARG" ;; + P) packagepath="$OPTARG" ;; + D) packagepath="$OPTARG:$packagepath" ;; + R) rootdir="$OPTARG" ;; + S) runscripts=0 ;; + C) runconfigure=0 ;; + A) absorb=1; syncopts="${syncopts} -A" ;; + O) overwrite=1; syncopts="${syncopts} -O" ;; + n) dryrun=1 ;; + v) verbose=1 ;; + b) backup=1 ;; + B) backup=0 ;; + L) ignorelibdeps=1 ;; + l) justlist=1 ;; + U) uninstall=1 ;; + z) pullrepos=0 ;; + p) syncopts="$syncopts -p" ;; + *) die "usage ..." ;; + esac +done +shift $(( OPTIND - 1 )) + +if [ -n "$rootdir" ]; then + : rootdir=${rootdir%%/} + ZPM_ROOT_DIR=$rootdir + export ZPM_ROOT_DIR +fi + +if [ -n "$localdb" ]; then + ZPMDB=$localdb +elif [ -z "$ZPMDB" ]; then + ZPMDB="$ZPM_ROOT_DIR/var/lib/zpm/local.db" +fi + +export ZPMDB + +# create the localdb if needed +zpm init $ZPMDB + +zpm test -v "$ZPMDB" || die "$ZPMDB is not a zpm database" + +validity_check + +for op in "$@"; do + case "$op" in + -*) pkgid=$(zpm findpkg -I "${op#-}") + if [ -n "$pkgid" ]; then + to_remove="$to_remove $pkgid" + else + die "$op not installed" + fi + ;; + +*) pkg=${op#+} + search="$search $pkg" + ;; + *:*) pkg=${op%:*} + file=${op#*:} + pkgid=$(zpm findpkg -f $file $pkg) + if [ -n $pkgid ]; then + merge="$merge $pkgid:$file" + else + die "can't find $pkg in $file" + fi + ;; + *) + if [ $uninstall -eq 0 ]; then + search="$search $op" + else + pkgid=$(zpm findpkg -I "${op}") + if [ -n "$pkgid" ]; then + to_remove="$to_remove $pkgid" + else + die "$op not installed" + fi + fi + ;; + esac +done + +search=$(echo $search) + +ebail=0 + +if [ $pullrepos -eq 1 ]; then + echo pulling repos + zpm repo pull +fi + +if [ $ignorelibdeps -eq 1 ]; then + merge=$(zpm search -iIO $search) + # TODO search for libs anyway and put a note for non-installed + # library deps +else + merge=$(zpm search -iIO -l $search) +fi + +if [ $? -ne 0 ]; then + warn "unmet packages or dependencies, or errors" + exit 1 +fi + +installset= +for mergepkg in $merge; do + pkgid=${mergepkg%%:*} + installset="$installset $pkgid" +done +installset=$(printf "%s\n" $installset | sort -u) + +# TODO check for downgrade + +# fixup package +nlist= +nfound= +baddl= +for mergepkg in $merge; do + pkgid=${mergepkg%:*} + repofile=${mergepkg#*:} + if [ ${repofile##*.} = 'repo' ]; then + status=$(zpm pkg -f $repofile $pkgid status) + reponame=$(basename $repofile .repo) + if [ "$status" != 'merged' ]; then + repodir=$(dirname $repofile) + zpmfile=$repodir/$reponame/$pkgid.zpm + if [ -f "$zpmfile" ]; then + nlist="$nlist $pkgid:$zpmfile" + continue + else + zpm repo fetch $reponame $pkgid + if [ -f "$zpmfile" ]; then + nlist="$nlist $pkgid:$zpmfile" + else + baddl="$baddl $reponame:$pkgid" + fi + fi + fi + else + nlist="$nlist $mergepkg" + fi +done +merge=${nlist#' '} +baddl=${baddl#' '} + +if [ -n "$baddl" ]; then + printf 'unable to download: %s\n' $baddl + die +fi + +for package in $merge; do + pkgid=${package%:*} + installlist="$installlist $pkgid" +done +installlist=${installlist#' '} + +if [ $justlist -eq 1 ]; then + for package in $merge; do + pkgid=${package%:*} + printf 'install %s\n' $pkgid + done + for pkgid in $to_remove; do + printf 'remove %s\n' $pkgid + done + exit 0 +fi + +if [ -z "$merge" ] && [ -z "$to_remove" ]; then + echo nothing to do + exit 0 +fi + +test -n "$merge" && echo "install: $installlist" +test -n "$to_remove" && echo "remove: $to_remove" + +# finally, merge everything +for mergepkg in $merge; do + pkgid=${mergepkg%:*} + pkgfile=${mergepkg#*:} + + # we could have found the package already in the localdb + # in which case, we don't need to merge it + # TODO check for symlinks? + if [ $pkgfile != $ZPMDB ]; then + echo merging $pkgfile $pkgid + zpm merge -Fu -f "$pkgfile" $pkgid + if [ $? -ne 0 ]; then + die "unable to merge $pkgfile" + fi + fi + to_install="$to_install $pkgid" +done + +to_install=${to_install#' '} + +if [ -n "$to_install" ]; then + echo "installing: $to_install" +fi + +# absorb anything we're updating or removing, if absorb flag set + +if [ -n "$to_install" ]; then + for pkgid in $to_install; do + current=$(current_version $pkgid) + maybe_run pre-install $pkgid $runscripts $current || die + done +fi + +if [ -n "$to_remove" ]; then + for pkgid in $to_remove; do + maybe_run pre-remove $pkgid $runscripts || die + done +fi + +if [ -n "$to_install" ]; then + for pkgid in $to_install; do + zpm pkg $pkgid status=installing + done + zpm shell "$ZPMDB" "update packages set status='updating' where status='installed' and package in (select package from packages where status = 'installing')" +fi + +if [ -n "$to_remove" ]; then + for pkgid in $to_remove; do + zpm pkg $pkgid status=removing + done +fi + +if [ $dryrun -gt 0 ]; then + runscripts=0 # we don't want to run post scripts on a dry-run + syncopts="$syncopts -n" +fi + +if [ $verbose -gt 0 ]; then + syncopts="${syncopts} -v" +fi +#else + # force -v during development + #syncopts="${syncopts} -v" +#fi + +if [ $dryrun -eq 0 ] && [ $backup -eq 1 ]; then + true + #zpm absorb -s updating + #zpm absorb -s removing +fi + +zpm syncfs $syncopts || die 'zpm-syncfs failed'; + +if [ -n "$to_remove" ]; then + for pkgid in $to_remove; do + maybe_run post-remove $pkgid $runscripts + done +fi + +changeall removing removed +changeall updating updated + +echo running ldconfig +run_ldconfig $rootdir + +if [ -n "$to_install" ]; then + for pkgid in $to_install; do + package=$(zpm parse -n $pkgid) + current=$(zpm list -s installed "$package") + + maybe_run post-install $pkgid $runscripts $current + + if [ -n "$current" ]; then + zpm pkg $pkgid status=installed :$current status=updated + else + zpm pkg $pkgid status=installed + fi + + maybe_run configure $pkgid $runconfigure + done +fi +echo install complete