scwrypts/zsh/lib/utils/io.zsh
yage f3e70c61cb v3.9.0
=====================================================================

--- Changes ------------------------------

- scwrypts runner has new arguments
  -q/--quiet   allows quiet-mode operation while still logging to logfiles
  -v/--verbose forces verbose mode
    --version  longform required (-v is now for "verbose" mode)

- scwrypts runner now auto-detects certain CLI usage, running in quiet,
  logged mode if pattern match successfully identifies a single scwrypt
  (or when using --name); use --verbose to override this behavior

- 'k exec' no longer requires double '--' if a '--' comes after
  - old : k exec -it my-pod-0 -- -- /bin/sh
  + new : k exec -it my-pod-0 -- /bin/sh
  + still works : k -- exec -it my-pod-0 -- /bin/sh

--- Bug Fixes ----------------------------

- fixed various plugins/kubectl auto-completion settings; arguments
  after '--' or profile number (e.g. 'k 1 get deployments') will now
  appropriately autocomplete in the indicated profile

- helm template functions now work on related .tpl files as well
  (renders from chart root)

- fixed some goofy UTF-8 icons in zsh/lib/utils/io

--- New Features -------------------------

- (experimental) scwrypts zsh plugin for interactive command selection
  (like CTRL+SPACE), but allows you to build command arguments,
  providing help dialogue for the selected command

--- New Scripts --------------------------

- zsh/misc/tally ) helps keep tally-counts of things; helpful when
                   running long scripts "what iteration am I on"
2023-12-11 18:19:37 -07:00

232 lines
5.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

