From b6552206167899aaac8ecc0a4a7c32228986f25a Mon Sep 17 00:00:00 2001 From: Nathaniel Landau Date: Thu, 28 Apr 2022 23:30:10 -0400 Subject: [PATCH] Refactor column output - Use single function _columns_ - Use single variable for indentation - add options for bold, underline, reverse for left column --- README.md | 3 +- template.sh | 33 ++++--------- template_standalone.sh | 90 ++++++++++++++++++---------------- utilities/alerts.bash | 107 +++++++++++++++-------------------------- 4 files changed, 99 insertions(+), 134 deletions(-) diff --git a/README.md b/README.md index 64a1569..a81c70a 100644 --- a/README.md +++ b/README.md @@ -125,12 +125,11 @@ You can copy any complete function from the Utilities and place it into your scr ## alerts.bash -- **`_columnizeOutput_`** Creates a column output for key/value pairs with line wrapping for the right column (value) +- **`_columns_`** Prints a two column output from a key/value pair - -**`_printFuncStack_`** Prints the function stack in use. Used for debugging, and error reporting - **`_alert_`** Performs alerting functions including writing to a log file and printing to screen - **`_centerOutput_`** Prints text in the center of the terminal window - **`_setColors_`** Sets color constants for alerting (**Note:** Colors default to a dark theme.) -- **`_usageCommands_`** Used to add commands to the `_usage_` function. Prints commands and their descriptions in two aligned columns. Uses an option 4 character tab count to indent the commands. Basic alerting, logging, and setting color functions (included in `scriptTemplate.sh` by default). Print messages to stdout and to a user specified logfile using the following functions. diff --git a/template.sh b/template.sh index 7e1e8dd..21df6fd 100755 --- a/template.sh +++ b/template.sh @@ -296,33 +296,18 @@ _usage_() { This is a script template. Edit this description to print help to users. ${bold}${underline}Options:${reset} -$(_usageCommands_ \ - "-h, --help" \ - "Display this help and exit") -$(_usageCommands_ \ - "--loglevel [LEVEL]" \ - "One of: FATAL, ERROR (default), WARN, INFO, NOTICE, DEBUG, ALL, OFF") -$(_usageCommands_ \ - "--logfile [FILE]" \ - "Full PATH to logfile. (Default is '${HOME}/logs/$(basename "$0").log')") -$(_usageCommands_ \ - "-n, --dryrun" \ - "Non-destructive. Makes no permanent changes." \ - 2) -$(_usageCommands_ \ - "-q, --quiet" \ - "Quiet (no output)") -$(_usageCommands_ \ - "-v, --verbose" \ - "Output more information. (Items echoed to 'verbose')") -$(_usageCommands_ \ - "--force" \ - "Skip all user interaction. Implied 'Yes' to all actions.") +$(_columns_ -b -- '-h, --help' "Display this help and exit" 2) +$(_columns_ -b -- "--loglevel [LEVEL]" "One of: FATAL, ERROR (default), WARN, INFO, NOTICE, DEBUG, ALL, OFF" 2) +$(_columns_ -b -- "--logfile [FILE]" "Full PATH to logfile. (Default is '\${HOME}/logs/$(basename "$0").log')" 2) +$(_columns_ -b -- "-n, --dryrun" "Non-destructive. Makes no permanent changes." 2) +$(_columns_ -b -- "-q, --quiet" "Quiet (no output)" 2) +$(_columns_ -b -- "-v, --verbose" "Output more information. (Items echoed to 'verbose')" 2) +$(_columns_ -b -- "--force" "Skip all user interaction. Implied 'Yes' to all actions." 2) ${bold}${underline}Example Usage:${reset} - ${gray}# Run the script and specify log level and log file.${reset} - $(basename "$0") -vn --logfile "/path/to/file.log" --loglevel 'WARN' + ${gray}# Run the script and specify log level and log file.${reset} + $(basename "$0") -vn --logfile "/path/to/file.log" --loglevel 'WARN' USAGE_TEXT } diff --git a/template_standalone.sh b/template_standalone.sh index afbdb22..c1b8d2e 100755 --- a/template_standalone.sh +++ b/template_standalone.sh @@ -600,47 +600,70 @@ _parseOptions_() { fi } -_usageCommands_() { +_columns_() { # DESC: - # Used to add commands to the _usage_ function. Prints commands and their descriptions - # in two aligned columns. Uses an option 4 character tab count to indent the commands. + # Prints a two column output from a key/value pair. + # Optionally pass a number of 2 space tabs to indent the output. # ARGS: - # $1 (required): Key name (left column text) - # $2 (required): Long value (right column text. Wraps around if too long) - # $3 (optional): Number of 4 character tabs to indent the command (default 1) + # $1 (required): Key name (Left column text) + # $2 (required): Long value (Right column text. Wraps around if too long) + # $3 (optional): Number of 2 character tabs to indent the command (default 1) + # OPTS: + # -b Bold the left column + # -u Underline the left column + # -r Reverse background and foreground colors # OUTS: # stdout: Prints the output in columns # NOTE: # Long text or ANSI colors in the first column may create display issues # USAGE: - # _usageCommands_ "Key" "Long value text" [tab level] + # _columns_ "Key" "Long value text" [tab level] [[ $# -lt 2 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" - local _key="$1" - local _value="$2" - local _tabSize=4 + local opt + local OPTIND=1 + local _style="" + while getopts ":bBuUrR" opt; do + case ${opt} in + b | B) _style="${_style}${bold}" ;; + u | U) _style="${_style}${underline}" ;; + r | R) _style="${_style}${reverse}" ;; + *) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;; + esac + done + shift $((OPTIND - 1)) + + local _key="${1}" + local _value="${2}" local _tabLevel="${3-}" + local _tabSize=2 local _line local _rightIndent local _leftIndent if [[ -z ${3-} ]]; then - _tabLevel=1 + _tabLevel=0 fi _leftIndent="$((_tabLevel * _tabSize))" - local _leftColumnWidth="$((32 - _leftIndent))" + local _leftColumnWidth="$((30 + _leftIndent))" if [ "$(tput cols)" -gt 180 ]; then - _rightIndent=80 + _rightIndent=110 elif [ "$(tput cols)" -gt 160 ]; then - _rightIndent=60 + _rightIndent=90 elif [ "$(tput cols)" -gt 130 ]; then - _rightIndent=30 + _rightIndent=60 elif [ "$(tput cols)" -gt 120 ]; then - _rightIndent=20 + _rightIndent=50 elif [ "$(tput cols)" -gt 110 ]; then + _rightIndent=40 + elif [ "$(tput cols)" -gt 100 ]; then + _rightIndent=30 + elif [ "$(tput cols)" -gt 90 ]; then + _rightIndent=20 + elif [ "$(tput cols)" -gt 80 ]; then _rightIndent=10 else _rightIndent=0 @@ -655,7 +678,7 @@ _usageCommands_() { else _key=" " fi - printf "%-${_leftIndent}s${bold}${white}%-${_leftColumnWidth}b${reset} %b\n" "" "${_key}${reset}" "${_line}" + printf "%-${_leftIndent}s${_style}%-${_leftColumnWidth}b${reset} %b\n" "" "${_key}${reset}" "${_line}" done <<<"$(fold -w${_rightWrapLength} -s <<<"${_value}")" } @@ -667,33 +690,18 @@ _usage_() { This is a script template. Edit this description to print help to users. ${bold}${underline}Options:${reset} -$(_usageCommands_ \ - "-h, --help" \ - "Display this help and exit") -$(_usageCommands_ \ - "--loglevel [LEVEL]" \ - "One of: FATAL, ERROR (default), WARN, INFO, NOTICE, DEBUG, ALL, OFF") -$(_usageCommands_ \ - "--logfile [FILE]" \ - "Full PATH to logfile. (Default is '${HOME}/logs/$(basename "$0").log')") -$(_usageCommands_ \ - "-n, --dryrun" \ - "Non-destructive. Makes no permanent changes." \ - 2) -$(_usageCommands_ \ - "-q, --quiet" \ - "Quiet (no output)") -$(_usageCommands_ \ - "-v, --verbose" \ - "Output more information. (Items echoed to 'verbose')") -$(_usageCommands_ \ - "--force" \ - "Skip all user interaction. Implied 'Yes' to all actions.") +$(_columns_ -b -- '-h, --help' "Display this help and exit" 2) +$(_columns_ -b -- "--loglevel [LEVEL]" "One of: FATAL, ERROR (default), WARN, INFO, NOTICE, DEBUG, ALL, OFF" 2) +$(_columns_ -b -- "--logfile [FILE]" "Full PATH to logfile. (Default is '\${HOME}/logs/$(basename "$0").log')" 2) +$(_columns_ -b -- "-n, --dryrun" "Non-destructive. Makes no permanent changes." 2) +$(_columns_ -b -- "-q, --quiet" "Quiet (no output)" 2) +$(_columns_ -b -- "-v, --verbose" "Output more information. (Items echoed to 'verbose')" 2) +$(_columns_ -b -- "--force" "Skip all user interaction. Implied 'Yes' to all actions." 2) ${bold}${underline}Example Usage:${reset} - ${gray}# Run the script and specify log level and log file.${reset} - $(basename "$0") -vn --logfile "/path/to/file.log" --loglevel 'WARN' + ${gray}# Run the script and specify log level and log file.${reset} + $(basename "$0") -vn --logfile "/path/to/file.log" --loglevel 'WARN' USAGE_TEXT } diff --git a/utilities/alerts.bash b/utilities/alerts.bash index 7ba8de9..b96fb0b 100644 --- a/utilities/alerts.bash +++ b/utilities/alerts.bash @@ -262,56 +262,6 @@ _centerOutput_() { printf "%s\n" "${_out}" } -_columnizeOutput_() { - # DESC: - # Creates a column output for key/value pairs with line wrapping for the right column (value). Attempts to wrap at a sane line length (~100 cols) on larger screens. - # ARGS: - # $1 (required): Left padding of table - # $2 (required): Width of first column - # $3 (required): Key name (left column text) - # $4 (required): Long value (right column text. Wraps around if too long) - # OUTS: - # stdout: Prints the columnized output - # NOTE: - # Long text or ANSI colors in the first column may create display issues - # USAGE: - # _columnizeOutput_ 0 30 "Key" "Long value text" - - [[ $# -lt 4 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" - - local _leftIndent=$1 - local _leftColumn=$2 - local _key="$3" - local _value="$4" - local _line - local _rightIndent - - if [ "$(tput cols)" -gt 180 ]; then - _rightIndent=80 - elif [ "$(tput cols)" -gt 160 ]; then - _rightIndent=60 - elif [ "$(tput cols)" -gt 130 ]; then - _rightIndent=30 - elif [ "$(tput cols)" -gt 120 ]; then - _rightIndent=20 - elif [ "$(tput cols)" -gt 110 ]; then - _rightIndent=10 - else - _rightIndent=0 - fi - local _rightWrapLength=$(($(tput cols) - _leftColumn - _leftIndent - _rightIndent)) - - local _first_line=0 - while read -r _line; do - if [[ ${_first_line} -eq 0 ]]; then - _first_line=1 - else - _key=" " - fi - printf "%-${_leftIndent}s%-${_leftColumn}b %b\n" "" "${_key}" "${_line}" - done <<<"$(fold -w${_rightWrapLength} -s <<<"${_value}")" -} - _clearLine_() ( # DESC: # Clears output in the terminal on the specified line number. @@ -335,47 +285,70 @@ _clearLine_() ( fi ) -_usageCommands_() { +_columns_() { # DESC: - # Used to add commands to the _usage_ function. Prints commands and their descriptions - # in two aligned columns. Uses an option 4 character tab count to indent the commands. + # Prints a two column output from a key/value pair. + # Optionally pass a number of 2 space tabs to indent the output. # ARGS: - # $1 (required): Key name (left column text) - # $2 (required): Long value (right column text. Wraps around if too long) - # $3 (optional): Number of 4 character tabs to indent the command (default 1) + # $1 (required): Key name (Left column text) + # $2 (required): Long value (Right column text. Wraps around if too long) + # $3 (optional): Number of 2 character tabs to indent the command (default 1) + # OPTS: + # -b Bold the left column + # -u Underline the left column + # -r Reverse background and foreground colors # OUTS: # stdout: Prints the output in columns # NOTE: # Long text or ANSI colors in the first column may create display issues # USAGE: - # _usageCommands_ "Key" "Long value text" [tab level] + # _columns_ "Key" "Long value text" [tab level] [[ $# -lt 2 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" - local _key="$1" - local _value="$2" - local _tabSize=4 + local opt + local OPTIND=1 + local _style="" + while getopts ":bBuUrR" opt; do + case ${opt} in + b | B) _style="${_style}${bold}" ;; + u | U) _style="${_style}${underline}" ;; + r | R) _style="${_style}${reverse}" ;; + *) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;; + esac + done + shift $((OPTIND - 1)) + + local _key="${1}" + local _value="${2}" local _tabLevel="${3-}" + local _tabSize=2 local _line local _rightIndent local _leftIndent if [[ -z ${3-} ]]; then - _tabLevel=1 + _tabLevel=0 fi _leftIndent="$((_tabLevel * _tabSize))" - local _leftColumnWidth="$((32 - _leftIndent))" + local _leftColumnWidth="$((30 + _leftIndent))" if [ "$(tput cols)" -gt 180 ]; then - _rightIndent=80 + _rightIndent=110 elif [ "$(tput cols)" -gt 160 ]; then - _rightIndent=60 + _rightIndent=90 elif [ "$(tput cols)" -gt 130 ]; then - _rightIndent=30 + _rightIndent=60 elif [ "$(tput cols)" -gt 120 ]; then - _rightIndent=20 + _rightIndent=50 elif [ "$(tput cols)" -gt 110 ]; then + _rightIndent=40 + elif [ "$(tput cols)" -gt 100 ]; then + _rightIndent=30 + elif [ "$(tput cols)" -gt 90 ]; then + _rightIndent=20 + elif [ "$(tput cols)" -gt 80 ]; then _rightIndent=10 else _rightIndent=0 @@ -390,6 +363,6 @@ _usageCommands_() { else _key=" " fi - printf "%-${_leftIndent}s${bold}${white}%-${_leftColumnWidth}b${reset} %b\n" "" "${_key}${reset}" "${_line}" + printf "%-${_leftIndent}s${_style}%-${_leftColumnWidth}b${reset} %b\n" "" "${_key}${reset}" "${_line}" done <<<"$(fold -w${_rightWrapLength} -s <<<"${_value}")" }