#!/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