blind mgmt setup
This commit is contained in:
parent
87f5dfcdf8
commit
074131bb54
5 changed files with 201 additions and 0 deletions
76
private_bin/private_argparse.bash
Normal file
76
private_bin/private_argparse.bash
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
declare -gA ARGP
|
||||||
|
declare -gA SHORT
|
||||||
|
|
||||||
|
__reset_argparse() {
|
||||||
|
declare -gA ARGP
|
||||||
|
declare -gA SHORT
|
||||||
|
}
|
||||||
|
|
||||||
|
die() { echo "Error: $*"; exit 1; }
|
||||||
|
|
||||||
|
def_arg() {
|
||||||
|
test "$3" = bool -o "$3" = value || die "def_arg: type (\$3) must be 'bool' or 'value', received '$3'"
|
||||||
|
ARGP["$1,type"]="$3"
|
||||||
|
|
||||||
|
if [ "$3" = bool ]; then
|
||||||
|
test -z "$4" || die "def_arg: bool args cannot specify required/default"
|
||||||
|
declare -g "$1=0"
|
||||||
|
else
|
||||||
|
test "$4" = required -o "$4" = default || die "def_arg: \$4 must be 'required' or 'default', received '$4'"
|
||||||
|
if [ "$4" = required ]; then
|
||||||
|
ARGP["$1,required"]=1
|
||||||
|
else
|
||||||
|
value="$5"
|
||||||
|
declare -g "$1=$value"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
SHORT["$2"]="$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
positional=()
|
||||||
|
while (( $# > 0 )); do
|
||||||
|
next="$1"; shift
|
||||||
|
if [[ "$next" == --* ]]; then
|
||||||
|
arg=${next#--}
|
||||||
|
test -n "${ARGP["$arg,type"]}" || die "unknown arg --$arg"
|
||||||
|
if [ "${ARGP["$arg,type"]}" = bool ]; then
|
||||||
|
value=1
|
||||||
|
elif [ $# -eq 0 ]; then
|
||||||
|
die "Missing value for --$arg"
|
||||||
|
else
|
||||||
|
value="$1"; shift
|
||||||
|
fi
|
||||||
|
declare -g "$arg=$value"
|
||||||
|
elif [[ "$next" == -* ]]; then
|
||||||
|
for ((i = 1 ; i < ${#next} ; i++ )); do
|
||||||
|
short=${next:$i:1}
|
||||||
|
arg=${SHORT["$short"]}
|
||||||
|
test -n "$arg" || die "unknown short arg -$short"
|
||||||
|
if [ "${ARGP["$arg,type"]}" = bool ]; then
|
||||||
|
declare -g "$arg=1"
|
||||||
|
else
|
||||||
|
value=${next:$(( i+1 ))}
|
||||||
|
if [ -z "$value" ]; then
|
||||||
|
value="$1"; shift
|
||||||
|
fi
|
||||||
|
test -n "$value" || die "missing value for -$short"
|
||||||
|
declare -g "$arg=$value"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
positional+=("$next")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# check for missing required
|
||||||
|
for arg in "${!ARGP[@]}"; do
|
||||||
|
arg="${arg%%,*}"
|
||||||
|
[ "${ARGP["$arg,required"]}" != 1 ] || [ -n "${!arg}" ] || die "missing argument --$arg"
|
||||||
|
done
|
||||||
|
}
|
||||||
90
private_bin/private_mgmt
Executable file
90
private_bin/private_mgmt
Executable file
|
|
@ -0,0 +1,90 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
source argparse.bash
|
||||||
|
functions=; def_arg functions f value default "${XDG_CONFIG_HOME:-"$HOME/.config"}/mgmt/functions"
|
||||||
|
modules=; def_arg modules m value default "${XDG_CONFIG_HOME:-"$HOME/.config"}/mgmt/modules"
|
||||||
|
positional=(); parse_args "$@"
|
||||||
|
|
||||||
|
while IFS= read -rd '' fnfile; do
|
||||||
|
source "$fnfile"
|
||||||
|
done < <(find "$functions" -type f -print0)
|
||||||
|
|
||||||
|
PREFIX=""
|
||||||
|
grey() { printf "\33[37;2m%s\33[0;m" "$*"; }
|
||||||
|
red() { printf "\33[31;1m%s\33[0;m" "$*"; }
|
||||||
|
diag() {
|
||||||
|
>&2 printf "\33[2K\r%s" "$(grey "$PREFIX")"
|
||||||
|
>&2 echo "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_by() { local IFS="$1"; shift; echo "$*"; }
|
||||||
|
filter_by_args() { grep -E "$(join_by '|' "${positional[@]}")"; }
|
||||||
|
|
||||||
|
#####
|
||||||
|
# Gather dependencies of (filtered) modules
|
||||||
|
#####
|
||||||
|
declare -a found_modules
|
||||||
|
mapfile -t filtered_mods < <(find "$modules" -type f | filter_by_args)
|
||||||
|
set -- "${filtered_mods[@]}"
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
unset deps; declare -a deps
|
||||||
|
for mod; do
|
||||||
|
if echo "${found_modules[@]}" | grep -q "$mod"; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
found_modules+=( "$mod" )
|
||||||
|
unset DEPENDS
|
||||||
|
source "$mod"
|
||||||
|
for dep in "${DEPENDS[@]}"; do
|
||||||
|
if echo "${found_modules[@]}" | grep -qv "$dep"; then
|
||||||
|
if echo "${deps[@]}" | grep -qv "$dep"; then
|
||||||
|
deps+=( "$dep" )
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
set -- "${deps[@]}"
|
||||||
|
done
|
||||||
|
|
||||||
|
#####
|
||||||
|
# Resolve dependency ordering
|
||||||
|
#####
|
||||||
|
declare -a ordered_modules
|
||||||
|
set -- "${found_modules[@]}"
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
unset remaining; declare -a remaining
|
||||||
|
for mod; do
|
||||||
|
unset DEPENDS
|
||||||
|
source "$mod"
|
||||||
|
if [[ -n "$(comm -23 <(printf -- '%s\n' "${DEPENDS[@]}" | sort) <(printf -- '%s\n' "${ordered_modules[@]}" | sort))" ]]; then
|
||||||
|
remaining+=( "$mod" )
|
||||||
|
else
|
||||||
|
ordered_modules+=( "$mod" )
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ $# -eq ${#remaining[@]} ]; then
|
||||||
|
diag "$(red "Error: dependency loop involving ${remaining[*]}")"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
set -- "${remaining[@]}"
|
||||||
|
done
|
||||||
|
|
||||||
|
#####
|
||||||
|
# Apply modules
|
||||||
|
#####
|
||||||
|
sudo -v
|
||||||
|
set -- "${ordered_modules[@]}"
|
||||||
|
for mod; do
|
||||||
|
diag -e "\nApplying $mod"
|
||||||
|
PREFIX="[$mod] "
|
||||||
|
unset check_setup setup check_apply apply
|
||||||
|
source "$modules/$mod"
|
||||||
|
test "$(declare -F check_setup)" || { check_setup() { false ; } }
|
||||||
|
test "$(declare -F check_apply)" || { check_apply() { false ; } }
|
||||||
|
test "$(declare -F setup)" || { setup() { true; } }
|
||||||
|
test "$(declare -F apply)" || { apply() { true; } }
|
||||||
|
check_setup || setup
|
||||||
|
check_apply || apply
|
||||||
|
PREFIX=""
|
||||||
|
done
|
||||||
|
|
@ -4,6 +4,8 @@ blue="\[\e[38;5;50m\]"
|
||||||
rst="\[\e[0m\]"
|
rst="\[\e[0m\]"
|
||||||
PS1="╭╢$blue\w$rst\n╰╼ "
|
PS1="╭╢$blue\w$rst\n╰╼ "
|
||||||
|
|
||||||
|
PATH=$PATH:"$HOME/bin"
|
||||||
|
|
||||||
function conf() {
|
function conf() {
|
||||||
fname="${XDG_CONFIG_HOME:-.config}/$1"
|
fname="${XDG_CONFIG_HOME:-.config}/$1"
|
||||||
test -f "$fname" && source "$fname"
|
test -f "$fname" && source "$fname"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
_os() {
|
||||||
|
if command -v termux-setup-storage >/dev/null; then
|
||||||
|
echo "termux"
|
||||||
|
else
|
||||||
|
grep '^ID=' /etc/os-release | cut -d= -f2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
missing=()
|
||||||
|
check_apply() {
|
||||||
|
while IFS= read -r package; do
|
||||||
|
cmd=$(echo "$package" | cut -d\; -f1)
|
||||||
|
pkg=$(echo "$package" | grep -Eo "$(_os):[^ ]+" || echo ":$cmd")
|
||||||
|
pkg=$(echo "$pkg" | cut -d: -f2)
|
||||||
|
[ -n "$pkg" ] || next
|
||||||
|
|
||||||
|
command -v "$cmd" >/dev/null || missing+=( "$pkg" )
|
||||||
|
done < ~/.config/mgmt/packages
|
||||||
|
|
||||||
|
[ ${#missing} -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
apply() {
|
||||||
|
case "$(_os)" in
|
||||||
|
ubuntu) manager="apt install" ;;
|
||||||
|
arch) manager="pacman -Syu" ;;
|
||||||
|
termux) manager="pkg install" ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
$manager "${missing[@]}"
|
||||||
|
}
|
||||||
1
private_dot_config/private_mgmt/private_packages
Normal file
1
private_dot_config/private_mgmt/private_packages
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
nvim; termux:neovim arch:neovim ubuntu:
|
||||||
Loading…
Add table
Add a link
Reference in a new issue