maint(resources): improve builder_launch to allow for arbitrary parameters

Also cleans up reporting of child scripts and links the list of reserved
parameters across a few locations. Address review comments.
This commit is contained in:
Marc Durdin 2025-11-14 10:18:38 +01:00
parent 5dbc438f53
commit 0988a86fa4
3 changed files with 69 additions and 66 deletions

View file

@ -1045,15 +1045,17 @@ options, and timing status through as parameters. This should be used rather
than calling the build script directly, to avoid multiple builds of
dependencies.
Do not use builder standard options such as `--deps` or `--debug`.
### Parameters
* 1: `script` path to script, relative to root of repo
* 2: `action` action(s)+target(s) for the child script to run, comma separated, at least one
* 2+: `parameters` action(s), target(s), parameters for the child script to run
### Example
```bash
builder_launch /core/build.sh configure,build:wasm
builder_launch core/build.sh configure,build:wasm --no-tests
```
--------------------------------------------------------------------------------

View file

@ -303,12 +303,12 @@ function builder_echo_start_end_tests() {
TEAMCITY_GIT_PATH=""
_builder_debug_internal=false
_builder_is_child=0
expected=""
expected="$(builder_echo heading "description")"
result=$(builder_echo start "foo" "description")
if [[ "${result[*]}" != "${expected}" ]]; then
builder_die "FAIL: Wrong output for 'builder_echo start foo description' (no debug, is child):\n Actual : ${result[*]}\n Expected: ${expected}"
fi
expected=""
expected="$(builder_echo success "description")"
result=$(builder_echo end "foo" success "description")
if [[ "${result[*]}" != "${expected}" ]]; then
builder_die "FAIL: Wrong output for 'builder_echo end foo success description' (no debug, is child):\n Actual : ${result[*]}\n Expected: ${expected}"

View file

@ -30,6 +30,11 @@ set -eu
#
SHLVL=0
# A regex of reserved builder parameters, must be kept in sync with
# the matching of builder parameters in _builder_parse_expanded_parameters
_builder_reserved_parameters='^(--help|-h|--color|--no-color|--verbose|-v|--timings|--no-timings|--debug|--release|--deps|--no-deps|--force-deps|--builder-dep-parent|--builder-child|--builder-report-dependencies|--builder-completion-describe|--offline|--builder-ignore-unknown-options)$'
# _builder_init is called internally at the bottom of this file after we have
# all function declarations in place.
function _builder_init() {
@ -180,7 +185,7 @@ function builder_heading() {
builder_echo() {
local color=white message= mark= block= action= do_output=true test=
local color=white message= mark= block= action= test=
local echo_target=echo
if [[ $# -gt 1 ]]; then
@ -194,9 +199,6 @@ builder_echo() {
shift 2
action="start"
color="heading"
if ! builder_is_running_on_teamcity && builder_is_child_build; then
do_output=${_builder_debug_internal:-false}
fi
elif [[ $1 == "end" ]] || [[ $1 == "endTest" ]]; then
# builder_echo end block status message
test="$1"
@ -204,9 +206,6 @@ builder_echo() {
color="$3"
shift 3
action="end"
if [[ "${color}" != "error" ]] && ! builder_is_running_on_teamcity && builder_is_child_build; then
do_output=${_builder_debug_internal:-false}
fi
fi
fi
message="$*"
@ -219,30 +218,28 @@ builder_echo() {
fi
fi
if ${do_output}; then
if [[ ! -z ${COLOR_RED+x} ]]; then
case $color in
white) color="$COLOR_WHITE" ;;
grey) color="$COLOR_GREY" ;;
green|success) color="$COLOR_GREEN" ;;
blue|heading) color="$COLOR_BLUE" ;;
yellow|warning) color="$COLOR_YELLOW" ;;
red|error) color="$COLOR_RED"; echo_target=_builder_error_echo ;;
purple) color="$COLOR_PURPLE" ;;
brightwhite) color="$COLOR_BRIGHTWHITE" ;;
teal|debug) color="$COLOR_TEAL" ;;
setmark) mark="$HEADING_SETMARK" color="$COLOR_PURPLE" ;;
esac
if [[ ! -z ${COLOR_RED+x} ]]; then
case $color in
white) color="$COLOR_WHITE" ;;
grey) color="$COLOR_GREY" ;;
green|success) color="$COLOR_GREEN" ;;
blue|heading) color="$COLOR_BLUE" ;;
yellow|warning) color="$COLOR_YELLOW" ;;
red|error) color="$COLOR_RED"; echo_target=_builder_error_echo ;;
purple) color="$COLOR_PURPLE" ;;
brightwhite) color="$COLOR_BRIGHTWHITE" ;;
teal|debug) color="$COLOR_TEAL" ;;
setmark) mark="$HEADING_SETMARK" color="$COLOR_PURPLE" ;;
esac
if builder_is_dep_build; then
$echo_target -e "$mark$COLOR_GREY[$THIS_SCRIPT_IDENTIFIER]$COLOR_RESET $color$message$COLOR_RESET"
else
$echo_target -e "$mark$BUILDER_BOLD$COLOR_BRIGHT_WHITE[$THIS_SCRIPT_IDENTIFIER]$COLOR_RESET $color$message$COLOR_RESET"
fi
if builder_is_dep_build; then
$echo_target -e "$mark$COLOR_GREY[$THIS_SCRIPT_IDENTIFIER]$COLOR_RESET $color$message$COLOR_RESET"
else
# Cope with the case of pre-init message and just emit plain text
$echo_target -e "$message"
$echo_target -e "$mark$BUILDER_BOLD$COLOR_BRIGHT_WHITE[$THIS_SCRIPT_IDENTIFIER]$COLOR_RESET $color$message$COLOR_RESET"
fi
else
# Cope with the case of pre-init message and just emit plain text
$echo_target -e "$message"
fi
if [[ "${action}" == "end" ]] && builder_is_running_on_teamcity; then
@ -447,28 +444,47 @@ _builder_cleanup_deps() {
# than calling the build script directly, to avoid multiple builds of
# dependencies.
#
# Do not use builder standard options such as `--deps` or `--debug`.
#
# ### Parameters
#
# * 1: `script` path to script, relative to root of repo
# * 2: `action` action(s)+target(s) for the child script to run, comma separated, at least one
# * 2+: `parameters` action(s), target(s), parameters for the child script to run
#
# ### Example
#
# ```bash
# builder_launch /core/build.sh configure,build:wasm
# builder_launch core/build.sh configure,build:wasm --no-tests
# ```
#
builder_launch() {
local script="$1"
local action="$2"
_builder_execute_child_script "${KEYMAN_ROOT}${script}" "${action}" ""
local param
shift
if [[ ! "$script" =~ ^/(.+) ]]; then
builder_die "Error: builder_launch: script path must start with /, and is relative to repo root"
fi
for param in "$@"; do
if [[ "${param}" =~ ${_builder_reserved_parameters} ]]; then
builder_die "Error: builder_launch: reserved parameter '${param}' used"
fi
done
builder_echo grey "## script '$script $*' launched..."
_builder_execute_child_script "${KEYMAN_ROOT}${script}" "$@"
builder_echo grey "## script '$script $*' completed"
}
_builder_execute_child() {
local action="$1"
local target="$2"
local script="$THIS_SCRIPT_PATH/${_builder_target_paths[$target]}/build.sh"
builder_echo grey "## child $action$target starting..."
_builder_execute_child_script "$script" "$action"
builder_echo grey "## child $action$target completed successfully"
}
# ### Parameters
@ -478,18 +494,15 @@ _builder_execute_child() {
# * 3: `target` reporting target, used when executing a child script through builder_run_child_actions, optional
_builder_execute_child_script() {
local script="$1"
local action="$2"
local target="${3:-}"
builder_echo start "child#$action$target" "## child $action$target starting..."
_builder_timing_start "$action$target"
# subsequent parameters passed as $@/$* below
shift
# Build array of specified inheritable options
local child_options=()
local opt
for opt in "${_builder_options_inheritable[@]}"; do
if builder_has_option $opt; then
child_options+=($opt)
if builder_has_option "${opt}"; then
child_options+=("${opt}")
fi
done
@ -509,17 +522,14 @@ _builder_execute_child_script() {
--builder-child \
$_builder_build_deps \
$dep_flag "$dep_module" \
"$action" \
${child_options[@]} \
"$@" \
"${child_options[@]}" \
$builder_verbose \
$builder_debug \
$_builder_offline \
&& (
_builder_timing_stop "$action$target"
builder_echo end "child#$action$target" success "## child $action$target completed successfully"
) || (
|| (
result=$?
builder_echo end "child#$action$target" error "## child $action$target failed with exit code $result"
builder_echo error "## child script '$script $*' failed with exit code $result"
exit $result
) || exit $? # Required due to above subshell masking exit
}
@ -766,10 +776,6 @@ _builder_timing_cleanup_and_report() {
return 0
fi
if [[ -z "${_builder_timing_report_file:+x}" ]]; then
return 0
fi
if [[ "$build_exit_code" != 0 ]]; then
# Hide the timings report if build failed, but still cleanup
_builder_timings=false
@ -1615,6 +1621,7 @@ _builder_parse_expanded_parameters() {
fi
else
# See also _builder_reserved_parameters
case "$key" in
--help|-h)
builder_display_usage
@ -1810,21 +1817,14 @@ _builder_completion_describe() {
echo -n "; "
printf '%s ' "${_builder_targets[@]}"
echo -n "; "
# Remove all '+' suffixes from options; they're a config on the option, not part
# of the actual option text itself.
local _builder_opts=()
for e in "${!_builder_params[@]}"; do
if [[ $e =~ ^-- ]]; then
_builder_opts+=(${e%+*})
fi
done
# Add default options
_builder_opts+=( --verbose --debug --color --no-color --offline --help )
local opts=("${_builder_options[@]}")
# Add default options; see also _builder_reserved_parameters
opts+=( --verbose --debug --release --color --no-color --offline --help --timings --no-timings )
if builder_has_dependencies; then
_builder_opts+=( --deps --no-deps --force-deps )
opts+=( --deps --no-deps --force-deps )
fi
printf '%s ' "${_builder_opts[@]}"
printf '%s ' "${opts[@]}"
}
builder_display_usage() {
@ -1900,6 +1900,7 @@ builder_display_usage() {
fi
done
# See also _builder_reserved_parameters
_builder_pad $width " --verbose, -v" "Verbose logging"
_builder_pad $width " --debug, -d" "Debug build"
_builder_pad $width " --color" "Force colorized output"