baz/baz
Ari Archer f652dafcca
7.6.0 : improve static and const usage, improve performance
Signed-off-by: Ari Archer <ari.web.xyz@gmail.com>
2023-05-22 01:41:45 +03:00

897 lines
24 KiB
Shell
Executable file

#!/usr/bin/env bash
[ "$BAZ_DEBUG" ] && set -x
export BAZ_VERSION='7.6.0'
export BAZ_DIR="$HOME/.local/share/baz"
export BAZ_CONFDIR="$HOME/.config/baz"
export BAZ_CONF="$BAZ_CONFDIR/config.env"
export BAZ_PRE="$BAZ_CONFDIR/preload.env"
export BAZ_LOADER="$BAZ_DIR/loader.sh"
export BAZ_PLUGDIR="$BAZ_DIR/plugins"
export CC="${CC:-cc}"
export BAZP_ENV=(
BAZP_NAME BAZP_LICENSE
BAZP_VER BAZP_AUTHOR BAZP_SRC
BAZP_METHOD BAZP_SOURCE
BAZP_DESCRIPTION
)
export BAZP_INDEX='baz.env'
BAZP_INITDIR="$("${PWDCMD:-pwd}")"
export BAZP_INITDIR
export TMPDIR="${TMPDIR:-/tmp}"
export BAZ_BASH_LOADER_TEMPLATE="$BAZP_INITDIR/loader.sht"
export BAZ_LOADER_DIR="$BAZP_INITDIR/loader"
export BAZ_LOADER_TEMPLATE="$BAZ_LOADER_DIR/loader.sht"
export BAZ_LOADER_PROG="$BAZ_LOADER_DIR/loader.c"
export BAZ_LOADER_PROG_BIN="$BAZ_DIR/load"
export BAZ_LOGGING_HEADER='[BAZ_LOAD]'
# helpers
baz_entry() { printf " + %-50s%s\n" "$1" "$2"; }
baz_log() {
[ "$BAZP_NO_LOG" = true ] && return
[ "$2" = printf ] && printf ' * %s' "$1" && return
${2:-echo} " * $1"
}
baz_elog() { baz_log "$1" >&2; }
baz_eecho() { [ "$BAZP_NO_LOG" = true ] || echo "$1" >&2; }
baz_unexpand_path() { echo "${1/"$HOME"/"${2:-~}"}"; }
baz_indent() { sed 's/^/ /g'; }
baz_git() { git "$1" --quiet "${@:2}" 2>/dev/null; }
baz_git_clone() { baz_git clone --recursive -- "$1" "$2"; }
baz_git_reset() { baz_git reset --hard; }
baz_git_env() {
baz_git checkout HEAD --force -- "$BAZP_INDEX"
bazp_source_env
}
baz_get_base() {
set -- "${1%"${1##*[!/]}"}"
echo "${1##*/}"
}
baz_sanitize() {
read -r x
local tmp="${x//[[:space:]\"\'~!#\\$%^&*\/()=]/}"
echo "${tmp//../}"
}
baz_hook() {
local hook="${BAZP_SRC:?}/hooks/$1"
if [ -f "$hook" ]; then
BAZP_NO_LOG=false baz_log "$2: $1"
"$3" "$hook"
fi
}
baz_run_hook() {
if [ -z "$1" ] || [ ! -d "${BAZP_SRC:?}/hooks" ]; then
return
fi
baz_hook "$1-pre" 'sourcing pre-hook' source
baz_hook "$1" 'running hook' bash
baz_hook "$1-source" 'sourcing hook' source
baz_hook "$1-post" 'sourcing post-hook' source
return 0
}
baz_in_array() {
for element in $1; do
if [[ $2 =~ $element ]]; then
baz_log "'$2' matches element : $element"
return 0
fi
done
return 1
}
baz_error() {
baz_elog "error : $1"
exit 1
}
baz_use() {
for dep in "$@"; do
if ! command -v -- "$dep" >/dev/null; then
case "${do_error:-}" in
no) return 1 ;;
*) baz_error "required dependency not installed : $dep" ;;
esac
fi
done
}
baz_yn() {
printf ' [yN] %s\n >> ' "$1"
read -r ans
[ "$ans" = 'y' ]
}
baz_check_plugin_state() {
plugin="$(echo "$plugin" | baz_sanitize)"
if [ ! "$plugin" ]; then
[ "$1" ] && : >"$1"
baz_error 'no plugins supplied'
fi
if [ ! -d "${BAZ_PLUGDIR:?}/$plugin" ]; then
[ "$1" ] && : >"$1"
baz_error "plugin '$plugin' not installed"
fi
}
baz_update_plugin_git() {
baz_git_env
bazp_check_env
old_ver="$BAZP_VER"
baz_git_reset
git remote update --prune >/dev/null 2>&1
if git status -uno | grep -iq behind; then
baz_git checkout FETCH_HEAD --force -- "$BAZP_INDEX"
bazp_source_env
new_ver="$BAZP_VER"
baz_git_env
if [ "$new_ver" != "$old_ver" ]; then
baz_log "updating '$1' from v$old_ver -> v$new_ver"
baz_run_hook 'pre-update'
baz_git merge -X theirs origin --all
baz_git submodule update --init --recursive --remote --merge --force
baz_run_hook 'post-update'
bazp_source_env
fi
fi
bazp_reset_env
}
baz_update_plugin_local() {
origin="$(head -n 1 origin)"
local_bazp="$origin/$BAZP_INDEX"
[ -d "$origin" ] || baz_error "origin $origin does not exist for plugin '$1'"
[ -f "$local_bazp" ] || baz_error "no $BAZP_INDEX in $origin for plugin '$1'"
bazp_source_env
old_ver="$BAZP_VER"
if [ -n "$(diff -rq --color=never -x .git -x disabled -x method -x origin "$origin" . 2>&1 || :)" ]; then
bazp_reset_env
. "${local_bazp:?}"
bazp_check_env
new_ver="$BAZP_VER"
if [ "$new_ver" != "$old_ver" ]; then
baz_log "updating '$1' from v$old_ver -> v$new_ver"
baz_run_hook 'pre-update'
# i am in pain how stupid this expression is
# btw cant use -exec or find breaks
while read -r file; do
rm -rf -- "$file"
done <<<"$(find . -not -path . -and -not -path ./origin -and -not -path ./method -and -not -path ./disabled)"
cp -r -- "$origin"/* .
baz_run_hook 'post-update'
fi
fi
bazp_reset_env
}
baz_update_plugin() {
bplug="$(baz_get_base "$1")"
cd -- "$1"
method="$(head -n 1 method)"
fn="baz_update_plugin_$method"
command -v -- "$fn" >/dev/null ||
baz_error "unknown method to update '$bplug' : $method"
"$fn" "$bplug"
cd -- "$BAZP_INITDIR"
}
baz_describe_env() {
baz_log '----------------'
baz_log "description : $BAZP_DESCRIPTION"
baz_log '----------------'
baz_log "name : $BAZP_NAME"
baz_log "license : $BAZP_LICENSE"
baz_log "version : v$BAZP_VER"
baz_log "author : $BAZP_AUTHOR"
baz_log "root_plugin_directory : $BAZP_SRC"
baz_log "recomended_install_method : $BAZP_METHOD"
baz_log "source : $BAZP_SOURCE"
[ -f 'method' ] && baz_log "installed_with_method : $(head -n 1 method)"
[ -f 'origin' ] && baz_log "plugin_origin : $(head -n 1 origin)"
baz_log "disabled : $( ([ -f 'disabled' ] && echo 'yes') || echo 'no')"
bazp_reset_env
return 0
}
baz_describe_local() {
[ -d "$1" ] || baz_error "plugin directory '$1' does not exist"
cd -- "$1"
. "$BAZP_INDEX"
baz_describe_env
cd -- "$BAZP_INITDIR"
}
baz_describe_git() {
_repo_dir="${TMPDIR:?}/$(baz_get_base "$1")"
trap 'rm -rf -- "$_repo_dir"' 0 1 15
baz_log "cloning $1 ... " printf
baz_git_clone "$1" "$_repo_dir"
baz_eecho 'done'
baz_eecho
cd -- "$_repo_dir"
. "$BAZP_INDEX"
baz_describe_env
cd -- "$BAZP_INITDIR"
}
baz_describe_exist() {
_plugdir="${BAZ_PLUGDIR:?}/$1"
[ -d "${BAZ_PLUGDIR:?}" ] || baz_error 'plugin directory does not exist'
[ -d "${_plugdir:?}" ] || baz_error "plugin '$1' not installed"
cd -- "$_plugdir"
[ -f "${BAZP_INDEX:?}" ] || baz_error "'$BAZP_INDEX' does not exist"
. "$BAZP_INDEX"
baz_describe_env
cd -- "$BAZP_INITDIR"
}
# generators
baz_config_gen() {
cat <<EOF
#!/usr/bin/env bash
# default baz configuration ( generated by baz v$BAZ_VERSION )
# BAZP_NO_ASKCHECK : ask wether to check and / or edit $BAZP_INDEX
# false : ask
# true : dont ask
export BAZP_NO_ASKCHECK=false
# BAZP_NO_ASKINST : ask whether to ( un )install a plugin
# false : ask
# true : dont ask
export BAZP_NO_ASKINST=false
# you can blacklist any variable of $BAZP_INDEX by
# prepending BLACKLIST_ to it, for example :
export BLACKLIST_BAZP_NAME=(.*-unstable$ .*-dangerous$)
# will blacklist all plugins that end with either -unstable or -dangerous
# at the end of their name, blocking the property \$BAZP_NAME
# BAZP_SINGLETHREAD : only use a single thread for operations that can be multitreaded ( e.g. updating )
# false : multiple thdeads
# true : single thread
export BAZP_SINGLETHREAD=false
# ex: ft=sh
EOF
}
baz_preload_gen() {
cat <<EOF
#!/usr/bin/env bash
# default baz preload configuration ( generated by baz v$BAZ_VERSION )
# BAZP_NO_LOG : disable most logging
# false : log
# true : dont log
export BAZP_NO_LOG=false
# BAZ_NORLWRAP : disable the use of rlwrap
# ( wont use rlwrap even if available )
# false : use
# true : dont use
export BAZ_NORLWRAP=false
# ex: ft=sh
EOF
}
baz_loader_q() { echo "s|#{$1}|$2|g"; }
baz_loader_logging_fn() {
if [ "$BAZ_LOGGING_ENABLED" ]; then
tr -d '\n' <<EOF
if [ "\$BAZ_DEBUG_LOAD" ]; then
_baz_vecho() { echo "$BAZ_LOGGING_HEADER \$1">\\&2;}\\&\\&
_baz_vecho "generated by baz version '\$BAZ_LOADER_VERSION'";
else
_baz_vecho() { :;};
fi
EOF
fi
}
baz_loader_baz_log() {
if [ "$BAZ_LOGGING_ENABLED" ]; then
echo '_baz_vecho'
else
echo '#'
fi
}
baz_loader_delim() {
baz_use head awk printf
local shasum
shasum=sha1
if ! do_error=no baz_use "$shasum"; then
shasum="${shasum}sum"
baz_use "$shasum" || baz_error 'sha1 / sha1sum dependency error : unable to locate a valid sha1 hashing tool'
fi
printf '_____UNSAFE_%s_DONT.USE.ME_____' "$RANDOM$(head -n 10 /dev/urandom | "$shasum" | awk '{print substr($1, 0, 19)}')$((RANDOM * 2))"
}
baz_loader_gen() {
baz_use sed head awk printf grep read echo
local idx=0 loader
loader="$(sed \
-e "$(baz_loader_q 'BAZ_DATA_DIR' "$BAZ_DIR")" \
-e "$(baz_loader_q 'BAZ_PLUG_DIR' "$BAZ_PLUGDIR")" \
-e "$(baz_loader_q 'BAZ_RDELIM' "$(baz_loader_delim)")" \
-e "$(baz_loader_q 'BAZ_VER' "$BAZ_VERSION")" \
-e "$(baz_loader_q 'BAZ_LOGGING_FN' "$(baz_loader_logging_fn)")" \
-e "$(baz_loader_q 'BAZ_LOG' "$(baz_loader_baz_log)")" \
-e "$(baz_loader_q 'BAZ_NOP' "$([ "$BAZ_ENSURE_OK" ] && echo ':')")" \
-e "$(baz_loader_q 'BAZ_RD' "read -rd ''")" \
-e "s|:BAZ_LOADER_CMD|$BAZ_LOADER_PROG_BIN|g" \
-e '/^[[:blank:]]*#/d; /^[[:blank:]]*$/d; s/^[[:blank:]]*//g; s/_baz_vecho/._l/g' \
-e 's/ </</g; s/ >/>/g; s/ \&\& /\&\&/g; s/ || /||/g; s/; /;/g' \
"$1")"
loader="$(printf '%s' "$loader" | sed -e "$(echo "$loader" | grep '^_.*\(\) {$' |
awk '{print $1}' |
while read -r func_name; do
echo "s/${func_name::-2}/.$idx/g;"
idx="$((idx + 1))"
done)" -e 's/() {/(){/g')"
loader="${loader//+([[:blank:]])/ }"
loader="${loader# }"
loader="${loader% }"
printf '%s' "$loader"
}
# installer helpers
bazp_check_env() {
for env in "${BAZP_ENV[@]}"; do
if [ ! "${!env}" ]; then
baz_eecho 'error'
baz_error "bazp : '$env' ( a required propery ) is not set in $BAZP_INDEX"
fi
done
for listing in "${BAZP_ENV[@]}"; do
_blacklist="BLACKLIST_${listing}"
[ "${!_blacklist}" ] || continue
baz_in_array "${!_blacklist}" "${!listing}" &&
baz_error "$listing '${!listing}' is blacklisted by $_blacklist"
done
}
bazp_source_env() {
bazp_reset_env
. "$BAZP_INDEX"
bazp_check_env
}
bazp_reset_env() {
for env in "${BAZP_ENV[@]}"; do
unset "$env"
done
}
bazp_install_dir() {
[ -d "$1" ] || baz_error "'$1' is not a directory"
cd -- "$1"
[ -f "$BAZP_INDEX" ] || baz_error "$BAZP_INDEX does not exist"
if [ "$BAZP_NO_ASKCHECK" != 'true' ]; then
baz_yn "do you want to check out $BAZP_INDEX ?" && less -- "$BAZP_INDEX"
baz_yn "do you want to edit $BAZP_INDEX ?" && ${EDITOR:-ed} "$BAZP_INDEX"
fi
bazp_source_env
BAZP_NAME="$(echo "$BAZP_NAME" | baz_sanitize)"
bazp_check_env
[ -d "${BAZ_PLUGDIR:?}" ] || mkdir -p -- "${BAZ_PLUGDIR:?}"
[ -d "${BAZ_PLUGDIR:?}/${BAZP_NAME:?}" ] && baz_error "plugin '$BAZP_NAME' already is installed"
baz_run_hook 'pre-install'
baz_log "installing plugin : ${BAZP_NAME:?} ... " printf
cp -r . "${BAZ_PLUGDIR:?}/${BAZP_NAME:?}"
if [ ! "$_bazp_no_write" ]; then
echo 'local' >"${BAZ_PLUGDIR:?}/${BAZP_NAME:?}/method"
pwd >"${BAZ_PLUGDIR:?}/${BAZP_NAME:?}/origin"
fi
baz_eecho 'done'
baz_run_hook 'post-install'
cd -- "$BAZP_INITDIR"
[ "$_bazp_no_clearenv" ] || bazp_reset_env
}
bazp_install_git() {
baz_use git
_plugdir="${TMPDIR:?}/$(baz_get_base "$1")"
if [ -e "$_plugdir" ]; then
baz_log "removing $1 ... " printf
rm -Ir -- "$_plugdir" || baz_error 'canceled'
baz_eecho 'done'
fi
baz_log "cloning repository : $1 ... " printf
baz_git_clone "$1" "$_plugdir" || baz_error "failed to clone $1"
baz_eecho 'done'
baz_log "installing $_plugdir"
_bazp_no_clearenv=true _bazp_no_write=true bazp_install_dir "$_plugdir"
echo 'git' >"${BAZ_PLUGDIR:?}/${BAZP_NAME:?}/method"
bazp_reset_env
rm -rf -- "$_plugdir"
}
bazp_install_dirs() {
for dir in "$@"; do
baz_log "installing : $dir"
bazp_install_dir "$dir"
done
}
bazp_install_gits() {
for repo in "$@"; do
baz_log "installing : $repo"
bazp_install_git "$repo"
done
}
# functionality
baz_help() {
[ "$BAZP_NO_LOG" = true ] && return
baz_elog "help for baz v$BAZ_VERSION"
{
baz_log 'subcommands'
{
baz_entry 'help' 'print help'
baz_entry 'setup' 'setup baz plugin manager'
baz_log "make sure you have at least one of the loaders in CWD" | baz_indent
baz_entry 'unsetup' 'unsetup ( remove ) the baz plugin manager'
baz_entry 'install [method] [atoms...]' 'install plugins'
{
baz_entry 'local' 'local plugin from a directory'
baz_log 'atom type : path to plugin, e.g. /tmp/myplug' | baz_indent
baz_entry 'git' 'git plugin from git'
baz_log 'atom type : <repo url>, e.g. https://ari-web.xyz/gh/baz-example-plugin' | baz_indent
} | baz_indent
baz_entry 'uninstall [plugins...]' 'uninstall plugins'
baz_entry 'list' 'list all installed plugins'
baz_entry 'update <plugins...>' 'update all installed or specified plugins'
baz_entry 'info [exist|local|git] [atoms...]' 'describe ( get info ) about plugins'
{
baz_entry 'exist' 'describe existing ( installed ) plugin'
baz_log 'atom type : plugin name, e.g. myplug' | baz_indent
baz_entry 'local' 'describe local plugin'
baz_log 'atom type : path to plugin, e.g. /tmp/myplug' | baz_indent
baz_entry 'git' 'describe plugin from a git source'
baz_log 'atom type : <repo url>, e.g. https://ari-web.xyz/gh/baz-example-plugin' | baz_indent
} | baz_indent
baz_entry 'upgrade' 'upgrade baz'
baz_log "make sure you're in the baz git repo directory" | baz_indent
baz_entry 'version' 'print version and exit'
baz_entry 'disable [plugins...]' 'disable plugins'
baz_entry 'enable [plugins...]' 'enable plugins'
} | baz_indent
echo
baz_log 'user loader functions'
{
baz_log 'can return anything'
baz_entry 'baz_load_plugin_low <plug dir>' 'load a baz plugin from a specified directory'
baz_log 'note : this is quite a low-level function, be careful' | baz_indent
baz_entry 'baz_loader' 'load all enabled installed plugins'
{
baz_log 'note : will leave environment variables of last plugin that was loaded'
baz_log 'all environment variables from baz.env' | baz_indent
} | baz_indent
} | baz_indent
} | baz_indent
}
baz_setup() {
baz_use awk
if [ "$_baz_upgrade" ]; then
baz_log "upgrading baz v$BAZ_VERSION"
baz_log "updating repo ... " printf
baz_git_reset || baz_error 'failed to reset the repo'
baz_git pull --recurse-submodules=yes || baz_error 'failed to pull from repo'
baz_eecho 'done'
else
baz_log "setting up baz v$BAZ_VERSION"
fi
if [ ! -d "$BAZ_DIR" ]; then
baz_log "making baz data directory : $(baz_unexpand_path "$BAZ_DIR")... " printf
mkdir -p -- "$BAZ_DIR"
baz_eecho 'done'
fi
if [ ! -d "$BAZ_CONFDIR" ]; then
baz_log "making baz config directory : $(baz_unexpand_path "$BAZ_CONFDIR") ... " printf
mkdir -p -- "$BAZ_CONFDIR"
baz_eecho 'done'
fi
baz_log "generating baz config : $(baz_unexpand_path "$BAZ_CONF") ... " printf
if [ ! -f "$BAZ_CONF" ] || [ "$BAZ_NEWCONF" ]; then
baz_config_gen >"$BAZ_CONF"
baz_eecho 'done'
else
baz_eecho 'found'
fi
baz_log "generating baz preload : $(baz_unexpand_path "$BAZ_PRE") ... " printf
if [ ! -f "$BAZ_PRE" ] || [ "$BAZ_NEWCONF" ]; then
baz_preload_gen >"$BAZ_PRE"
baz_eecho 'done'
else
baz_eecho 'found'
fi
if [ ! "$BAZ_NO_CC" ] && do_error=no baz_use "$CC" && [ -f "$BAZ_LOADER_PROG" ]; then
if [ -f "$BAZ_LOADER_TEMPLATE" ]; then
baz_log "generating wrapper to $(baz_unexpand_path "$BAZ_LOADER") ... " printf
baz_loader_gen "$BAZ_LOADER_TEMPLATE" >"$BAZ_LOADER"
baz_eecho 'done'
else
baz_log "no wrapper template ( $(baz_unexpand_path "$BAZ_LOADER_TEMPLATE") ) found in CWD"
fi
baz_log "compiling loader $(baz_unexpand_path "$BAZ_LOADER_PROG_BIN") ... " printf
# shellcheck disable=SC2086
if "$CC" $CFLAGS "$BAZ_LOADER_PROG" $([ "$BAZ_LOGGING_ENABLED" ] && echo "-D LOGGING=\"\\\"$BAZ_LOGGING_HEADER\\\"\"") -o "$BAZ_LOADER_PROG_BIN"; then
if [ "$STRIP" ] && do_error=no baz_use "$STRIP"; then
# shellcheck disable=SC2086
"$STRIP" $STRIPFLAGS "$BAZ_LOADER_PROG_BIN" || baz_eecho 'stripping failed'
fi
baz_eecho 'done'
else
baz_eecho 'complilation failed'
fi
elif [ -f "$BAZ_LOADER_TEMPLATE" ]; then
baz_log "cannot use the c loader, using bash loader"
baz_log "generating bash loader to $(baz_unexpand_path "$BAZ_LOADER") ... " printf
baz_loader_gen "$BAZ_BASH_LOADER_TEMPLATE" >"$BAZ_LOADER"
baz_eecho 'done'
else
baz_log "unable to use any loaders"
fi
baz_eecho
if [ "$_baz_upgrade" ]; then
baz_log "done ! baz has been upgraded"
else
baz_log "done ! now just add this ( if it already isnt there ) to your ~/.bashrc :"
baz_eecho
cat <<EOF
export BAZ_LOADER_ENABLED=true
_baz_loader="\$HOME/.local/share/baz/loader.sh"
# shellcheck disable=SC1090
[ ! -f "\$_baz_loader" ] || source "\$_baz_loader"
EOF
fi
}
baz_unsetup() {
baz_log "removing baz v$BAZ_VERSION"
baz_log "removing baz data directory : $(baz_unexpand_path "$BAZ_DIR") ... " printf
rm -rf -- "$BAZ_DIR"
baz_eecho 'done'
baz_log "now just remove $0 and remove the loader lines from bashrc"
}
baz_install() {
[ "$1" ] || baz_error 'no method specified'
[ "$2" ] || baz_error 'no atom specified'
baz_log 'will install :'
{
for dir in "${@:2}"; do
baz_log "$dir"
done
} | baz_indent
baz_eecho
if [ "$BAZP_NO_ASKINST" != 'true' ]; then
baz_yn "are you sure ?" ||
baz_error 'aborting, canceled by the user'
fi
export BAZP_INSTALL_METHOD="$1"
case "$1" in
local) bazp_install_dirs "${@:2}" ;;
git) bazp_install_gits "${@:2}" ;;
*) baz_error "method '$1' does not exist" ;;
esac
}
baz_uninstall() {
[ "$1" ] || baz_error 'no plugins specified'
baz_log 'will uninstall :'
_ex="${TMPDIR:?}/.baz_uninstall.ss"
{
set -e
for plugin in "$@"; do
baz_check_plugin_state "$_ex"
if [ ! -d "${BAZ_PLUGDIR:?}/${plugin:?}" ]; then
: >"$_ex"
baz_error "plugin '$plugin' is not installed"
fi
baz_log "$plugin"
done
} | baz_indent
baz_eecho
[ -e "$_ex" ] && rm -f -- "$_ex" && exit 1
if [ "$BAZP_NO_ASKINST" != 'true' ]; then
baz_yn 'are you sure ?' || baz_error 'aborting : canceled by the user'
fi
for plugin in "$@"; do
baz_check_plugin_state
{
baz_log "uninstalling : $plugin ..."
cd "${BAZ_PLUGDIR:?}/$plugin"
. "$BAZP_INDEX"
baz_run_hook 'pre-uninstall'
bazp_reset_env
cd "$BAZP_INITDIR"
rm -rf -- "${BAZ_PLUGDIR:?}/$plugin"
} &
[ "$BAZP_SINGLETHREAD" = true ] && wait
done
[ "$BAZP_SINGLETHREAD" != true ] && wait
}
baz_list() {
[ -d "${BAZ_PLUGDIR:?}" ] || baz_error 'no plugin directory'
[ -z "$(ls -A -- "${BAZ_PLUGDIR:?}")" ] && baz_error 'no plugins installed'
baz_log 'installed plugins :'
{
while read -r dir; do
_plugent="$(baz_get_base "$dir")"
[ -f "$dir/disabled" ] && _plugent+=' [DISABLED]'
baz_log "$_plugent"
done <<<"$(find "${BAZ_PLUGDIR:?}" -maxdepth 1 -not -path "${BAZ_PLUGDIR:?}" -type d)"
} | baz_indent >&2
}
baz_update() {
baz_log "updating plugins $([ "$BAZP_SINGLETHREAD" != true ] && echo 'in paralel ')... " printf
if [ "$1" ]; then
baz_eecho 'specified'
for plugin in "$@"; do
plugin="$(baz_get_base "${plugin:?}")" baz_check_plugin_state
baz_update_plugin "${BAZ_PLUGDIR:?}/${plugin:?}" &
done
else
[ -d "${BAZ_PLUGDIR:?}" ] || baz_error 'no plugin directory'
baz_eecho 'all'
for plugin in "${BAZ_PLUGDIR:?}"/*; do
baz_update_plugin "${plugin:?}" &
[ "$BAZP_SINGLETHREAD" = true ] && wait
done
fi
if [ "$BAZP_SINGLETHREAD" != true ]; then
baz_log 'waiting for updates to finish'
wait
fi
baz_log 'updated !'
}
baz_info() {
[ "$1" ] || baz_error 'no plugin type specified'
[ "$2" ] || baz_error 'no atom specified'
fn="baz_describe_$1"
command -v -- "$fn" >/dev/null ||
baz_error "plugin type '$1' is not known"
for plugin in "${@:2}"; do
[ "$1" = 'exist' ] && baz_check_plugin_state
"$fn" "$plugin"
baz_eecho
done
}
baz_upgrade() {
baz_log 'upgrading baz'
baz_yn 'do you want to overwrite your config ?' && export BAZ_NEWCONF=true
_baz_upgrade=true baz_setup
}
baz_disable() {
[ "$1" ] || baz_error 'no plugins specified'
for plugin in "$@"; do
baz_check_plugin_state
baz_log "disabling plugin $plugin"
: >"${BAZ_PLUGDIR:?}/${plugin:?}/disabled"
done
}
baz_enable() {
[ "$1" ] || baz_error 'no plugins specified'
for plugin in "$@"; do
baz_check_plugin_state
baz_log "enabling plugin $plugin"
rm -f -- "${BAZ_PLUGDIR:?}/${plugin:?}/disabled"
done
}
main() {
baz_use printf
[ "$_BAZ_NO_PRE" != true ] && [ -f "$BAZ_PRE" ] && . "$BAZ_PRE"
if [ "$BAZ_NORLWRAP" != true ] && command -v rlwrap >/dev/null; then
baz_use trap rlwrap return
_BAZ_NO_PRE=true BAZ_NORLWRAP=true exec rlwrap -n -H /dev/null -- "$0" "$@"
fi
set -e
baz_use trap command find rm cp mkdir \
read printf unset return \
while echo git wait head
if [ -f "$BAZ_CONF" ]; then
. "$BAZ_CONF"
else
baz_elog 'warning : no config found'
fi
if [ "$BAZ_LOADER_VERSION" ] && [ "$BAZ_LOADER_VERSION" != "$BAZ_VERSION" ]; then
baz_elog "baz loader version ( $BAZ_LOADER_VERSION ) does not match current version ( $BAZ_VERSION )"
fi
bazp_reset_env
case "${1//[[:space:]]/}" in
help) baz_help ;;
setup) baz_setup ;;
unsetup) baz_unsetup ;;
install) baz_install "$2" "${@:3}" ;;
uninstall) baz_uninstall "${@:2}" ;;
list) baz_list ;;
update) baz_update "${@:2}" ;;
info) baz_info "$2" "${@:3}" ;;
upgrade) baz_upgrade ;;
version) echo "v$BAZ_VERSION" ;;
disable) baz_disable "${@:2}" ;;
enable) baz_enable "${@:2}" ;;
'')
baz_help >&2
exit 1
;;
*)
baz_elog "error : subcommand '$1' is not valid"
baz_help | baz_indent >&2
exit 1
;;
esac
}
[ "$BAZ_HEADER" ] || main "$@"