e7484103b9
===================================================================== A follow-up to V5 focused on hardening the environment system and expanding the ZSH logging/caching toolkit. No migration required from v5.0.x, though note the log-level reorganization below may quiet some messages at lower verbosities. --- New Features ------------------------- - persistent cross-runtime cache for ZSH-type scwrypts; extends the v5.0 runtime speedup cache to survive between runs with automatic hash-based invalidation (toggle via SCWRYPTS__ZSH_CACHE_ENABLED) - new 'trace' log level (5) and echo.trace, plus '-v VARNAME' state injection for echo.debug / echo.trace to surface variable values inline - additional scwrypts output formats: 'raw' and 'logfmt' (alongside pretty and json) - normalize.boolean utility for consistent truthy/falsey handling across ZSH-type scwrypts - utils.fzf.file-select for directory-scoped file selection prompts - automatic dependency wrappers providing default arguments, GNU coreutil resolution, and scwrypts trace on wrapped commands --- Changes ------------------------------ - log levels reorganized; success / status / reminder messages now emit at level 3, so lower verbosities will show fewer of these - environment library restructured around get-user-json as the single source of truth (replaces the previous user module and cache-output) - utility renames for consistency: user.Yn / user.yN (from utils.*) - utils.fail and utils.abort deprecated in favor of echo.error and echo.error.user-abort --- Bug Fixes ---------------------------- - CI runs now resolve config lookup-paths (.dotted.path) to their environment variable before reading, fixing false "not set" reports and invalid-export errors for lookup-path checks in CI - hardened environment type detection so array-valued configs reprint correctly after their first check - corrected exit-code capture in the cache layer (now reflects the cached command, not the downstream output filter) - scwrypt exit code now survives the logging pipeline - assorted script fixes (efs unmount file listing, postgres run-sql file discovery)
126 lines
3.2 KiB
Bash
126 lines
3.2 KiB
Bash
DEPENDENCIES+=(jo jq printf)
|
|
|
|
utils.io.print() {
|
|
local \
|
|
message \
|
|
prefix prefix_delimiter=' : ' color \
|
|
minimum_log_level ignore_minimum_log_level=false \
|
|
print_to_stderr=true \
|
|
print_to_stdout=false \
|
|
last_line_end=$'\n' \
|
|
variables=() \
|
|
;
|
|
|
|
# since this function can be used outside of scwrypts, we bump log
|
|
# level to maximum to avoid confusion of "why isn't my print
|
|
# statment working"
|
|
[[ "${SCWRYPTS_LOG_LEVEL:=${LOG_LEVEL}}" ]] \
|
|
|| local SCWRYPTS_LOG_LEVEL=4
|
|
|
|
[[ "${SCWRYPTS_OUTPUT_FORMAT}" ]] \
|
|
|| local SCWRYPTS_OUTPUT_FORMAT=pretty
|
|
|
|
local _s
|
|
while [[ "${#}" -gt 0 ]]
|
|
do
|
|
_s=1
|
|
case "${1}" in
|
|
( --prefix ) _s=2; prefix="${2}" ;;
|
|
( --prefix-delimiter ) _s=2; prefix_delimiter="${2}" ;;
|
|
( --color ) _s=2; color="${2}" ;;
|
|
( --minimum-log-level ) _s=2; minimum_log_level="${2}" ;;
|
|
( --format ) _s=2; local SCWRYPTS_OUTPUT_FORMAT="${2}" ;;
|
|
|
|
( -v ) _s=2 # appends 'name=value' to the end of the message
|
|
variables+=("${2}")
|
|
;;
|
|
|
|
( --force-print )
|
|
ignore_minimum_log_level=true
|
|
;;
|
|
|
|
( --stdout )
|
|
print_to_stdout=true
|
|
print_to_stderr=false
|
|
;;
|
|
|
|
( --no-line-end ) # only applicable to some formats (see below)
|
|
last_line_end=''
|
|
;;
|
|
|
|
( * )
|
|
[[ "${message}" ]] && message+=" ${1}" || message="${1}"
|
|
;;
|
|
esac
|
|
|
|
shift "${_s}" || { echo "ERROR : missing argument for '${1}'" >&2; return 1; }
|
|
done
|
|
|
|
: \
|
|
&& [[ "${minimum_log_level}" ]] \
|
|
&& [[ "${ignore_minimum_log_level}" =~ false ]] \
|
|
&& [[ "${SCWRYPTS_LOG_LEVEL}" -lt "${minimum_log_level}" ]] \
|
|
&& return 0
|
|
|
|
local variable
|
|
for variable in "${variables[@]}"
|
|
do
|
|
message+=$'\n'" - ${variable}=${(Pq)variable}"
|
|
done
|
|
|
|
case ${SCWRYPTS_OUTPUT_FORMAT:l} in
|
|
( raw ) message+="${last_line_end}" ;;
|
|
|
|
( pretty )
|
|
message="${color}$({
|
|
while IFS='' read -r line
|
|
do
|
|
[[ ${prefix} =~ ^[[:space:]]\+$ ]] && printf '%s' $'\n'
|
|
printf "%s" "${prefix}${prefix_delimiter}$(echo "${line}" | sed 's/^ \+//; s/ \+$//')"
|
|
prefix="$(printf '%*s' ${#prefix} '')"
|
|
done <<< "${message}"
|
|
})${last_line_end}$(utils.colors.reset)"
|
|
;;
|
|
|
|
( json )
|
|
message="$(jo \
|
|
timestamp=$(date +%s) \
|
|
runtime=${SCWRYPTS_RUNTIME_ID} \
|
|
status="$(echo "${prefix}" | sed 's/ .*//')" \
|
|
message="$(echo -n "${message}" | sed 's/^\t\+//')" \
|
|
2>/dev/null || echo "{\"error\":\"your message was too long so I encoded it\",\"messageB64\":\"$(echo "${message}" | base64 | tr -d '\n')\"}"
|
|
)"$'\n'
|
|
;;
|
|
|
|
( logfmt )
|
|
local ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
|
|
local level
|
|
case "${prefix}" in
|
|
( ERROR* ) level=error ;;
|
|
( WARNING* ) level=warn ;;
|
|
( DEBUG* ) level=debug ;;
|
|
( TRACE* ) level=trace ;;
|
|
( * ) level=info ;;
|
|
esac
|
|
|
|
local msg="${message}"
|
|
msg="${msg//\\/\\\\}"
|
|
msg="${msg//\"/\\\"}"
|
|
msg="${msg//$'\n'/\\n}"
|
|
|
|
message="ts=${ts} level=${level} runtime=${SCWRYPTS_RUNTIME_ID} msg=\"${msg}\""$'\n'
|
|
;;
|
|
|
|
( * )
|
|
echo "ERROR : unsupported format '${SCWRYPTS_OUTPUT_FORMAT}'" >&2
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
[[ "${print_to_stderr}" =~ true ]] && printf "%s" "${message}" >&2
|
|
[[ "${print_to_stdout}" =~ true ]] && printf "%s" "${message}"
|
|
|
|
return 0
|
|
}
|