Refactor column output

- Use single function _columns_
- Use single variable for indentation
- add options for bold, underline, reverse for left column
This commit is contained in:
Nathaniel Landau
2022-04-28 23:30:10 -04:00
parent 8719caa6bd
commit b655220616
4 changed files with 99 additions and 134 deletions

View File

@@ -125,12 +125,11 @@ You can copy any complete function from the Utilities and place it into your scr
## alerts.bash ## 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 - -**`_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 - **`_alert_`** Performs alerting functions including writing to a log file and printing to screen
- **`_centerOutput_`** Prints text in the center of the terminal window - **`_centerOutput_`** Prints text in the center of the terminal window
- **`_setColors_`** Sets color constants for alerting (**Note:** Colors default to a dark theme.) - **`_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. 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.

View File

@@ -296,33 +296,18 @@ _usage_() {
This is a script template. Edit this description to print help to users. This is a script template. Edit this description to print help to users.
${bold}${underline}Options:${reset} ${bold}${underline}Options:${reset}
$(_usageCommands_ \ $(_columns_ -b -- '-h, --help' "Display this help and exit" 2)
"-h, --help" \ $(_columns_ -b -- "--loglevel [LEVEL]" "One of: FATAL, ERROR (default), WARN, INFO, NOTICE, DEBUG, ALL, OFF" 2)
"Display this help and exit") $(_columns_ -b -- "--logfile [FILE]" "Full PATH to logfile. (Default is '\${HOME}/logs/$(basename "$0").log')" 2)
$(_usageCommands_ \ $(_columns_ -b -- "-n, --dryrun" "Non-destructive. Makes no permanent changes." 2)
"--loglevel [LEVEL]" \ $(_columns_ -b -- "-q, --quiet" "Quiet (no output)" 2)
"One of: FATAL, ERROR (default), WARN, INFO, NOTICE, DEBUG, ALL, OFF") $(_columns_ -b -- "-v, --verbose" "Output more information. (Items echoed to 'verbose')" 2)
$(_usageCommands_ \ $(_columns_ -b -- "--force" "Skip all user interaction. Implied 'Yes' to all actions." 2)
"--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.")
${bold}${underline}Example Usage:${reset} ${bold}${underline}Example Usage:${reset}
${gray}# Run the script and specify log level and log file.${reset} ${gray}# Run the script and specify log level and log file.${reset}
$(basename "$0") -vn --logfile "/path/to/file.log" --loglevel 'WARN' $(basename "$0") -vn --logfile "/path/to/file.log" --loglevel 'WARN'
USAGE_TEXT USAGE_TEXT
} }

View File

@@ -600,47 +600,70 @@ _parseOptions_() {
fi fi
} }
_usageCommands_() { _columns_() {
# DESC: # DESC:
# Used to add commands to the _usage_ function. Prints commands and their descriptions # Prints a two column output from a key/value pair.
# in two aligned columns. Uses an option 4 character tab count to indent the commands. # Optionally pass a number of 2 space tabs to indent the output.
# ARGS: # ARGS:
# $1 (required): Key name (left column text) # $1 (required): Key name (Left column text)
# $2 (required): Long value (right column text. Wraps around if too long) # $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) # $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: # OUTS:
# stdout: Prints the output in columns # stdout: Prints the output in columns
# NOTE: # NOTE:
# Long text or ANSI colors in the first column may create display issues # Long text or ANSI colors in the first column may create display issues
# USAGE: # USAGE:
# _usageCommands_ "Key" "Long value text" [tab level] # _columns_ "Key" "Long value text" [tab level]
[[ $# -lt 2 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" [[ $# -lt 2 ]] && fatal "Missing required argument to ${FUNCNAME[0]}"
local _key="$1" local opt
local _value="$2" local OPTIND=1
local _tabSize=4 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 _tabLevel="${3-}"
local _tabSize=2
local _line local _line
local _rightIndent local _rightIndent
local _leftIndent local _leftIndent
if [[ -z ${3-} ]]; then if [[ -z ${3-} ]]; then
_tabLevel=1 _tabLevel=0
fi fi
_leftIndent="$((_tabLevel * _tabSize))" _leftIndent="$((_tabLevel * _tabSize))"
local _leftColumnWidth="$((32 - _leftIndent))" local _leftColumnWidth="$((30 + _leftIndent))"
if [ "$(tput cols)" -gt 180 ]; then if [ "$(tput cols)" -gt 180 ]; then
_rightIndent=80 _rightIndent=110
elif [ "$(tput cols)" -gt 160 ]; then elif [ "$(tput cols)" -gt 160 ]; then
_rightIndent=60 _rightIndent=90
elif [ "$(tput cols)" -gt 130 ]; then elif [ "$(tput cols)" -gt 130 ]; then
_rightIndent=30 _rightIndent=60
elif [ "$(tput cols)" -gt 120 ]; then elif [ "$(tput cols)" -gt 120 ]; then
_rightIndent=20 _rightIndent=50
elif [ "$(tput cols)" -gt 110 ]; then 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 _rightIndent=10
else else
_rightIndent=0 _rightIndent=0
@@ -655,7 +678,7 @@ _usageCommands_() {
else else
_key=" " _key=" "
fi 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}")" done <<<"$(fold -w${_rightWrapLength} -s <<<"${_value}")"
} }
@@ -667,33 +690,18 @@ _usage_() {
This is a script template. Edit this description to print help to users. This is a script template. Edit this description to print help to users.
${bold}${underline}Options:${reset} ${bold}${underline}Options:${reset}
$(_usageCommands_ \ $(_columns_ -b -- '-h, --help' "Display this help and exit" 2)
"-h, --help" \ $(_columns_ -b -- "--loglevel [LEVEL]" "One of: FATAL, ERROR (default), WARN, INFO, NOTICE, DEBUG, ALL, OFF" 2)
"Display this help and exit") $(_columns_ -b -- "--logfile [FILE]" "Full PATH to logfile. (Default is '\${HOME}/logs/$(basename "$0").log')" 2)
$(_usageCommands_ \ $(_columns_ -b -- "-n, --dryrun" "Non-destructive. Makes no permanent changes." 2)
"--loglevel [LEVEL]" \ $(_columns_ -b -- "-q, --quiet" "Quiet (no output)" 2)
"One of: FATAL, ERROR (default), WARN, INFO, NOTICE, DEBUG, ALL, OFF") $(_columns_ -b -- "-v, --verbose" "Output more information. (Items echoed to 'verbose')" 2)
$(_usageCommands_ \ $(_columns_ -b -- "--force" "Skip all user interaction. Implied 'Yes' to all actions." 2)
"--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.")
${bold}${underline}Example Usage:${reset} ${bold}${underline}Example Usage:${reset}
${gray}# Run the script and specify log level and log file.${reset} ${gray}# Run the script and specify log level and log file.${reset}
$(basename "$0") -vn --logfile "/path/to/file.log" --loglevel 'WARN' $(basename "$0") -vn --logfile "/path/to/file.log" --loglevel 'WARN'
USAGE_TEXT USAGE_TEXT
} }

View File

@@ -262,56 +262,6 @@ _centerOutput_() {
printf "%s\n" "${_out}" 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_() ( _clearLine_() (
# DESC: # DESC:
# Clears output in the terminal on the specified line number. # Clears output in the terminal on the specified line number.
@@ -335,47 +285,70 @@ _clearLine_() (
fi fi
) )
_usageCommands_() { _columns_() {
# DESC: # DESC:
# Used to add commands to the _usage_ function. Prints commands and their descriptions # Prints a two column output from a key/value pair.
# in two aligned columns. Uses an option 4 character tab count to indent the commands. # Optionally pass a number of 2 space tabs to indent the output.
# ARGS: # ARGS:
# $1 (required): Key name (left column text) # $1 (required): Key name (Left column text)
# $2 (required): Long value (right column text. Wraps around if too long) # $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) # $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: # OUTS:
# stdout: Prints the output in columns # stdout: Prints the output in columns
# NOTE: # NOTE:
# Long text or ANSI colors in the first column may create display issues # Long text or ANSI colors in the first column may create display issues
# USAGE: # USAGE:
# _usageCommands_ "Key" "Long value text" [tab level] # _columns_ "Key" "Long value text" [tab level]
[[ $# -lt 2 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" [[ $# -lt 2 ]] && fatal "Missing required argument to ${FUNCNAME[0]}"
local _key="$1" local opt
local _value="$2" local OPTIND=1
local _tabSize=4 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 _tabLevel="${3-}"
local _tabSize=2
local _line local _line
local _rightIndent local _rightIndent
local _leftIndent local _leftIndent
if [[ -z ${3-} ]]; then if [[ -z ${3-} ]]; then
_tabLevel=1 _tabLevel=0
fi fi
_leftIndent="$((_tabLevel * _tabSize))" _leftIndent="$((_tabLevel * _tabSize))"
local _leftColumnWidth="$((32 - _leftIndent))" local _leftColumnWidth="$((30 + _leftIndent))"
if [ "$(tput cols)" -gt 180 ]; then if [ "$(tput cols)" -gt 180 ]; then
_rightIndent=80 _rightIndent=110
elif [ "$(tput cols)" -gt 160 ]; then elif [ "$(tput cols)" -gt 160 ]; then
_rightIndent=60 _rightIndent=90
elif [ "$(tput cols)" -gt 130 ]; then elif [ "$(tput cols)" -gt 130 ]; then
_rightIndent=30 _rightIndent=60
elif [ "$(tput cols)" -gt 120 ]; then elif [ "$(tput cols)" -gt 120 ]; then
_rightIndent=20 _rightIndent=50
elif [ "$(tput cols)" -gt 110 ]; then 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 _rightIndent=10
else else
_rightIndent=0 _rightIndent=0
@@ -390,6 +363,6 @@ _usageCommands_() {
else else
_key=" " _key=" "
fi 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}")" done <<<"$(fold -w${_rightWrapLength} -s <<<"${_value}")"
} }