Skip to content

Commit 422fa01

Browse files
release: 11.0.0
1 parent 3fe0e0f commit 422fa01

File tree

1 file changed

+71
-56
lines changed

1 file changed

+71
-56
lines changed

libbash

Lines changed: 71 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
#! /usr/bin/env bash
22

3-
# libbash 10.0.0 - a collection of useful functions for your Bash scripts
3+
# libbash 11.0.0 - a collection of useful functions for your Bash scripts
44
#
55
# Copyright (C) Georg Lauterbach
66
# GitHub: https://github.com/georglauterbach/libbash
77
#
8-
# Underscored functions are not unset when libbash has been loaded
9-
# successfully. They are required by other functions in libbash.
8+
# ---
9+
#
10+
# Upon successful loading of libbash, all functions of all loaded modules
11+
# become available and you MAY use them.
12+
#
13+
# Certain modules require other functions or variables (e.g., for logging
14+
# or error handling) that do not belong to a module directly. Such
15+
# functions are prefixed with `libbash__` and variables with `LIBBASH__`,
16+
# and you MAY use them, but you MUST NOT change them.
17+
#
18+
# Finally, there are functions and variables that do not belong to modules
19+
# and that are prefixed with `__libbash__` (and `__LIBBASH__` respectively).
20+
# You MUST NOT change or use these functions and variables.
1021

1122
# cSpell: ignore Georg Lauterbach
1223

