#!/bin/sh ## DEFINITIONS name="$(basename "$0")" homedir="$(find "$INSTALEE_HOME" "${XDG_CONFIG_HOME:-$HOME/.config}/$name" "$HOME/.$name" "$(dirname $0)" "$PWD" -maxdepth 0 2>/dev/null | head -1)" handlers="$homedir/handlers.available" packagedir="$homedir/packages" highlight() { echo "$1"; } destress() { echo "$1"; } # Get the content of a file or the output of its execution getcontent() { if test -z "$noexec" && test -x "$1" then "$1" else cat "$1" fi } # Get available package entries for given package getentries() { cat "$handlers" | while read handler do find "$packagedir/$1/" -depth -type f -name "$handler*" 2>/dev/null | tac done } # Install a package by name installpkg() { test "$1" = "--quiet" && local quiet=true && shift local pkgs=$(getentries "$1") local pkgdir="$packagedir/$1/" if test -z "$pkgs"; then local pkghandlers="$(find "$pkgdir" -type f -printf "%f\n" 2>/dev/null)" for handler in $pkghandlers do installpkg --quiet "$handler" && echo "$handler" >>"$pkghandlers" && installpkg "$1" && return $? done test "$quiet" || echo "No handler available for package '$1'" >&2 return 2 fi local pkg for pkg in $pkgs do highlight "Installing $(echo ${pkg#$packagedir/} | sed 's|\(.*\)/|\1 via |')" set -e local name="$(basename $pkg)" local base="${name%_*}" echo "Dependencies" for dependency in $(cat "${pkgdir}depends" "${pkgdir}${base}_depends" 2>/dev/null) do runinstalee $dependency | sed 's/^/ /' done local ext="${name#$base}" local handler="$homedir/handlers/$base" cd $(mktemp -d --tmpdir=$execdir $pkg.XXXX) if test -d "$handler" then # This declaration needs to be ahead, otherwise it overrides failing exit codes local args local install args="$(getcontent "$pkg")" args="${args:-$1}" install="$(find "$handler" -name "install$ext" | head -1)" destress " $install $args" $install $args else destress " running unhandled $pkg" $pkg fi break done } ## EXECUTION chmod +rx "$homedir/handlers" -R case "$1" in (-V|--version|"") printf "$name r%s.%s\n" "$(git rev-list --count HEAD 2>/dev/null)" "$(git rev-parse --short HEAD 2>/dev/null)" echo "Try '$0 --help' or 'man $name' for usage info" # TODO license https://www.gnu.org/prep/standards/html_node/_002d_002dversion.html#g_t_002d_002dversion exit 0 ;; (-h|--help) man $name 2>/dev/null || man "$homedir/$name.1" exit $? ;; (-a|--add) shift if test $# -gt 0 then packagename=$1; shift else printf "Name of the package? "; read packagename fi dir="$packagedir/$packagename" mkdir -p "$dir" if test $# -gt 0 then handler=$1 test $# -gt 1 && echo "$2">"$dir/$handler" || ${EDITOR:-vi} "$dir/$handler" exit $? else while printf "Handler? (Ctrl-C or Ctrl-D to exit, / to list all) " && read handler do case "$handler" in (/*) find "$packagedir" "$homedir/handlers" -type f -not -name "*depends" -printf "%f\n" | sort | uniq | paste -s -d ' ';; (*) ${EDITOR:-vi} "$dir/$handler";; esac done exit 0 fi ;; (-v|--verbose) set -x shift ;; (-x|--noexec) noexec=true shift ;; esac execdir=/tmp/instalee.%(date +%s) mkdir -p $execdir cd $execdir runinstalee() { groupfile="$homedir/groups/$1" if test -f "$groupfile" then for pkg in $(getcontent "$groupfile") do if ! runinstalee "$pkg" then highlight "Attempting install of $pkg via default handler" "$homedir/handlers/$(head -1 "$handlers")/install" "$pkg" # TODO apply noexec to how handlers are run - via sh fi done else installpkg "$1" fi } if ! test -f "$handlers" then copy="$(find "$homedir" -name "handlers.available.*" -exec sh -c "echo {} | rev | cut -d'.' -f1 | rev | xargs -i% expr $(lsb_release -s -i | tr 'A-Z' 'a-z') : % >/dev/null" \; -a -print)" && test -n "$copy" && echo "Bootstrapping available handlers from $copy" && cp "$copy" "$handlers" || { echo "Missing available handlers in $handlers!" exit 1 } fi exitcode=0 while test $# -gt 0; do runinstalee "$1" exitcode=$(expr $exitcode \| $?) shift done exit $exitcode