PRINT() {
local MESSAGE
local LAST_LINE_END='\n'
local STDERR=1
local STDOUT=0
local LTRIM=1
while [[ $# -gt 0 ]]
do
case $1 in
-n | --no-trim-tabs ) LTRIM=0 ;;
-x | --no-line-end ) LAST_LINE_END='' ;;
-o | --use-stdout ) STDOUT=1; STDERR=0 ;;
* ) MESSAGE+="$(echo $1) " ;;
esac
shift 1
done
MESSAGE="$(echo "$MESSAGE" | sed 's/%/%%/g')"
local STYLED_MESSAGE="$({
printf "${COLOR}"
while IFS='' read line
do
[[ $PREFIX =~ ^[[:space:]]\+$ ]] && printf '\n'
printf "${PREFIX} : $(echo "$line" | sed 's/^ \+//; s/ \+$//')"
PREFIX=$(echo $PREFIX | sed 's/./ /g')
done <<< $MESSAGE
})"
STYLED_MESSAGE="${COLOR}$(echo "$STYLED_MESSAGE" | sed 's/%/%%/g')${__COLOR_RESET}${LAST_LINE_END}"
[[ $STDERR -eq 1 ]] && printf $STYLED_MESSAGE >&2
[[ $STDOUT -eq 1 ]] && printf $STYLED_MESSAGE
return 0
}
[ ! $ERRORS ] && ERRORS=0
ERROR() { PREFIX="ERROR ✖" COLOR=$__RED PRINT "$@"; ((ERRORS+=1)); }
SUCCESS() { PREFIX="SUCCESS ✔" COLOR=$__GREEN PRINT "$@"; }
WARNING() { PREFIX="WARNING " COLOR=$__ORANGE PRINT "$@"; }
STATUS() { PREFIX="STATUS " COLOR=$__BLUE PRINT "$@"; }
REMINDER() { PREFIX="REMINDER " COLOR=$__PURPLE PRINT "$@"; }
INFO() { PREFIX="INFO " COLOR=$__WHITE PRINT "$@"; }
PROMPT() {
PREFIX="PROMPT " COLOR=$__CYAN PRINT "$@"
PREFIX="USER ⌨" COLOR=$__CYAN PRINT '' --no-line-end
}
FAIL() { ERROR "${@:2}"; exit $1; }
ABORT() { FAIL 69 'user abort'; }
CHECK_ERRORS() {
local FAIL_OUT=1
local DISPLAY_USAGE=1
while [[ $# -gt 0 ]]
do
case $1 in
--no-fail ) FAIL_OUT=0 ;;
--no-usage ) DISPLAY_USAGE=0 ;;
esac
shift 1
done
[ ! $ERRORS ] && ERRORS=0
[[ $ERRORS -eq 0 ]] && return 0
[[ $DISPLAY_USAGE -eq 1 ]] && USAGE
[[ $FAIL_OUT -eq 1 ]] && exit $ERRORS
return $ERRORS
}
USAGE() { # formatter for USAGE variable
[ ! $USAGE ] && return 0
local USAGE_LINE=$(echo $USAGE | grep -i '^[ ]*usage *:' | sed 's/^[ ]*//')
[ $USAGE__usage ] && echo $USAGE_LINE | grep -q 'usage: -' \
&& USAGE_LINE=$(echo $USAGE_LINE | sed "s/usage: -/usage: $USAGE__usage/")
[ $__SCWRYPT ] \
&& USAGE_LINE=$(
echo $USAGE_LINE \
| sed "s;^[^:]*:;& scwrypts $SCWRYPT_NAME --;" \
| sed 's/ \{2,\}/ /g; s/scwrypts -- scwrypts/scwrypts/' \
)
local THE_REST=$(echo $USAGE | grep -vi '^[ ]*usage *:' )
local DYNAMIC_USAGE_ELEMENT
#
# create dynamic usage elements (like 'args') by defining USAGE__<element>
# then using the syntax "<element>: -" in your USAGE variable
#
# e.g.
#
# USAGE__args="
# subcommand arg 1 arg 1 description
# subcommand arg 2 some other description
# "
#
# USAGE="
# usage: some-command [...args...]
#
# args: -
# -h, --help some arguments are applicable everywhere
# "
#
for DYNAMIC_USAGE_ELEMENT in $(echo $THE_REST | sed -n 's/^\([^:]*\): -$/\1/p')
do
DYNAMIC_USAGE_ELEMENT_TEXT=$(eval echo '$USAGE__'$DYNAMIC_USAGE_ELEMENT)
[[ ! $DYNAMIC_USAGE_ELEMENT =~ ^description$ ]] \
&& DYNAMIC_USAGE_ELEMENT_TEXT=$(echo $DYNAMIC_USAGE_ELEMENT_TEXT | sed 's/[^ ]/ &/')
THE_REST=$(echo $THE_REST | perl -pe "s/$DYNAMIC_USAGE_ELEMENT: -/$DYNAMIC_USAGE_ELEMENT:\n$DYNAMIC_USAGE_ELEMENT_TEXT\n\n/")
done
# allow for dynamic 'description: -' but delete the 'description:' header line
THE_REST=$(echo $THE_REST | sed '/^[ ]*description:$/d')
echo "$__DARK_BLUE$USAGE_LINE$__COLOR_RESET\n\n$THE_REST" \
| sed "s/^\t\+//; s/\s\+$//; s/^\\s*$//;" \
| sed '/./,$!d; :a; /^\n*$/{$d;N;ba;};' \
| perl -p0e 's/\n{2,}/\n\n/g' \
| perl -p0e 's/:\n{2,}/:\n/g' \
>&2
}
INPUT() {
PROMPT "${@:2}"
READ $1
local VALUE=$(eval echo '$'$1)
[ $VALUE ]
}
Yn() {
PROMPT "$@ [Yn]"
[ $CI ] && { echo y; return 0; }
[ $__SCWRYPTS_YES ] && [[ $__SCWRYPTS_YES -eq 1 ]] && { echo y; return 0; }
local Yn; READ -k Yn; echo >&2
[[ $Yn =~ [nN] ]] && return 1 || return 0
}
yN() {
PROMPT "$@ [yN]"
[ $CI ] && { echo y; return 0; }
[ $__SCWRYPTS_YES ] && [[ $__SCWRYPTS_YES -eq 1 ]] && { echo y; return 0; }
local yN; READ -k yN; echo >&2
[[ $yN =~ [yY] ]] && return 0 || return 1
}
CAPTURE() {
[ ! $USAGE ] && USAGE="
usage: stdout-varname stderr-varname [...cmd and args...]
captures stdout and stderr on separate variables for a command
"
{
IFS=$'\n' read -r -d '' $2;
IFS=$'\n' read -r -d '' $1;
} < <((printf '\0%s\0' "$(${@:3})" 1>&2) 2>&1)
}
#####################################################################
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; }
}
LESS() { less -R $@ </dev/tty >/dev/tty; }
FZF() {
[ $CI ] && {
ERROR 'currently in CI, but FZF requires user input'
exit 1
}
local FZF_ARGS=()
FZF_ARGS+=(-i)
FZF_ARGS+=(--ansi)
FZF_ARGS+=(--bind=ctrl-c:cancel)
FZF_ARGS+=(--height=50%)
FZF_ARGS+=(--layout=reverse)
local SELECTION=$(fzf ${FZF_ARGS[@]} --layout=reverse --prompt "$1 : " ${@:2})
PROMPT "$1"
echo $SELECTION >&2
echo $SELECTION
}
FZF_HEAD() { FZF $@ --print-query | sed '/^$/d' | head -n1; } # prefer user input over selected
FZF_TAIL() { FZF $@ --print-query | sed '/^$/d' | tail -n1; } # prefer selected over user input
READ() {
[ $CI ] && {
INFO 'currently in CI, skipping READ'
return 0
}
read $@ </dev/tty
}
EDIT() {
[ $CI ] && {
INFO 'currently in CI, skipping EDIT'
return 0
}
STATUS "opening '$1' for editing"
$EDITOR $@ </dev/tty >/dev/tty
SUCCESS "finished editing '$1'!"
}
YQ() {
yq --version | grep -q mikefarah || {
yq $@
return $?
}
yq eval '... comments=""' | yq $@
}