@@ -35,7 +46,7 @@ function libbash__main() {
3546
LIBBASH__DIRECTORY=$(realpath -eL "$(dirname "${BASH_SOURCE[0]}")")
3647
LIBBASH__EXIT_IN_INTERACTIVE_MODE=${LIBBASH__EXIT_IN_INTERACTIVE_MODE:-false}
3748
LIBBASH__LOADED_MODULES=()
38-
LIBBASH__VERSION=10.0.0
49+
LIBBASH__VERSION=11.0.0
3950

4051
# ! export all variables here first, even if not
4152
# ! all modules are sourced to satisfy shellcheck
@@ -109,13 +120,14 @@ function libbash__finish() {
109120
unset LIBBASH__DIRECTORY
110121
unset LIBBASH__EXIT_IN_INTERACTIVE_MODE
111122
unset LIBBASH__LOADED_MODULES
123+
unset LIBBASH__LOG_IS_LOADED
112124
unset LIBBASH__VERSION
113125

114126
unset -f libbash__debug
115127
unset -f libbash__show_call_stack
116128

117129
unset -f __libbash__show_error
118-
unset -f __libbash__exit_checked
130+
unset -f libbash__exit_checked
119131
fi
120132

121133
unset -f libbash__main
@@ -132,7 +144,7 @@ function libbash__finish() {
132144
#
133145
# Shows some debug information that `libbash` has collected.
134146
function libbash__debug() {
135-
if ! ${__LIBBASH__LOG_IS_LOADED:-false}; then
147+
if ! ${LIBBASH__LOG_IS_LOADED:-false}; then
136148
__libbash__show_error "Debug functionality requires the log module to be loaded and 'LOG_LEVEL' set to 'debug' or 'trace'"
137149
return 1
138150
fi
@@ -167,26 +179,16 @@ function libbash__show_call_stack() {
167179
}
168180
export -f libbash__show_call_stack
169181

170-
# ### Show an Error
171-
#
172-
# Indicates an error has happened in `libbash`. Used to display
173-
# errors even when the log module is not (or has not yet been)
174-
# loaded.
175-
function __libbash__show_error() {
176-
printf "%s \e[91mERROR\e[0m %s: %s\n" \
177-
"$(date +"%Y-%m-%dT%H:%M:%S.%6N%:z" || :)" "${SCRIPT:-$(basename "${0}")}" "${*}" >&2
178-
}
179-
export -f __libbash__show_error
180-
181182
# ### Exit With Conditions
182183
#
183-
# This function will exit when not running interactively or when
184-
# 'LIBBASH__EXIT_IN_INTERACTIVE_MODE' is set to 'true'.
184+
# This function will call `exit` when not running interactively
185+
# or when 'LIBBASH__EXIT_IN_INTERACTIVE_MODE' is set to 'true'.
186+
# Otherwise, it calls `return`.
185187
#
186188
# #### Arguments
187189
#
188190
# $1 :: the return code (optional, default=1)
189-
function __libbash__exit_checked() {
191+
function libbash__exit_checked() {
190192
local CODE=${1:-1}
191193
local METHOD='return'
192194

@@ -197,11 +199,22 @@ function __libbash__exit_checked() {
197199
if [[ ${CODE} =~ ^[0-9]$ ]]; then
198200
"${METHOD}" "${CODE}"
199201
else
200-
__libbash__show_error "Supplied non-number code ('${CODE}') to __libbash__exit_checked"
202+
__libbash__show_error "Supplied non-number code ('${CODE}') to libbash__exit_checked"
201203
"${METHOD}" 1
202204
fi
203205
}
204-
export -f __libbash__exit_checked
206+
export -f libbash__exit_checked
207+
208+
# ### Show an Error
209+
#
210+
# Indicates an error has happened in `libbash`. Used to display
211+
# errors even when the log module is not (or has not yet been)
212+
# loaded.
213+
function __libbash__show_error() {
214+
printf "%s \e[91mERROR\e[0m %s: %s\n" \
215+
"$(date +"%Y-%m-%dT%H:%M:%S.%6N%:z" || :)" "${SCRIPT:-$(basename "${0}")}" "${*}" >&2
216+
}
217+
export -f __libbash__show_error
205218

206219
# Load the 'cri' module
207220
function libbash__load_module_cri() {
@@ -229,51 +242,55 @@ function libbash__load_module_log() {
229242
export LIBBASH__LOG_COLOR_WARN='\e[93m'
230243
export LIBBASH__LOG_COLOR_ERROR='\e[91m'
231244

232-
export __LIBBASH__LOG_IS_LOADED=true
245+
export LIBBASH__LOG_IS_LOADED=true
246+
247+
# ### The Actual Logger
248+
#
249+
# This function is used by `log` to print the messages.
250+
function __libbash__log_generic() {
251+
local LEVEL=${1:?libbash bug: log level message format must be provided to __libbash__log_generic}
252+
local COLOR="LIBBASH__LOG_COLOR_${LEVEL^^}"
253+
shift 1
254+
255+
# shellcheck disable=SC2059
256+
printf "%s ${!COLOR}%-5s${LIBBASH__LOG_COLOR_RESET} %s: %s\n" \
257+
"$(date +"%Y-%m-%dT%H:%M:%S.%6N%:z" || :)" "${LEVEL^^}" "${SCRIPT:-$(basename "${0}")}" "${*}"
258+
}
259+
export -f __libbash__log_generic
233260

234261
# ### The Logging Functions
235262
#
236263
# `log` uses five different log levels and behaves as you would
237264
# expect from a log function: you provide the log level as the
238265
# first argument and the message in the consecutive ones. The
239266
# default log level is 'info'. The global log level is defined
240-
# in the
267+
# in the `LOG_LEVEL` variables. The global variable `SCRIPT`
268+
# defines a prefix of the message that is being logged.
241269
#
242270
# #### Log Level
243271
#
244272
# The provided log level, as well as the environment variable
245-
# `LOG_LEVEL`, Can be one of
273+
# `LOG_LEVEL`, can be one of
246274
#
247-
# meaning - what to log
248-
# -------------------------------------------------
249-
# trace - log trace information
250-
# debug - log debug information
251-
# info - log informational output
252-
# warn - log warnings
253-
# error - log critical errors and aborts
275+
# - trace (log all messages)
276+
# - debug
277+
# - info
278+
# - warn
279+
# - error
280+
# - off (log no messages)
254281
#
255-
# where a higher level includes the level below. The
256-
# default log level is 'info' (2).
282+
# The default log level is 'info'.
257283
#
258284
# #### Return Codes
259285
#
260-
# This function is infallible. Hence, it always returns with
261-
# return code 0, even when issues appeared.
286+
# This function is infallible.
262287
#
263288
# #### Arguments
264289
#
265-
# $1 :: log level
266-
# $2 :: message (strictly speaking optional, no default / empty string)
290+
# $1 :: log level
291+
# ${@:1} :: message
267292
function log() {
268-
function __log_generic() {
269-
local LEVEL=${1:?libbash bug: log level message format must be provided to __log_generic}
270-
local COLOR="LIBBASH__LOG_COLOR_${LEVEL^^}"
271-
shift 1
272-
273-
# shellcheck disable=SC2059
274-
printf "%s ${!COLOR}%-5s${LIBBASH__LOG_COLOR_RESET} %s: %s\n" \
275-
"$(date +"%Y-%m-%dT%H:%M:%S.%6N%:z" || :)" "${LEVEL^^}" "${SCRIPT:-$(basename "${0}")}" "${*}"
276-
}
293+
[[ ${LOG_LEVEL:-} == off ]] && return 0
277294

278295
if [[ -z ${1+set} ]]; then
279296
log 'warn' "'log' called without log level"
@@ -286,13 +303,13 @@ function libbash__load_module_log() {
286303
return 0
287304
fi
288305

289-
local MESSAGE_LOG_LEVEL="${1}"
306+
local MESSAGE_LOG_LEVEL=${1}
290307
shift 1
291308

292-
# ! scoping of dictionaries beyond `source` / in the global namespace is
293-
# ! even more horrendous that normal scoping in Bash - hence, we avoid it
294-
declare -A LOG_LEVEL_MAPPING=( ["error"]="0" ["warn"]="1" ["info"]="2" ["debug"]="3" ["trace"]="4" )
295-
309+
# Scoping of dictionaries beyond `source` / in the global namespace is
310+
# even more horrendous that normal scoping in Bash - hence, we avoid it
311+
# and put the dictionary here.
312+
declare -A LOG_LEVEL_MAPPING=([off]=0 [error]=1 [warn]=2 [info]=3 [debug]=4 [trace]=5 )
296313
if [[ -z ${LOG_LEVEL_MAPPING[${LOG_LEVEL:=info}]:-} ]]; then
297314
local OLD_LOG_LEVEL=${LOG_LEVEL}
298315
export LOG_LEVEL='debug'
@@ -302,12 +319,10 @@ function libbash__load_module_log() {
302319
[[ ${LOG_LEVEL_MAPPING[${LOG_LEVEL}]} -lt ${LOG_LEVEL_MAPPING[${MESSAGE_LOG_LEVEL}]} ]] && return 0
303320

304321
if [[ ${LOG_LEVEL_MAPPING[${MESSAGE_LOG_LEVEL}]} -lt 2 ]]; then
305-
__log_generic "${MESSAGE_LOG_LEVEL}" "${*}" >&2
322+
__libbash__log_generic "${MESSAGE_LOG_LEVEL}" "${*}" >&2
306323
else
307-
__log_generic "${MESSAGE_LOG_LEVEL}" "${*}"
324+
__libbash__log_generic "${MESSAGE_LOG_LEVEL}" "${*}"
308325
fi
309-
310-
return 0
311326
}
312327
}
313328

0 commit comments

Comments
 (0)