]> pd.if.org Git - zpackage/blobdiff - bin/zpm-update
move programs to bin for build
[zpackage] / bin / zpm-update
diff --git a/bin/zpm-update b/bin/zpm-update
new file mode 100755 (executable)
index 0000000..e1accc8
--- /dev/null
@@ -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