sequencer - rework color handling, adding option to have color codes within pipes

sequencer - helpApi now uses less by default
This commit is contained in:
2022-11-28 14:24:25 +01:00
parent 661f2ff550
commit 915f8cbf3f

View File

@@ -72,6 +72,10 @@ set -o pipefail
_sqr_single=0 _sqr_single=0
readonly _sqr_stepMax=512 readonly _sqr_stepMax=512
_sqr_verbose=0 _sqr_verbose=0
# Part of a pipe or output to terminal
_sqr_term=0 && [ -t 1 ] && _sqr_term=1
readonly _sqr_term
_sqr_colorAlways=0
## Terminal position ## Terminal position
_sqr_savePosAlias= ;[ -t 1 ] && _sqr_savePosAlias='\033[1A\033[1C\033[s\033[1B\033[1C' _sqr_savePosAlias= ;[ -t 1 ] && _sqr_savePosAlias='\033[1A\033[1C\033[s\033[1B\033[1C'
@@ -80,23 +84,24 @@ set -o pipefail
_sqr_restorePos= ;[ -t 1 ] && _sqr_restorePos='\033[u' _sqr_restorePos= ;[ -t 1 ] && _sqr_restorePos='\033[u'
## Terminal colors ## Terminal colors
col_black= ; [ -t 1 ] && col_black='\033[0;30m' col_black() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[0;30m';}
col_darkgrey= ; [ -t 1 ] && col_darkgrey='\033[1;30m' col_darkgrey() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[1;30m';}
col_red= ; [ -t 1 ] && col_red='\033[0;31m' col_red() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[0;31m';}
col_lightred= ; [ -t 1 ] && col_lightred='\033[1;31m' col_lightred() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[1;31m';}
col_green= ; [ -t 1 ] && col_green='\033[0;32m' col_green() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[0;32m';}
col_lightgreen= ; [ -t 1 ] && col_lightgreen='\033[1;32m' col_lightgreen() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[1;32m';}
col_orange= ; [ -t 1 ] && col_orange='\033[0;33m' col_orange() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[0;33m';}
col_yellow= ; [ -t 1 ] && col_yellow='\033[1;33m' col_yellow() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[1;33m';}
col_blue= ; [ -t 1 ] && col_blue='\033[0;34m' col_blue() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[0;34m';}
col_lightblue= ; [ -t 1 ] && col_lightblue='\033[1;34m' col_lightblue() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[1;34m';}
col_purple= ; [ -t 1 ] && col_purple='\033[0;35m' col_purple() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[0;35m';}
col_lightpurple= ; [ -t 1 ] && col_lightpurple='\033[1;35m' col_lightpurple() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[1;35m';}
col_cyan= ; [ -t 1 ] && col_cyan='\033[0;36m' col_cyan() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[0;36m';}
col_lightcyan= ; [ -t 1 ] && col_lightcyan='\033[1;36m' col_lightcyan() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[1;36m';}
col_lightgray= ; [ -t 1 ] && col_lightgray='\033[0;37m' col_lightgray() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[0;37m';}
col_white= ; [ -t 1 ] && col_white='\033[1;37m' col_white() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[1;37m';}
col_off= ;[ -t 1 ] && col_off='\033[0m' # No Color ## No Color
col_off() { ((_sqr_term)) || ((_sqr_colorAlways)) && printf '%b' '\033[0m';}
} }
helpSequencer() { helpSequencer() {
@@ -105,6 +110,7 @@ Usage: ${seq_name} [OPTIONS] [STEP NUMBER(s) or ALIAS] [STEP ARGUMENTS]
[OPTIONS] [OPTIONS]
--all, -a : Run all steps regardless of continuity --all, -a : Run all steps regardless of continuity
--color : Output color codes also within pipe
--config, -c : Open sequence configuration file (also sets -qq) --config, -c : Open sequence configuration file (also sets -qq)
--dry-run, -d : Only print to console what would be done --dry-run, -d : Only print to console what would be done
! Attention - Sequence must support this ! Attention - Sequence must support this
@@ -169,19 +175,19 @@ sequencer.sh global variables:
sequencer.sh build-in functions: sequencer.sh build-in functions:
USAGE_API USAGE_API
echo -e "${col_green} root${col_off}" echo -e "$(col_green) root$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Returns true if current user is root. Returns true if current user is root.
e.g. root || echo "Not root" e.g. root || echo "Not root"
USAGE_API USAGE_API
echo -e "${col_green} running${col_off}" echo -e "$(col_green) running$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Returns true if same script already runs. Returns true if same script already runs.
e.g. running && exit 1 e.g. running && exit 1
USAGE_API USAGE_API
echo -e "${col_green} exists [OPTIONS] [ELEMENT]${col_off}" echo -e "$(col_green) exists [OPTIONS] [ELEMENT]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
[ELEMENT] [ELEMENT]
: either a variable- or a funtion name (-f) : either a variable- or a funtion name (-f)
@@ -189,37 +195,37 @@ USAGE_API
-f : a function -f : a function
-- : end of options -- : end of options
USAGE_API USAGE_API
echo -e "${col_green} quiet${col_off}" echo -e "$(col_green) quiet$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Returns true if seq runs non-interactive (-q|-qq). Returns true if seq runs non-interactive (-q|-qq).
USAGE_API USAGE_API
echo -e "${col_green} silent${col_off}" echo -e "$(col_green) silent$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Returns true if seq runs interactive. Returns true if seq runs interactive.
USAGE_API USAGE_API
echo -e "${col_green} dry${col_off}" echo -e "$(col_green) dry$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Returns true if seq runs in dry-run mode (-d) Returns true if seq runs in dry-run mode (-d)
USAGE_API USAGE_API
echo -e "${col_green} verbose${col_off}" echo -e "$(col_green) verbose$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Returns true if seq runs in verbose mode (-v) Returns true if seq runs in verbose mode (-v)
USAGE_API USAGE_API
echo -e "${col_green} contextHelp${col_off}" echo -e "$(col_green) contextHelp$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Returns true if current output is only for help purposes. Returns true if current output is only for help purposes.
USAGE_API USAGE_API
echo -e "${col_green} contextExe${col_off}" echo -e "$(col_green) contextExe$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Returns true if current output is in execution mode. Returns true if current output is in execution mode.
USAGE_API USAGE_API
echo -e "${col_green} confirm [OPTIONS] [QUESTION]${col_off}" echo -e "$(col_green) confirm [OPTIONS] [QUESTION]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Default (empty character) = no Default (empty character) = no
Invalid character trigger the default Invalid character trigger the default
@@ -230,7 +236,7 @@ USAGE_API
-- : end of options -- : end of options
USAGE_API USAGE_API
echo -e "${col_green} ask [OPTION] [QUESTION] [DEFAULT]${col_off}" echo -e "$(col_green) ask [OPTION] [QUESTION] [DEFAULT]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Will ask for input even if quiet, when [DEFAULT] is empty Will ask for input even if quiet, when [DEFAULT] is empty
[OPTION] [OPTION]
@@ -242,14 +248,14 @@ USAGE_API
-- : End of options -- : End of options
USAGE_API USAGE_API
echo -e "${col_green} exe [COMMANDLINE]${col_off}" echo -e "$(col_green) exe [COMMANDLINE]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Execute command line without pipes or redirects (>,<,|). Execute command line without pipes or redirects (>,<,|).
Supporting: dry-run (-d): only print command without execution Supporting: dry-run (-d): only print command without execution
verbose (-v): print command before execution verbose (-v): print command before execution
USAGE_API USAGE_API
echo -e "${col_green} exep \"[COMMAND STRING(s)]\"${col_off}" echo -e "$(col_green) exep \"[COMMAND STRING(s)]\"$(col_off)"
cat <<USAGE_API cat <<USAGE_API
See exe, but support for pipes or redirects. See exe, but support for pipes or redirects.
e.g.: exep echo hello world \\> \\'out put.log\\' e.g.: exep echo hello world \\> \\'out put.log\\'
@@ -261,13 +267,13 @@ USAGE_API
- All apostrophes need to be esacped since the command line is given as string. - All apostrophes need to be esacped since the command line is given as string.
USAGE_API USAGE_API
echo -e "${col_green} escpath <PATH>${col_off}" echo -e "$(col_green) escpath <PATH>$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Escaping non-printable characters with the proposed POSIX $'' syntax Escaping non-printable characters with the proposed POSIX $'' syntax
e.g. \$(escpath /my own/ho me/path) = $(escpath /my own/ho me/path) e.g. \$(escpath /my own/ho me/path) = $(escpath /my own/ho me/path)
USAGE_API USAGE_API
echo -e "${col_green} initSeqConfig [OPTION] <NAME> [TEMPLATE]${col_off}" echo -e "$(col_green) initSeqConfig [OPTION] <NAME> [TEMPLATE]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Create a configuration file in ${seq_configRoot}/ and source it if already existent. Create a configuration file in ${seq_configRoot}/ and source it if already existent.
[OPTION] [OPTION]
@@ -282,7 +288,7 @@ USAGE_API
3 : No configuration created 3 : No configuration created
USAGE_API USAGE_API
echo -e "${col_green} addConf <OPTIONS> [SOURCE TYPE] <SOURCE> <DESTINATION FILE>${col_off}" echo -e "$(col_green) addConf <OPTIONS> [SOURCE TYPE] <SOURCE> <DESTINATION FILE>$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Trying to write or append text or a file (<SOURCE>) to a destination file. Trying to write or append text or a file (<SOURCE>) to a destination file.
If the CONFIGFILE exists, a backup (name_%Y%m%d-%H%M%S.bck) is saved at the same location. If the CONFIGFILE exists, a backup (name_%Y%m%d-%H%M%S.bck) is saved at the same location.
@@ -301,13 +307,13 @@ USAGE_API
Target file to be created or modified. Target file to be created or modified.
USAGE_API USAGE_API
echo -e "${col_green} step <STEP NUMBER OR ALIAS>${col_off}" echo -e "$(col_green) step <STEP NUMBER OR ALIAS>$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Executes a single step also by alias. Useful if step numbers get reorganized. Executes a single step also by alias. Useful if step numbers get reorganized.
dry-run is not applied in this function! The executed step is responsible. dry-run is not applied in this function! The executed step is responsible.
USAGE_API USAGE_API
echo -e "${col_green} color [FOREGROUND COLOR] [BACKGROUND COLOR]${col_off}" echo -e "$(col_green) color [FOREGROUND COLOR] [BACKGROUND COLOR]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Set output color permanently until reset. Set output color permanently until reset.
No argument or unknown foreground color restores shell default (reset). No argument or unknown foreground color restores shell default (reset).
@@ -315,7 +321,7 @@ USAGE_API
[COLOR]: black, red, green, yellow, blue, magenta, cyan, white [COLOR]: black, red, green, yellow, blue, magenta, cyan, white
USAGE_API USAGE_API
echo -e "${col_green} info|warning|error|debug [OPTIONS] [STRING]${col_off}" echo -e "$(col_green) info|warning|error|debug [OPTIONS] [STRING]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Output [STRING] (can be multiline) to stdout according to log level. Output [STRING] (can be multiline) to stdout according to log level.
[OPTIONS] [OPTIONS]
@@ -325,13 +331,13 @@ USAGE_API
-n : No newline -n : No newline
USAGE_API USAGE_API
echo -e "${col_green} echoinfo [...]${col_off}" echo -e "$(col_green) echoinfo [...]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
echo additional correctly indented line to step info echo additional correctly indented line to step info
[...] : all parameter are forwared to echo [...] : all parameter are forwared to echo
USAGE_API USAGE_API
echo -e "${col_green} echoinfoArgs [...]${col_off}" echo -e "$(col_green) echoinfoArgs [...]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
echo argument description after step number or alias. echo argument description after step number or alias.
This must be called first in the step info function. This must be called first in the step info function.
@@ -339,24 +345,24 @@ USAGE_API
[...] : no parameter are forwared to echo [...] : no parameter are forwared to echo
USAGE_API USAGE_API
echo -e "${col_green} endIfEmpty <VARIABLENAME> [DESCRIPTION]${col_off}" echo -e "$(col_green) endIfEmpty <VARIABLENAME> [DESCRIPTION]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
exit 666 if variable is empty exit 6 if variable is empty
<VARIABLENAME> : Name without \$ <VARIABLENAME> : Name without \$
[DESCRIPTION] : Additional text for error output [DESCRIPTION] : Additional text for error output
USAGE_API USAGE_API
echo -e "${col_green} saveReturn [ERRORCODE]${col_off}" echo -e "$(col_green) saveReturn [ERRORCODE]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Save ERRORCODE if it is != 0 for later use with endReturn Save ERRORCODE if it is != 0 for later use with endReturn
USAGE_API USAGE_API
echo -e "${col_green} getReturn${col_off}" echo -e "$(col_green) getReturn$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Return last saved error code Return last saved error code
USAGE_API USAGE_API
echo -e "${col_green} endReturn [OPTIONS] [MESSAGE]${col_off}" echo -e "$(col_green) endReturn [OPTIONS] [MESSAGE]$(col_off)"
cat <<USAGE_API cat <<USAGE_API
Notifys user that there was an error (previously saved by saveReturn, Notifys user that there was an error (previously saved by saveReturn,
or -o [ERRORCODE]) and asks to continue or end the sequence. or -o [ERRORCODE]) and asks to continue or end the sequence.
@@ -397,7 +403,8 @@ USAGE_API
local appendText= local appendText=
local direct=0 # no prefix and timestamp local direct=0 # no prefix and timestamp
local newline='\n' local newline='\n'
local col_end="${col_off}" local col_end=
col_end="$(col_off)"
local outp='/dev/stdout' local outp='/dev/stdout'
local log_level="${1:-}" local log_level="${1:-}"
@@ -413,16 +420,11 @@ USAGE_API
while getopts "aden" arg; do while getopts "aden" arg; do
case "${arg}" in case "${arg}" in
a) a) appendText=1 ;;
appendText=1 ;; d) direct=1 ;;
d) e) outp='/dev/stderr' ;;
direct=1 ;; n) newline='' ;;
e) *) ;;
outp='/dev/stderr' ;;
n)
newline='' ;;
*)
;;
esac esac
done done
shift "$((OPTIND-1))"; OPTIND=1 shift "$((OPTIND-1))"; OPTIND=1
@@ -460,12 +462,12 @@ USAGE_API
sqr::debugContinue sqr::debugContinue
} }
fatal () { sqr::log "stop" "${col_red}" "${@}"; exit 1; } fatal () { sqr::log "stop" "$(col_red)" "${@}"; exit 1; }
die () { sqr::log "end" "" "${@}"; exit 1; } die () { sqr::log "end" "" "${@}"; exit 1; }
error () { [[ "${LOG_LEVEL:-0}" -ge ${log_error} ]] && sqr::log "e" "${col_red}" "${@}"; true; } error () { [[ "${LOG_LEVEL:-0}" -ge ${log_error} ]] && sqr::log "e" "$(col_red)" "${@}"; true; }
warning () { [[ "${LOG_LEVEL:-0}" -ge ${log_warning} ]] && sqr::log "w" "${col_orange}" "${@}"; true; } warning () { [[ "${LOG_LEVEL:-0}" -ge ${log_warning} ]] && sqr::log "w" "$(col_orange)" "${@}"; true; }
info () { [[ "${LOG_LEVEL:-0}" -ge ${log_info} ]] && sqr::log "i" "" "${@}"; true; } info () { [[ "${LOG_LEVEL:-0}" -ge ${log_info} ]] && sqr::log "i" "" "${@}"; true; }
debug () { [[ "${LOG_LEVEL:-0}" -ge ${log_debug} ]] && sqr::log "dbug" "${col_lightpurple}" "${@}"; true; } debug () { [[ "${LOG_LEVEL:-0}" -ge ${log_debug} ]] && sqr::log "dbug" "$(col_lightpurple)" "${@}"; true; }
# internal print(s) same loglevel as error # internal print(s) same loglevel as error
# shellcheck disable=SC2059 # don't use variables in format # shellcheck disable=SC2059 # don't use variables in format
@@ -1112,7 +1114,7 @@ displayHelp() {
# Display alias if exists # Display alias if exists
if exists -f "step_${i}_alias" ; then if exists -f "step_${i}_alias" ; then
echo -en " = ${col_orange}$("step_${i}_alias")${col_off}${_sqr_savePosAlias}" echo -en " = $(col_orange)$("step_${i}_alias")$(col_off)${_sqr_savePosAlias}"
# Newline only if step info() exists # Newline only if step info() exists
exists -f "step_${i}_info" && printf '\n%s' "$_sqr_indentHelp" exists -f "step_${i}_info" && printf '\n%s' "$_sqr_indentHelp"
else else
@@ -1345,7 +1347,7 @@ execute() {
exists -f "step_${1}_alias" && stepAlias=$("step_${1}_alias") exists -f "step_${1}_alias" && stepAlias=$("step_${1}_alias")
printf '\n [%3d] ' "${1}" printf '\n [%3d] ' "${1}"
if [ -n "${stepAlias}" ]; then if [ -n "${stepAlias}" ]; then
echo -en "${col_orange}${stepAlias}${col_off}${_sqr_savePosAlias}" echo -en "$(col_orange)${stepAlias}$(col_off)${_sqr_savePosAlias}"
# Only add newline if step info() available # Only add newline if step info() available
exists -f "step_${1}_info" && printf '\n%s' "${_sqr_indentExe}" exists -f "step_${1}_info" && printf '\n%s' "${_sqr_indentExe}"
else else
@@ -1511,6 +1513,9 @@ sqr::main() {
--config|-c) # open sequence configuration file --config|-c) # open sequence configuration file
_seq_configEdit=1 _seq_configEdit=1
shift ;; shift ;;
--color) # Output color codes within pipe
_sqr_colorAlways=1
shift ;;
--debug) --debug)
_sqr_debug="1" _sqr_debug="1"
shift ;; shift ;;
@@ -1518,14 +1523,13 @@ sqr::main() {
_sqr_dry=1 _sqr_dry=1
shift ;; shift ;;
--help|-h) # show only help --help|-h) # show only help
displayHelp 1 "${2:-}" local _sqr_optHelp=1
exit 0 ;; shift ;;
--helpapi|-ha) #show build-in functions --helpapi|-ha) #show build-in functions
helpApi local _sqr_optHelpapi=1
exit 0;; shift ;;
--liststeps|-ls) --liststeps|-ls)
shift listSteps "${2:-}"
listSteps "${1:-}"
exit 0 ;; exit 0 ;;
--profile|-p) # seq profile name --profile|-p) # seq profile name
sqr_args+=" $1 ${2:-}" sqr_args+=" $1 ${2:-}"
@@ -1565,6 +1569,9 @@ sqr::main() {
esac esac
done done
((${_sqr_optHelp:-})) && displayHelp 1 "${1:-}" && exit 0
((${_sqr_optHelpapi:-})) && helpApi | less -R && exit 0
# debug mode # debug mode
if [[ "${_sqr_debug:-}" = "1" ]]; then if [[ "${_sqr_debug:-}" = "1" ]]; then
set -o xtrace set -o xtrace
@@ -1576,14 +1583,14 @@ sqr::main() {
# Don't show help if only configuration should be edited # Don't show help if only configuration should be edited
[ ${_seq_configEdit} -ne 0 ] && [ -z "${1:-}" ] && LOG_LEVEL=1 [ ${_seq_configEdit} -ne 0 ] && [ -z "${1:-}" ] && LOG_LEVEL=1
if [ -z "${1:-}" ] && [ $quickStartOne -eq 0 ] ; then if [ -z "${1:-}" ] && (( ! quickStartOne )) ; then
if ! quiet && [[ ${LOG_LEVEL} -ge $log_info ]] ; then if ! quiet && [[ ${LOG_LEVEL} -ge $log_info ]] ; then
# Empty -> show help # Empty -> show help
displayHelp displayHelp
fi fi
# Assume starting at one for interactive mode # Assume starting at one for interactive mode
toStart=( "1" ) toStart=( "1" )
elif [ $quickStartOne -ne 0 ] ; then elif (( quickStartOne )) ; then
emptyCall=0 emptyCall=0
toStart=( "1" ) toStart=( "1" )
seq_args=( "$@" ) seq_args=( "$@" )
@@ -1635,7 +1642,7 @@ sqr::main() {
else else
error "No configuration file available" error "No configuration file available"
fi fi
[ ${emptyCall} -ne 0 ] && exit 0 (( emptyCall )) && exit 0
fi fi
if checkStep "${toStart[0]}" >/dev/null 2>&1 ; then if checkStep "${toStart[0]}" >/dev/null 2>&1 ; then
@@ -1658,7 +1665,7 @@ sqr::main() {
fi fi
# check if more than one step is given and select execution mode # check if more than one step is given and select execution mode
if [ ${_sqr_single} -ne 0 ] ; then if (( _sqr_single )) ; then
selection "${toStart[0]}" selection "${toStart[0]}"
elif [ "${#toStart[@]}" -gt "1" ]; then elif [ "${#toStart[@]}" -gt "1" ]; then
selection "${toStart[@]}" selection "${toStart[@]}"