diff --git a/iglu.sh b/iglu.sh new file mode 100755 index 0000000..a035202 --- /dev/null +++ b/iglu.sh @@ -0,0 +1,100 @@ +#!/bin/sh +# usage: iglu [ add | del ] +# +# WONTFIX: +# - circular deps shall not be handled + +set -e + +usage() { + echo "usage: $(basename $0) [add | del] " + exit 1 +} + +fatal() { + echo "ERROR: $@" + exit 1 +} + +warn() { + echo "WARNING: $@" +} + +chop_fs() { + sed -n '/\[fs\]/,/\[backup\]/{/\[fs\]\|\[backup\]/!p}' "$1" \ + | awk '{print length, $0}' | sort -rn | cut -d' ' -f2- +} + +continue_interactive() { + printf '%s' "Do you wish to proceed?: " + read yn + case $yn in + [Yy]* ) echo "Proceeding";; + [Nn]* ) exit;; + * ) exit;; + esac +} + +remove() { + rm -f "$@" 2> /dev/null + while shift 2> /dev/null; do + if [ -d "/$1" ]; then + set +e + rmdir "/$1" 2> /dev/null + set -e + fi + done +} + +assert_deps() { + for dep in $(grep '^deps=' "$1" | cut -d'=' -f2- | tr ':' '\n'); do + [ -f "/usr/share/iglupkg/$dep" ] || fatal "Missing dep $dep" + done +} + +CMD=$1 +PKG=$2 + +[ -z "$1" ] && usage + +[ $(id -u) -eq 0 ] || fatal "root permissions needed" + +if [ "$CMD" = "add" ]; then + META_PATH=$(tar -I zstd -tf "$PKG" | grep 'usr/share/iglupkg/' | tail -n1) + PKGNAME=$(basename "$META_PATH") + + TMP_DIR=$(mktemp -d) + tar -I zstd -C "$TMP_DIR" -xf "$PKG" "$META_PATH" + assert_deps "$TMP_DIR/$META_PATH" + + if [ -f "/$META_PATH" ]; then + warn "package $PKGNAME already installed. upgrading ..." + + chop_fs "$TMP_DIR/$META_PATH" > "$TMP_DIR/new" + chop_fs "/$META_PATH" > "$TMP_DIR/old" + + + warn "removing duplicate files ..." + TO_REMOVE=$(diff -u "$TMP_DIR/old" "$TMP_DIR/new" | grep -v '^---' | grep -E '^\-' | cut -d'-' -f 2 | awk '{ print "/"$1 }') + + [ -z "$TO_REMOVE" ] || warn "will remove $TO_REMOVE" + continue_interactive + + remove "$TO_REMOVE" + else + warn "installing $PKGNAME ..." + continue_interactive + fi + tar -I zstd -C / -xf "$PKG" + rm -rf "$TMP_DIR" +elif [ "$CMD" = "del" ]; then + META_PATH="/usr/share/iglupkg/$PKG" + [ -f "$META_PATH" ] || fatal "package $PKG not installed" + TO_REMOVE=$(chop_fs $META_PATH | awk '{ print "/"$1 }') + [ -z "$TO_REMOVE" ] || warn "will remove $TO_REMOVE" + continue_interactive + + remove $TO_REMOVE +else + fatal "unknown command $CMD" +fi