From: Nathan Wagner Date: Sat, 1 Dec 2018 17:45:17 +0000 (+0000) Subject: add zpm-update X-Git-Tag: v0.3.3~12 X-Git-Url: https://pd.if.org/git/?p=zpackage;a=commitdiff_plain;h=881763b16a50b342676f3d59c2d883e2c39548ff add zpm-update --- diff --git a/Makefile b/Makefile index ab71151..ebe88bb 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ ZPKGBIN=zpm-addfile zpm-extract zpm-init zpm-vercmp zpm-stat zpm-hash \ SCRIPTS=zpm zpm-install zpm-merge zpm-list zpm-preserve zpm-test zpm-log \ zpm-contents zpm-uninstall zpm-pathmod zpm-rmpackage zpm-newpackage \ - zpm-pkg zpm-add zpm-pkgfile zpm-gc zpm-repo + zpm-pkg zpm-add zpm-pkgfile zpm-gc zpm-repo zpm-update COMPILED=$(ZPKGBIN) PROGRAMS=$(SCRIPTS) $(COMPILED) diff --git a/zpm-update b/zpm-update new file mode 100755 index 0000000..3423ff6 --- /dev/null +++ b/zpm-update @@ -0,0 +1,341 @@ +#!/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 + 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 + +# TODO option to attempt to resume an ongoing install +# zpm-install [-SCn] [ -d localdb ] [ -f pkgfile ] [ -R installroot ] pkgstr ... +while getopts f:d:R:nSCvAObBL 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 ;; + *) die "usage ..." ;; + esac +done +shift $(( OPTIND - 1)) + +ZPMDB=${localdb:-${ZPMDB:-/var/lib/zpm/local.db}} +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" + fi + # else warn not installed + ;; + +*) 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 + ;; + *) search="$search $op" + ;; + esac +done + +search=$(echo $search) + +ebail=0 + +if [ $ignorelibdeps -eq 1 ]; then + merge=$(zpm search -iIO $search) +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 + echo downloading $zpmfile + 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 + +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 +fi + +if [ -z "$merge" ] && [ -z "$to_remove" ]; then + echo nothing to do + exit 0 +fi + +echo "merge: $merge" + +# 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 -Fuv -f "$pkgfile" $pkgid + fi + to_install="$to_install $pkgid" +done + +to_install=${to_install#' '} + +echo "installing: $to_install" + +# 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 +fi + +if [ -n "$to_remove" ]; then + for pkgid in $to_remove; do + zpm pkg $pkgid status=removing + done +fi + +if [ -n "$rootdir" ]; then + ZPM_ROOT_DIR=$rootdir + export ZPM_ROOT_DIR + : rootdir=${rootdir%%/} +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" +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 + +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