X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=zpm-install;h=af14c4d364de847df6591293b583a539cab34d12;hb=c20db3d43f58abb15e22fca0fe12e23ffb21d0d5;hp=8123b9ba4c90967fa99d1c0d124ef6f43e371873;hpb=6cc6d722040434ceaec43d57d20f60f113bd247f;p=zpackage diff --git a/zpm-install b/zpm-install index 8123b9b..af14c4d 100755 --- a/zpm-install +++ b/zpm-install @@ -1,13 +1,42 @@ #!/bin/sh -package=${1:-$ZPMPACKAGE} -shift +# do one thing and do it well +# this program installs packages from a package file +# by default, it will install the latest version of each package +# found in the file. + +# todo + +# if package specifiers are given as arguments after the package file +# it will only install those packages. + +# package specifiers are of the form pkg[-ver[-rel]], i.e the +# release can be omitted, and the version-release can be omitted. +# examples: +# zpm install -f foo-0.1-1.zpm +# zpm install -f foo.zpm foo-0.1 + +# todo: file tag handling + +# what we need to install a package: + +# recording repo: where we record what we've done +# source: where we get the package and files from +# install root: really just a prefix, but thought about differently, +# and we might need to do a chroot +# package name to install, could be "all" or "all most recent" +# but for now, assume only one package in a file? + +# zpm install [options] + pkgver=${ZPMPACKAGEVER:-1.0} pkgrel=${ZPMPACKAGEREL:-1} pkgroot=/ # allocate an install id, perhaps hash package and timestamp +# installid=$(echo $(date) $pkglist | zpm hash) + # extract pre-scripts and run them # get list of paths to install # for each path, if directory, create and set mode @@ -19,96 +48,298 @@ pkgroot=/ # move into place # after all the files, extract post scripts and run them +# also need to mark package as installing so if it fails part way +# through, it can be finished later +# probably also want an option to "backup" any packages being upgraded +# so it's trivial to downgrade or to revert if the install fails + # option for "multipackage" just to let the system know that's what you meant # option to take filenames from stdin # parse package, version, release from file if not given -while getopts :f:v:r:d:a:u:l:p:b:P: opt; do +# TODO what's the difference between prefix and pkgroot +# need an option to not chown the files +# option to install but not merge/track + +# options +# -R install root, if installing as root, will chroot? +# -C no chroot, even if root +# -N no pre-scripts +# -X no post-scripts +# -f source repository file +# -d local (recording) repository database +# -D don't locally record +# -t only files matching tags +# -T exclude files matching tags + +chroot=1 + +while getopts :R:CNXf:d:Dt:T:u:g: opt; do case $opt in R) pkgroot="$OPTARG" ;; + C) chroot=0 ;; f) pkgfile="$OPTARG" ;; - v) pkgver="$OPTARG" ;; - r) pkgrel="$OPTARG" ;; - d) description="$OPTARG" ;; - a) arch="$OPTARG" ;; - u) url="$OPTARG" ;; - l) licenses="$OPTARG" ;; - p) packager="$OPTARG" ;; - b) builddate="$OPTARG" ;; - P) prefix="$OPTARG" ;; + u) user="$OPTARG" ;; + g) group="$OPTARG" ;; + d) ZPMDB="$OPTARG" ;; esac done -set -e +shift $((OPTIND - 1)) + +for cf in /etc/zpmrc ~/.zpmrc ./.zpmrc; do + test -r $cf && . $cf +done + +: ${ZPMDB:=/var/lib/zpm/db.zpm} + +export ZPMDB + +die() { + printf 'zpm-install:' 1>&2 + printf ' %s' $* 1>&2 + printf '\n' 1>&2 + exit 1 +} + if [ -z "$pkgfile" ]; then + # actually, if no pkgfile, get pkgfile from repo + # but need to loop over finding package files then + # so this program probably needs to be "install from pkgfile" + # and a separate one that will loop over a package + # spec list and find from repos + die "must specify package file" pkgfile="$package-$pkgver-$pkgrel.zpm" fi -appid=$(sqlite3 $pkgfile 'pragma application_id;' | ( echo obase = 16; cat - ) | bc) -if [ "$appid" != "5A504442" ]; then - echo $pkgfile does not appear to be a zpm package file - exit 1 +set -e +zpm test -v $pkgfile + +if [ $# -gt 0 ]; then + pkglist="$@" +else + pkglist=$(zpm findpkg $pkgfile) fi -# check if package exists -# run preinstall or preupgrade stage, in chroot - -# add package info and mark installing to local package database -# each path: add to local db, extract, set mode/owner/mtime etc. -# mark install done in local database - -for path in $*; do - mtime=$(stat -c '%Y' $path) - uid=$(stat -c '%u' $path) - gid=$(stat -c '%g' $path) - username=$(stat -c '%U' $path) - groupname=$(stat -c '%G' $path) - mode=$(stat -c '%a' $path) - - # strip off leading slashes - rpath=$(echo "$path" | sed -e 's|^/*||') - # and a leading ./ - rpath=${rpath#./} - rpath=$(echo "$rpath" | sed -e 's|^/*||') - - if [ -z "$rpath" ] || [ "$rpath" = '.' ]; then - continue +pathlist() { + zpm shell $pkgfile< $target"} -printf "%s\n" $path +conflicts() { + echo conflict check $pkg $pkgfile + #newver=$1 + { + zpm shell $pkgfile<<-EOS + .separator " " + select hash,path from packagefiles + where package||'-'||version||'-'||release = '$pkg' + and filetype = 'r' + ; + EOS + } | while read hash path; do + rpath=$pkgroot$path + if [ -f $rpath ]; then + ihash=$(zpm hash $rpath) + if [ $ihash != $hash ]; then + die $path already exists + fi + elif [ -d $rpath ]; then + die $path already exists + fi + done + + { + zpm shell $pkgfile<<-EOS + .separator " " + select path from packagefiles + where package||'-'||version||'-'||release = '$pkg' + and filetype = 'd' + ; + EOS + } | while read hash path; do + rpath=$pkgroot$path + if [ -f $rpath ]; then + die $path already exists + elif [ -d $rpath ]; then + die $path already exists + elif [ -e $rpath ]; then + die $path already exists + fi + done +} + +for pkg in $pkglist; do + pname=$(pkgname $pkg) + curver=$(zpm findpkg $ZPMDB $pname) + pkg=$(zpm findpkg $pkgfile $pkg) + upgrade='n' + + if [ -n "$curver" ]; then + set +e + upgrade=$(zpm vercmp $pkg $curver) + fi + + case $upgrade in + 0) die 'already installed' $curver;; + 1) do_upgrade $pkg $curver ; exit 0 ;; + -1) die 'would be downgrade' $curver '->' $pkg ;; + n) printf 'ok to install %s\n' $pkg ;; + esac + + zpm merge $pkgfile $pkg + # TODO find scripts marked as pre-install + #run_preinstall + + # TODO if this is an upgrade, run pre-upgrade + #if [ $upgrade != 'n' ]; then + # run_preupgrade + #fi + + # TODO get total size of install so we can do a progress bar + #tsize=totalsize + + # add package info to local package db + #zpm merge $pkgfile $pkg + + # check for conflicts + + conflicts $pkgroot $pkg + + # mark package in localdb as installing + # zpm setmark installing $pkg + # install all the files for a package + # TODO install directories first in order of path length + echo installing $pkglist + filecount=$(pathlist | wc -l) + echo $filecount files + #die 'aborting for test' + #pathlist + zpm pkg $pkg status installing + pathlist | xargs zpm ipkgfile ${user+-u $user} ${group+-g $group} -R "$pkgroot" -f $pkgfile -- $pkg + + # TODO find scripts marked as post-install + # TODO if this is an upgrade, run post-upgrade + + # mark as ready for install + zpm pkg $pkg status installed + #zpm setmark ready $pkg done + +#zpm setmark installed $pkglist