#!/bin/sh export STOW_DIR=/etc/portage/stow err() { printf "bosun: %s\n" "$@" >&2 } errx() { err "$@" exit 1 } usage() { printf "usage: bosun add role ...\n" >&2 printf " bosun flush\n" >&2 printf " bosun [list [type ...]]\n" >&2 printf " bosun rebuild [role ...]\n" >&2 printf " bosun remove [role ...]\n" >&2 exit 1 } need_role() { test $# -gt 0 || errx "this command requires at least one role" for dir in "$@"; do test -d "$STOW_DIR/$dir" || errx "no such role '$dir' in $STOW_DIR" done } need_root() { test "$(id -u)" -eq 0 || errx "this action requires superuser access" } add() { need_root need_role "$@" stow -S "$@" } remove() { need_root need_role "$@" stow -D "$@" } flush() { need_root list | xargs -- stow -D } rebuild() { need_root if test $# -gt 0; then need_role "$@" stow -R "$@" else list | xargs -- stow -R fi } list() { subcmd="${1:-active}" case $subcmd in active) list_active;; all) list_all;; available) list_available;; *) errx "no such list type '$subcmd'. Try: active, all, available" esac } list_active() { # Note: we de not escape any special characters in $STOW_DIR since it is # assumed we are in full control of its contents. # XXX: -r for xargs is a GNU extension find "$STOW_DIR/.." -type l -print0 2>/dev/null \ | xargs -r0 readlink -f \ | sed -n ":^$STOW_DIR: s:^$STOW_DIR/\([^/]\+\)/.*:\1:p" \ | sort -u } list_all() { ls -1 "$STOW_DIR" } list_available() { tmp="$(mktemp)" || exit 1 list_active > "$tmp" list_all | comm -13 "$tmp" - rm -f "$tmp" } cmd="${1:-list}" test $# -gt 0 && shift case $cmd in add) add "$@";; flush) flush;; list) list "$@";; rebuild) rebuild "$@";; del|delete|remove) remove "$@";; *) err "no such command '$cmd'"; usage;; esac