2024-02-06 21:06:44 +00:00
|
|
|
|
#####################################################################
|
|
|
|
|
### basic colorized print messages ##################################
|
|
|
|
|
#####################################################################
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
source "${0:a:h}/io.print.zsh"
|
|
|
|
|
[ ! $ERRORS ] && ERRORS=0
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
ERROR() { # command encountered an error
|
|
|
|
|
[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \
|
|
|
|
|
&& PREFIX="ERROR ✖" COLOR=$__RED PRINT "$@"
|
|
|
|
|
((ERRORS+=1))
|
|
|
|
|
return $ERRORS
|
|
|
|
|
}
|
2023-06-27 11:00:06 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
SUCCESS() { # command completed successfully
|
|
|
|
|
[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \
|
|
|
|
|
&& PREFIX="SUCCESS ✔" COLOR=$__GREEN PRINT "$@"
|
|
|
|
|
}
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
REMINDER() { # include sysadmin reminder or other important notice to users
|
|
|
|
|
[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \
|
|
|
|
|
&& PREFIX="REMINDER " COLOR=$__BRIGHT_MAGENTA PRINT "$@"
|
|
|
|
|
}
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
STATUS() { # general status updates (prefer this to generic 'echo')
|
|
|
|
|
[[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] \
|
|
|
|
|
&& PREFIX="STATUS " COLOR=$__BLUE PRINT "$@"
|
|
|
|
|
}
|
2023-06-27 11:00:06 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
WARNING() { # warning-level messages; not errors
|
|
|
|
|
[[ $SCWRYPTS_LOG_LEVEL -ge 3 ]] \
|
|
|
|
|
&& PREFIX="WARNING " COLOR=$__YELLOW PRINT "$@"
|
|
|
|
|
}
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
DEBUG() { # helpful during development or (sparingly) to help others' development
|
|
|
|
|
[[ $SCWRYPTS_LOG_LEVEL -ge 4 ]] \
|
|
|
|
|
&& PREFIX="DEBUG ℹ" COLOR=$__WHITE PRINT "$@"
|
2023-02-22 01:44:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
PROMPT() { # you probably want to use yN or INPUT from below
|
|
|
|
|
[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \
|
|
|
|
|
&& PREFIX="PROMPT " COLOR=$__CYAN PRINT "$@" \
|
|
|
|
|
&& PREFIX="USER ⌨" COLOR=$__BRIGHT_CYAN PRINT '' --no-line-end \
|
|
|
|
|
;
|
2023-02-22 01:44:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
FAIL() { SCWRYPTS_LOG_LEVEL=1 ERROR "${@:2}"; exit $1; }
|
2023-02-22 01:44:27 +00:00
|
|
|
|
ABORT() { FAIL 69 'user abort'; }
|
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
#####################################################################
|
|
|
|
|
### check for reported errors and format USAGE contents #############
|
|
|
|
|
#####################################################################
|
|
|
|
|
|
2023-02-22 01:44:27 +00:00
|
|
|
|
CHECK_ERRORS() {
|
2024-02-06 21:06:44 +00:00
|
|
|
|
local FAIL_OUT=true
|
|
|
|
|
local DISPLAY_USAGE=true
|
|
|
|
|
|
|
|
|
|
[ ! $ERRORS ] && ERRORS=0
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
|
|
|
|
while [[ $# -gt 0 ]]
|
|
|
|
|
do
|
|
|
|
|
case $1 in
|
2024-02-06 21:06:44 +00:00
|
|
|
|
--fail ) FAIL_OUT=true ;;
|
|
|
|
|
--no-fail ) FAIL_OUT=false ;;
|
|
|
|
|
|
|
|
|
|
--usage ) DISPLAY_USAGE=true ;;
|
|
|
|
|
--no-usage ) DISPLAY_USAGE=false ;;
|
2023-02-22 01:44:27 +00:00
|
|
|
|
esac
|
|
|
|
|
shift 1
|
|
|
|
|
done
|
|
|
|
|
|
2023-08-30 23:26:13 +00:00
|
|
|
|
[[ $ERRORS -eq 0 ]] && return 0
|
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
[[ $DISPLAY_USAGE =~ true ]] && USAGE
|
2023-08-30 23:26:13 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
[[ $FAIL_OUT =~ true ]] && exit $ERRORS || return $ERRORS
|
2023-02-22 01:44:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
source "${0:a:h}/io.usage.zsh"
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
#####################################################################
|
|
|
|
|
### facilitate user prompt and input ################################
|
|
|
|
|
#####################################################################
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
# yes/no prompts && = yes (exit code 0)
|
|
|
|
|
# || = no (exit code 1)
|
|
|
|
|
Yn() { [[ ! $(READ_YN $@ '[Yn]') =~ [nN] ]]; } # default 'yes'
|
|
|
|
|
yN() { [[ $(READ_YN $@ '[yN]') =~ [yY] ]]; } # default 'no'
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
INPUT() { # read a single line of user input
|
2023-02-22 01:44:27 +00:00
|
|
|
|
PROMPT "${@:2}"
|
|
|
|
|
READ $1
|
|
|
|
|
local VALUE=$(eval echo '$'$1)
|
|
|
|
|
[ $VALUE ]
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
source "${0:a:h}/io.fzf.zsh" # allow user to select from a list of inputs
|
|
|
|
|
|
|
|
|
|
EDIT() { # edit a file in user's preferred editor
|
|
|
|
|
[ $CI ] && {
|
|
|
|
|
WARNING 'currently in CI, skipping EDIT'
|
|
|
|
|
return 0
|
|
|
|
|
}
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
STATUS "opening '$1' for editing"
|
|
|
|
|
$EDITOR $@ </dev/tty >/dev/tty
|
|
|
|
|
SUCCESS "finished editing '$1'!"
|
2023-02-22 01:44:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
#####################################################################
|
|
|
|
|
### basic commands with tricky states or default requirements #######
|
|
|
|
|
#####################################################################
|
|
|
|
|
|
|
|
|
|
LESS() { less -R $@ </dev/tty >/dev/tty; }
|
|
|
|
|
|
|
|
|
|
YQ() {
|
|
|
|
|
yq --version | grep -q mikefarah || {
|
|
|
|
|
yq $@
|
|
|
|
|
return $?
|
|
|
|
|
}
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
yq eval '... comments=""' | yq $@
|
2023-02-22 01:44:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
#####################################################################
|
|
|
|
|
### other i/o utilities #############################################
|
|
|
|
|
#####################################################################
|
|
|
|
|
|
2023-10-30 20:23:23 +00:00
|
|
|
|
CAPTURE() {
|
|
|
|
|
[ ! $USAGE ] && USAGE="
|
2024-02-06 21:06:44 +00:00
|
|
|
|
usage: stdout-varname stderr-varname [...cmd and args...]
|
2023-10-30 20:23:23 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
captures stdout and stderr on separate variables for a command
|
2023-10-30 20:23:23 +00:00
|
|
|
|
"
|
|
|
|
|
{
|
|
|
|
|
IFS=$'\n' read -r -d '' $2;
|
|
|
|
|
IFS=$'\n' read -r -d '' $1;
|
|
|
|
|
} < <((printf '\0%s\0' "$(${@:3})" 1>&2) 2>&1)
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
|
|
|
|
GETSUDO() {
|
|
|
|
|
echo "\\033[1;36mPROMPT : checking sudo password...\\033[0m" >&2
|
|
|
|
|
sudo echo hi >/dev/null 2>&1 </dev/tty \
|
|
|
|
|
&& SUCCESS '...authenticated!' \
|
|
|
|
|
|| { ERROR 'failed :c'; return 1; }
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
READ() {
|
|
|
|
|
[ $CI ] && [ -t 0 ] \
|
|
|
|
|
&& FAIL 42 'currently in CI, but attempting interactive read; aborting'
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
local FORCE_USER_INPUT=false
|
|
|
|
|
local ARGS=()
|
2023-08-10 17:08:57 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
while [[ $# -gt 0 ]]
|
|
|
|
|
do
|
|
|
|
|
case $1 in
|
|
|
|
|
--force-user-input ) FORCE_USER_INPUT=true ;;
|
|
|
|
|
-k )
|
|
|
|
|
ARGS+=($1)
|
|
|
|
|
;;
|
|
|
|
|
* ) ARGS+=($1) ;;
|
|
|
|
|
esac
|
|
|
|
|
shift 1
|
|
|
|
|
done
|
2023-08-10 17:08:57 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
while read -k -t 0; do :; done; # flush user stdin
|
|
|
|
|
|
|
|
|
|
case $FORCE_USER_INPUT in
|
|
|
|
|
true )
|
|
|
|
|
read ${PREARGS[@]} ${ARGS[@]} $@ </dev/tty
|
|
|
|
|
;;
|
|
|
|
|
false )
|
|
|
|
|
[ -t 0 ] || ARGS=(-u 0 ${ARGS[@]})
|
|
|
|
|
read ${ARGS[@]} $@
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2023-02-22 01:44:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
READ_YN() { # yes/no read is suprisingly tricky
|
|
|
|
|
local FORCE_USER_INPUT=false
|
|
|
|
|
local USERPROMPT=()
|
|
|
|
|
local READ_ARGS=()
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
while [[ $# -gt 0 ]]
|
|
|
|
|
do
|
|
|
|
|
case $1 in
|
|
|
|
|
--force-user-input )
|
|
|
|
|
# overrides 'scwrypts -y' and stdin pipe but not CI
|
|
|
|
|
FORCE_USER_INPUT=true
|
|
|
|
|
READ_ARGS+=($1)
|
|
|
|
|
;;
|
|
|
|
|
* ) USERPROMPT+=($1) ;;
|
|
|
|
|
esac
|
|
|
|
|
shift 1
|
|
|
|
|
done
|
2023-02-22 01:44:27 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
##########################################
|
2023-11-22 22:54:16 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
local SKIP_USER_INPUT=false
|
2023-11-22 22:54:16 +00:00
|
|
|
|
|
2024-02-06 21:06:44 +00:00
|
|
|
|
[ $CI ] \
|
|
|
|
|
&& SKIP_USER_INPUT=true
|
|
|
|
|
|
|
|
|
|
[ $__SCWRYPTS_YES ] && [[ $__SCWRYPTS_YES -eq 1 ]] && [[ $FORCE_USER_INPUT =~ false ]] \
|
|
|
|
|
&& SKIP_USER_INPUT=true
|
|
|
|
|
|
|
|
|
|
##########################################
|
|
|
|
|
|
|
|
|
|
local yn
|
|
|
|
|
PROMPT "${USERPROMPT[@]}"
|
|
|
|
|
|
|
|
|
|
case $SKIP_USER_INPUT in
|
|
|
|
|
true ) yn=y ;;
|
|
|
|
|
false )
|
|
|
|
|
[[ $FORCE_USER_INPUT =~ true ]] && [[ $SCWRYPTS_LOG_LEVEL -lt 1 ]] \
|
|
|
|
|
&& echo -n "${USERPROMPT[@]} : " >&2
|
|
|
|
|
|
|
|
|
|
READ ${READ_ARGS[@]} -s -k yn
|
|
|
|
|
|
|
|
|
|
[[ $FORCE_USER_INPUT =~ true ]] && [[ $SCWRYPTS_LOG_LEVEL -lt 1 ]] \
|
|
|
|
|
&& echo $yn >&2
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
[[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] && echo $yn >&2
|
|
|
|
|
|
|
|
|
|
echo $yn
|
2023-11-22 22:54:16 +00:00
|
|
|
|
}
|