@@ -20,6 +20,104 @@ if [ "$0" != "${BASH_SOURCE[0]}" ] && [ "$BAKE_INTERNAL_CAN_SOURCE" != 'yes' ];
2020 return 1
2121fi
2222
23+ # @description Prints `$1` formatted as an error and the stacktrace to standard error,
24+ # then exits with code 1
25+ # @arg $1 string Text to print
26+ bake.die () {
27+ if [ -n " $1 " ]; then
28+ __bake_error " $1 . Exiting"
29+ else
30+ __bake_error ' Exiting'
31+ fi
32+ __bake_print_big ' <- ERROR'
33+
34+ __bake_print_stacktrace
35+
36+ exit 1
37+ }
38+
39+ # @description Prints `$1` formatted as a warning to standard error
40+ # @arg $1 string Text to print
41+ bake.warn () {
42+ if __bake_is_color; then
43+ printf " \033[1;33m%s:\033[0m %s\n" ' Warn' " $1 "
44+ else
45+ printf ' %s: %s\n' ' Warn' " $1 "
46+ fi
47+ } >&2
48+
49+ # @description Prints `$1` formatted as information to standard output
50+ # @arg $1 string Text to print
51+ bake.info () {
52+ if __bake_is_color; then
53+ printf " \033[0;34m%s:\033[0m %s\n" ' Info' " $1 "
54+ else
55+ printf ' %s: %s\n' ' Info' " $1 "
56+ fi
57+ }
58+
59+ # @description Dies if any of the supplied variables are empty. Deprecated in favor of 'bake.assert_not_empty'
60+ # @arg $@ string Names of variables to check for emptiness
61+ # @see bake.assert_not_empty
62+ bake.assert_nonempty () {
63+ __bake_internal_warn " Function 'bake.assert_nonempty' is deprecated. Please use 'bake.assert_not_empty' instead"
64+ bake.assert_not_empty " $@ "
65+ }
66+
67+ # @description Dies if any of the supplied variables are empty
68+ # @arg $@ string Names of variables to check for emptiness
69+ bake.assert_not_empty () {
70+ local variable_name=
71+ for variable_name; do
72+ local -n ____variable=" $variable_name "
73+
74+ if [ -z " $____variable " ]; then
75+ bake.die " Failed because variable '$variable_name ' is empty"
76+ fi
77+ done ; unset -v variable_name
78+ }
79+
80+ # @description Dies if a command cannot be found
81+ # @arg $1 string Command name to test for existence
82+ bake.assert_cmd () {
83+ local cmd=$1
84+
85+ if [ -z " $cmd " ]; then
86+ bake.die " Argument must not be empty"
87+ fi
88+
89+ if ! command -v " $cmd " & > /dev/null; then
90+ bake.die " Failed to find command '$cmd '. Please install it before continuing"
91+ fi
92+ }
93+
94+ # @description Change the behavior of Bake
95+ # @arg $1 string Name of config property to change
96+ # @arg $2 string New value of config property
97+ bake.cfg () {
98+ local cfg=$1
99+ local value=$2
100+
101+ case $cfg in
102+ stacktrace)
103+ case $value in
104+ yes|no) __bake_cfg_stacktrace=$value ;;
105+ * ) __bake_internal_die2 " Config property '$cfg ' accepts only either 'yes' or 'no'" ;;
106+ esac
107+ ;;
108+ pedantic-task-cd)
109+ case $value in
110+ yes) trap ' __bake_trap_debug' ' DEBUG' ;;
111+ no) trap - ' DEBUG' ;;
112+ * ) __bake_internal_die2 " Config property '$cfg ' accepts only either 'yes' or 'no'" ;;
113+ esac
114+ ;;
115+ * )
116+ __bake_internal_die2 " No config property matched '$cfg '"
117+ ;;
118+ esac
119+ }
120+
23121# @description Prints stacktrace
24122# @internal
25123__bake_print_stacktrace () {
@@ -31,25 +129,39 @@ __bake_print_stacktrace() {
31129 fi
32130
33131 local i=
34- for (( i= 0 ;i< ${# FUNCNAME[@]} - 1 ;i ++ )) ; do
35- local __bash_source=${BASH_SOURCE[$i]} ; __bash_source=" ${__bash_source##*/ } "
132+ for (( i= 0 ; i< ${# FUNCNAME[@]} - 1 ; ++ i )) ; do
133+ local __bash_source=" ${BASH_SOURCE[$i]} " ; __bash_source=${__bash_source##*/ }
36134 printf ' %s\n' " in ${FUNCNAME[$i]} ($__bash_source :${BASH_LINENO[$i-1]} )"
37135 done ; unset -v i __bash_source
38136 fi
39137} >&2
40138
41- # @description Function 'trap' calls on 'ERR'
139+ # @description Function that is executed when the 'ERR' event is trapped
42140# @internal
43141__bake_trap_err () {
44142 local error_code=$?
45143
46144 __bake_print_big " <- ERROR"
47- __bake_internal_error " Your ' Bakefile.sh' did not exit successfully"
145+ __bake_internal_error " Your Bakefile did not exit successfully (exit code $error_code ) "
48146 __bake_print_stacktrace
49147
50148 exit $error_code
51149} >&2
52150
151+ __global_bake_trap_debug_current_function=
152+ __bake_trap_debug () {
153+ local current_function=" ${FUNCNAME[1]} "
154+
155+ if [[ $current_function != " $__global_bake_trap_debug_current_function " \
156+ && $current_function == task.* ]]; then
157+ if ! cd " $BAKE_ROOT " ; then
158+ __bake_internal_die " Failed to cd to \$ BAKE_ROOT"
159+ fi
160+ fi
161+
162+ __global_bake_trap_debug_current_function=$current_function
163+ } >&2
164+
53165# @description Test whether color should be outputed
54166# @exitcode 0 if should print color
55167# @exitcode 1 if should not print color
@@ -62,6 +174,25 @@ __bake_is_color() {
62174 fi
63175}
64176
177+ # @description Calls `__bake_internal_error` and terminates with code 1
178+ # @arg $1 string Text to print
179+ # @internal
180+ __bake_internal_die () {
181+ __bake_internal_error " $1 . Exiting"
182+ exit 1
183+ }
184+
185+ # @description Calls `__bake_internal_error` and terminates with code 1. Before
186+ # doing so, it closes with "<- ERROR" big text
187+ # @arg $1 string Text to print
188+ # @internal
189+ __bake_internal_die2 () {
190+ __bake_print_big ' <- ERROR'
191+
192+ __bake_internal_error " $1 . Exiting"
193+ exit 1
194+ }
195+
65196# @description Prints `$1` formatted as an internal Bake error to standard error
66197# @arg $1 Text to print
67198# @internal
@@ -84,15 +215,8 @@ __bake_internal_warn() {
84215 fi
85216} >&2
86217
87- # @description Calls `__bake_internal_error` and terminates with code 1
88- # @arg $1 string Text to print
89- # @internal
90- __bake_internal_die () {
91- __bake_internal_error " $1 . Exiting"
92- exit 1
93- }
94-
95- # @description Prints `$1` formatted as an error to standard error
218+ # @description Prints `$1` formatted as an error to standard error. This is not called because
219+ # I do not wish to surface a public 'bake.error' function. All errors should halt execution
96220# @arg $1 string Text to print
97221# @internal
98222__bake_error () {
@@ -103,7 +227,7 @@ __bake_error() {
103227 fi
104228} >&2
105229
106- # @description Nicely prints all 'Basalt .sh' tasks to standard output
230+ # @description Nicely prints all 'Bakefile .sh' tasks to standard output
107231# @internal
108232__bake_print_tasks () {
109233 # shellcheck disable=SC1007,SC2034
@@ -144,7 +268,11 @@ __bake_print_big() {
144268 fi
145269} >&2
146270
147- __bake_set_vars () {
271+ # @description Parses the arguments. This also includes setting the the 'BAKE_ROOT'
272+ # and 'BAKE_FILE' variables
273+ # @set REPLY Number of times to shift
274+ # @internal
275+ __bake_parse_args () {
148276 unset REPLY; REPLY=
149277 local -i total_shifts=0
150278
@@ -153,7 +281,7 @@ __bake_set_vars() {
153281 -f)
154282 BAKE_FILE=$2
155283 if [ -z " $BAKE_FILE " ]; then
156- __bake_internal_die ' File must not be empty. Exiting '
284+ __bake_internal_die " A value was not specified for for flag '-f "
157285 fi
158286 (( total_shifts += 2 ))
159287 if ! shift 2; then
@@ -164,7 +292,7 @@ __bake_set_vars() {
164292 __bake_internal_die " Specified file '$BAKE_FILE ' does not exist"
165293 fi
166294 if [ ! -f " $BAKE_FILE " ]; then
167- __bake_internal_die " Specified path '$BAKE_FILE ' is not actually a file"
295+ __bake_internal_die " Specified file '$BAKE_FILE ' is not actually a file"
168296 fi
169297 ;;
170298 -h)
@@ -195,7 +323,7 @@ __bake_set_vars() {
195323
196324 printf ' %s' " $PWD "
197325 ) ; then
198- __bake_internal_die " Could not find 'Bakefile.sh'"
326+ __bake_internal_die " Failed to find 'Bakefile.sh'"
199327 fi
200328 BAKE_FILE=" $BAKE_ROOT /Bakefile.sh"
201329 fi
@@ -211,106 +339,27 @@ __bake_set_vars() {
211339 REPLY=$total_shifts
212340}
213341
214- # @description Prints `$1` formatted as an error and the stacktrace to standard error,
215- # then exits with code 1
216- # @arg $1 string Text to print
217- bake.die () {
218- if [ -n " $1 " ]; then
219- __bake_error " $1 . Exiting"
220- else
221- __bake_error ' Exiting'
222- fi
223- __bake_print_big ' <- ERROR'
224-
225- __bake_print_stacktrace
226-
227- exit 1
228- }
229-
230- # @description Prints `$1` formatted as a warning to standard error
231- # @arg $1 string Text to print
232- bake.warn () {
233- if __bake_is_color; then
234- printf " \033[1;33m%s:\033[0m %s\n" ' Warn' " $1 "
235- else
236- printf ' %s: %s\n' ' Warn' " $1 "
237- fi
238- } >&2
239-
240- # @description Prints `$1` formatted as information to standard output
241- # @arg $1 string Text to print
242- bake.info () {
243- if __bake_is_color; then
244- printf " \033[0;34m%s:\033[0m %s\n" ' Info' " $1 "
245- else
246- printf ' %s: %s\n' ' Info' " $1 "
247- fi
248- }
249-
250- # @description Dies if any of the supplied variables are empty. Deprecated in favor of 'bake.assert_not_empty'
251- # @arg $@ string Variable names to print
252- # @see bake.assert_not_empty
253- bake.assert_nonempty () {
254- __bake_internal_warn " Function 'bake.assert_nonempty' is deprecated. Please use 'bake.assert_not_empty' instead"
255- bake.assert_not_empty
256- }
257-
258- # @description Dies if any of the supplied variables are empty
259- # @arg $@ string Variable names to print
260- bake.assert_not_empty () {
261- local variable_name=
262- for variable_name; do
263- local -n variable=" $variable_name "
264-
265- if [ -z " $variable " ]; then
266- bake.die " Failed because variable '$variable_name ' is empty"
267- fi
268- done ; unset -v variable_name
269- }
270-
271- # @description Dies if a command cannot be found
272- # @arg $1 string Command to test for existence
273- bake.assert_cmd () {
274- local cmd=$1
275-
276- if [ -z " $cmd " ]; then
277- bake.die " Argument must not be empty"
278- fi
279-
280- if ! command -v " $cmd " & > /dev/null; then
281- bake.die " Failed to find command '$cmd '. Please install it before continuing"
282- fi
283- }
284-
285- # @description Edit configuration that affects the behavior of Bake
286- # @arg $1 string Configuration option to change
287- # @arg $2 string Value of configuration property
288- bake.cfg () {
289- local cfg=$1
290- local value=$2
291-
292- case $cfg in
293- stacktrace)
294- __bake_cfg_stacktrace=$value
295- esac
296- }
297-
342+ # @description Main function
343+ # @internal
298344__bake_main () {
299- __bake_cfg_stacktrace=' yes '
345+ __bake_cfg_stacktrace=' no '
300346
301- set -Eeo pipefail
347+ set -ETeo pipefail
302348 shopt -s dotglob extglob globasciiranges globstar lastpipe shift_verbose
303- export LANG=' C' LC_CTYPE=' C' LC_NUMERIC=' C' LC_TIME=' C' LC_COLLATE=' C' LC_MONETARY=' C' LC_MESSAGES=' C' \
304- LC_PAPER=' C' LC_NAME=' C' LC_ADDRESS=' C' LC_TELEPHONE=' C' LC_MEASUREMENT=' C' LC_IDENTIFICATION=' C' LC_ALL=' C'
349+ export LANG=' C' LC_CTYPE=' C' LC_NUMERIC=' C' LC_TIME=' C' LC_COLLATE=' C' \
350+ LC_MONETARY=' C' LC_MESSAGES=' C' LC_PAPER=' C' LC_NAME=' C' LC_ADDRESS=' C' \
351+ LC_TELEPHONE=' C' LC_MEASUREMENT=' C' LC_IDENTIFICATION=' C' LC_ALL=' C'
305352 trap ' __bake_trap_err' ' ERR'
353+ bake.cfg pedantic-task-cd ' no'
306354
307355 # Set `BAKE_{ROOT,FILE}`
308356 BAKE_ROOT=; BAKE_FILE=
309- __bake_set_vars " $@ "
357+ __bake_parse_args " $@ "
310358 if ! shift " $REPLY " ; then
311359 __bake_internal_die ' Failed to shift'
312360 fi
313361
362+ # shellcheck disable=SC1007
314363 local __bake_key= __bake_value=
315364 local __bake_arg=
316365 for __bake_arg; do case $__bake_arg in
0 commit comments