Skip to content

Commit 7f30861

Browse files
committed
feat: Add color for print functions
This also removes the behavior of printing only (ex. "Error") if no message was passed. (now it prints "Error: ") This changes the print so that `_fn()` prints show parenthesis of the functions
1 parent 0858b6f commit 7f30861

File tree

4 files changed

+108
-30
lines changed

4 files changed

+108
-30
lines changed

bake

+66-15
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# Learn more about it [on GitHub](https://github.com/hyperupcall/bake)
1717

1818
if [ "$0" != "${BASH_SOURCE[0]}" ] && [ "$BAKE_INTERNAL_CAN_SOURCE" != 'yes' ]; then
19-
printf '%s\n' "Error: This file should not be sourced" >&2
19+
printf '%s\n' 'Error: This file should not be sourced' >&2
2020
return 1
2121
fi
2222

@@ -91,12 +91,12 @@ bake.assert_cmd() {
9191
fi
9292
}
9393

94-
# @description Change the behavior of Bake
94+
# @description Change the behavior of Bake. See [guide.md](./docs/guide.md) for details
9595
# @arg $1 string Name of config property to change
9696
# @arg $2 string New value of config property
9797
bake.cfg() {
98-
local cfg=$1
99-
local value=$2
98+
local cfg="$1"
99+
local value="$2"
100100

101101
case $cfg in
102102
stacktrace)
@@ -112,6 +112,12 @@ bake.cfg() {
112112
*) __bake_internal_die2 "Config property '$cfg' accepts only either 'yes' or 'no'" ;;
113113
esac
114114
;;
115+
big-print)
116+
case $value in
117+
yes|no) ;;
118+
*) __bake_internal_die2 "Config property '$cfg' accepts only either 'yes' or 'no'" ;;
119+
esac
120+
;;
115121
*)
116122
__bake_internal_die2 "No config property matched '$cfg'"
117123
;;
@@ -230,15 +236,27 @@ __bake_error() {
230236
# @description Nicely prints all 'Bakefile.sh' tasks to standard output
231237
# @internal
232238
__bake_print_tasks() {
239+
printf '%s\n' 'Tasks:'
240+
local str=
241+
233242
# shellcheck disable=SC1007,SC2034
234243
local regex="^(([[:space:]]*function[[:space:]]*)?task\.(.*?)\(\)).*"
235244
local line=
236-
printf '%s\n' 'Tasks:'
237245
while IFS= read -r line || [ -n "$line" ]; do
238246
if [[ "$line" =~ $regex ]]; then
239-
printf '%s\n' " -> ${BASH_REMATCH[3]}"
247+
str+=" -> ${BASH_REMATCH[3]}"$'\n'
240248
fi
241249
done < "$BAKE_FILE"; unset -v line
250+
251+
if [ -z "$str" ]; then
252+
if __bake_is_color; then
253+
str=$' \033[3mNo tasks\033[0m\n'
254+
else
255+
str=$' No tasks\n'
256+
fi
257+
fi
258+
259+
printf '%s' "$str"
242260
} >&2
243261

244262
# @description Prints text that takes up the whole terminal width
@@ -247,13 +265,21 @@ __bake_print_tasks() {
247265
__bake_print_big() {
248266
local print_text="$1"
249267

268+
if [ "$__bake_cfg_big_print" = 'no' ]; then
269+
return
270+
fi
271+
250272
# shellcheck disable=SC1007
251273
local _stty_height= _stty_width=
252274
read -r _stty_height _stty_width < <(
253-
if command -v stty &>/dev/null; then
275+
if stty size &>/dev/null; then
254276
stty size
255277
else
256-
printf '%s\n' '20 80'
278+
if [ -n "$COLUMNS" ]; then
279+
printf '%s\n' "20 $COLUMNS"
280+
else
281+
printf '%s\n' '20 80'
282+
fi
257283
fi
258284
)
259285

@@ -276,6 +302,7 @@ __bake_parse_args() {
276302
unset REPLY; REPLY=
277303
local -i total_shifts=0
278304

305+
# FIXME: bug for when passing -v to child task argument
279306
local __bake_arg=
280307
for arg; do case $arg in
281308
-f)
@@ -295,6 +322,10 @@ __bake_parse_args() {
295322
__bake_internal_die "Specified file '$BAKE_FILE' is not actually a file"
296323
fi
297324
;;
325+
-v)
326+
local bake_version='1.8.2'
327+
printf '%s\n' "Version: $bake_version"
328+
;;
298329
-h)
299330
local flag_help='yes'
300331
if ! shift; then
@@ -311,7 +342,7 @@ __bake_parse_args() {
311342
BAKE_FILE="$BAKE_ROOT/${BAKE_FILE##*/}"
312343
else
313344
if ! BAKE_ROOT=$(
314-
while [ ! -f 'Bakefile.sh' ] && [ "$PWD" != / ]; do
345+
while [ ! -f './Bakefile.sh' ] && [ "$PWD" != / ]; do
315346
if ! cd ..; then
316347
exit 1
317348
fi
@@ -329,8 +360,8 @@ __bake_parse_args() {
329360
fi
330361

331362
if [ "$flag_help" = 'yes' ]; then
332-
cat <<-EOF
333-
Usage: bake [-h] [-f <Bakefile>] [var=value ...] <task> [args ...]
363+
cat <<-"EOF"
364+
Usage: bake [-h|-v] [-f <Bakefile>] [var=value ...] <task> [args ...]
334365
EOF
335366
__bake_print_tasks
336367
exit
@@ -343,22 +374,27 @@ __bake_parse_args() {
343374
# @internal
344375
__bake_main() {
345376
__bake_cfg_stacktrace='no'
377+
__bake_cfg_big_print='yes'
346378

379+
# Environment boilerplate
347380
set -ETeo pipefail
348381
shopt -s dotglob extglob globasciiranges globstar lastpipe shift_verbose
349-
export LANG='C' LC_CTYPE='C' LC_NUMERIC='C' LC_TIME='C' LC_COLLATE='C' LC_MONETARY='C' \
350-
LC_MESSAGES='C' LC_PAPER='C' LC_NAME='C' LC_ADDRESS='C' LC_TELEPHONE='C' \
351-
LC_MEASUREMENT='C' LC_IDENTIFICATION='C' LC_ALL='C'
382+
export LANG='C' LC_CTYPE='C' LC_NUMERIC='C' LC_TIME='C' LC_COLLATE='C' \
383+
LC_MONETARY='C' LC_MESSAGES='C' LC_PAPER='C' LC_NAME='C' LC_ADDRESS='C' \
384+
LC_TELEPHONE='C' LC_MEASUREMENT='C' LC_IDENTIFICATION='C' LC_ALL='C'
352385
trap '__bake_trap_err' 'ERR'
386+
trap ':' 'INT' # Ensure Ctrl-C ends up printing <- ERROR ==== etc.
353387
bake.cfg pedantic-task-cd 'no'
354388

389+
# Parse arguments
355390
# Set `BAKE_{ROOT,FILE}`
356391
BAKE_ROOT=; BAKE_FILE=
357392
__bake_parse_args "$@"
358393
if ! shift "$REPLY"; then
359394
__bake_internal_die 'Failed to shift'
360395
fi
361396

397+
# Set variables à la Make
362398
# shellcheck disable=SC1007
363399
local __bake_key= __bake_value=
364400
local __bake_arg=
@@ -376,8 +412,8 @@ __bake_main() {
376412
;;
377413
*) break
378414
esac done; unset -v __bake_arg
379-
# Note: Don't unset '__bake_variable' or none of the variables will stay set
380415
unset -v __bake_key __bake_value
416+
unset -vn __bake_variable
381417

382418
local __bake_task="$1"
383419
if [ -z "$__bake_task" ]; then
@@ -397,6 +433,21 @@ __bake_main() {
397433
__bake_task= source "$BAKE_FILE"
398434

399435
if declare -f task."$__bake_task" >/dev/null 2>&1; then
436+
local line=
437+
local shouldTestNextLine='no'
438+
while IFS= read -r line; do
439+
if [ "$shouldTestNextLine" = 'yes' ]; then
440+
if [[ $line == *'bake.cfg'*big-print*no* ]]; then
441+
__bake_cfg_big_print='no'
442+
fi
443+
shouldTestNextLine='no'
444+
fi
445+
446+
if [[ $line == @(task."$__bake_task"|init)*'('*')'*'{' ]]; then
447+
shouldTestNextLine='yes'
448+
fi
449+
done < "$BAKE_FILE"; unset -v line shouldTestNextLine
450+
400451
__bake_print_big "-> RUNNING TASK '$__bake_task'"
401452
if declare -f init >/dev/null 2>&1; then
402453
init "$__bake_task"

pkg/src/public/bash-core.sh

+18-6
Original file line numberDiff line numberDiff line change
@@ -308,23 +308,23 @@ core.print_stacktrace() {
308308
core.print_error_fn() {
309309
local msg="$1"
310310

311-
printf '%s\n' "Error: ${FUNCNAME[1]}${msg:+": "}$msg" >&2
311+
core.print_error "${FUNCNAME[1]}()${msg:+": "}$msg"
312312
}
313313

314314
# @description Print a warning message to standard error
315315
# @arg $1 string message
316316
core.print_warn_fn() {
317317
local msg="$1"
318318

319-
printf '%s\n' "Warn: ${FUNCNAME[1]}${msg:+": "}$msg" >&2
319+
core.print_warn "${FUNCNAME[1]}()${msg:+": "}$msg"
320320
}
321321

322322
# @description Print an informative message to standard output
323323
# @arg $1 string message
324324
core.print_info_fn() {
325325
local msg="$1"
326326

327-
printf '%s\n' "Info: ${FUNCNAME[1]}${msg:+": "}$msg"
327+
core.print_info "${FUNCNAME[1]}()${msg:+": "}$msg"
328328
}
329329

330330
# @description Print a error message to standard error and die
@@ -339,23 +339,35 @@ core.print_die() {
339339
core.print_error() {
340340
local msg="$1"
341341

342-
printf '%s\n' "Error${msg:+": "}$msg" >&2
342+
if core.private.should_print_color 2; then
343+
printf "\033[1;31m%s:\033[0m %s\n" 'Error' "$msg" >&2
344+
else
345+
printf "%s: %s\n" 'Error' "$msg" >&2
346+
fi
343347
}
344348

345349
# @description Print a warning message to standard error
346350
# @arg $1 string message
347351
core.print_warn() {
348352
local msg="$1"
349353

350-
printf '%s\n' "Warn${msg:+": "}$msg" >&2
354+
if core.private.should_print_color 2; then
355+
printf "\033[1;33m%s:\033[0m %s\n" 'Warn' "$msg" >&2
356+
else
357+
printf "%s: %s\n" 'Warn' "$msg" >&2
358+
fi
351359
}
352360

353361
# @description Print an informative message to standard output
354362
# @arg $1 string message
355363
core.print_info() {
356364
local msg="$1"
357365

358-
printf '%s\n' "Info${msg:+": "}$msg"
366+
if core.private.should_print_color 1; then
367+
printf "\033[1;32m%s:\033[0m %s\n" 'Info' "$msg" >&2
368+
else
369+
printf "%s: %s\n" 'Info' "$msg" >&2
370+
fi
359371
}
360372

361373
# @description (DEPRECATED). Determine if color should be printed. Note that this doesn't

pkg/src/util/util.sh

+15
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,23 @@ core.private.util.trap_handler_common() {
3333
}
3434

3535
# @description Prints the current error stored
36+
# @internal
3637
core.private.util.err_print() {
3738
printf '%s\n' 'Error found:'
3839
printf '%s\n' " ERRCODE: $ERRCODE" >&2
3940
printf '%s\n' " ERR: $ERR" >&2
41+
}
42+
43+
core.private.should_print_color() {
44+
local fd="$1"
45+
46+
if [[ ${NO_COLOR+x} || "$TERM" = 'dumb' ]]; then
47+
return 1
48+
fi
49+
50+
if [ -t "$fd" ]; then
51+
return 0
52+
fi
53+
54+
return 1
4055
}

tests/print.bats

+9-9
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,37 @@ infofn() { "$@"; }
1212
@test "core.print_error_fn works" {
1313
run errorfn core.print_error_fn
1414
assert_success
15-
assert_output 'Error: errorfn'
15+
assert_output 'Error: errorfn()'
1616

1717
run errorfn core.print_error_fn 'Something'
1818
assert_success
19-
assert_output 'Error: errorfn: Something'
19+
assert_output 'Error: errorfn(): Something'
2020
}
2121

2222
@test "core.print_warn_fn works" {
2323
run warnfn core.print_warn_fn
2424
assert_success
25-
assert_output 'Warn: warnfn'
25+
assert_output 'Warn: warnfn()'
2626

2727
run warnfn core.print_warn_fn 'Something'
2828
assert_success
29-
assert_output 'Warn: warnfn: Something'
29+
assert_output 'Warn: warnfn(): Something'
3030
}
3131

3232
@test "core.print_info_fn works" {
3333
run infofn core.print_info_fn
3434
assert_success
35-
assert_output 'Info: infofn'
35+
assert_output 'Info: infofn()'
3636

3737
run infofn core.print_info_fn 'Something'
3838
assert_success
39-
assert_output 'Info: infofn: Something'
39+
assert_output 'Info: infofn(): Something'
4040
}
4141

4242
@test "core.print_error works" {
4343
run errorfn core.print_error
4444
assert_success
45-
assert_output 'Error'
45+
assert_output 'Error: '
4646

4747
run errorfn core.print_error 'Something'
4848
assert_success
@@ -52,7 +52,7 @@ infofn() { "$@"; }
5252
@test "core.print_warn works" {
5353
run warnfn core.print_warn
5454
assert_success
55-
assert_output 'Warn'
55+
assert_output 'Warn: '
5656

5757
run warnfn core.print_warn 'Something'
5858
assert_success
@@ -62,7 +62,7 @@ infofn() { "$@"; }
6262
@test "core.print_info works" {
6363
run infofn core.print_info
6464
assert_success
65-
assert_output 'Info'
65+
assert_output 'Info: '
6666

6767
run infofn core.print_info 'Something'
6868
assert_success

0 commit comments

Comments
 (0)