159 lines
4.3 KiB
Bash
Executable file
159 lines
4.3 KiB
Bash
Executable file
#!/bin/sh
|
||
|
||
## DEFINITIONS
|
||
name="$(basename "$0")"
|
||
self="$(realpath "$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 "[4m[1m$1[0m"; }
|
||
destress() { echo "[2m$1[0m"; }
|
||
|
||
# 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 "[1mDependencies[0m"
|
||
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
|
||
|
||
# TODO getopt
|
||
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;;
|
||
(-d|--default) default=true; shift;;
|
||
(-x|--noexec) noexec=true; shift;;
|
||
esac
|
||
noexec=true
|
||
|
||
installdefault() {
|
||
local defaulthandler="$(head -1 "$handlers")"
|
||
highlight "Attempting install of $1 via default handler"
|
||
$(test "$noexec" && echo "sh") "$homedir/handlers/$defaulthandler/install" "$1" &&
|
||
$(test "$noexec" && echo "sh") "$self" --add "$1" "$defaulthandler" ""
|
||
}
|
||
|
||
runinstalee() {
|
||
local groupfile="$homedir/groups/$1"
|
||
if test -f "$groupfile"
|
||
then for pkg in $(getcontent "$groupfile")
|
||
do runinstalee "$pkg" || installdefault "$pkg"
|
||
done
|
||
else installpkg "$1" || { test "$default" && installdefault "$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
|
||
|
||
chmod +rx "$homedir/handlers" -R
|
||
|
||
execdir=/tmp/instalee.$(date +%s)
|
||
mkdir -p $execdir
|
||
cd $execdir
|
||
|
||
exitcode=0
|
||
while test $# -gt 0; do
|
||
runinstalee "$1"
|
||
exitcode=$(expr $exitcode \| $?)
|
||
shift
|
||
done
|
||
exit $exitcode
|