Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/base-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ jobs:
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-cli
ref: 9f3ed25fc0991e3aa9de8411878805c122f90a11
ref: v0.4.0
path: .base/base-cli

- name: Set up Python
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-cli
ref: 9f3ed25fc0991e3aa9de8411878805c122f90a11
ref: v0.4.0
path: .dependencies/base-cli

- name: Set up Python
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-cli
ref: 9f3ed25fc0991e3aa9de8411878805c122f90a11
ref: v0.4.0
path: .dependencies/base-cli

- name: Set up Python ${{ matrix.python-version }}
Expand Down
20 changes: 10 additions & 10 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-cli
ref: 9f3ed25fc0991e3aa9de8411878805c122f90a11
ref: v0.4.0
path: .dependencies/base-cli

- name: Set up Python
Expand Down Expand Up @@ -67,13 +67,13 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-bash-libs
ref: 2c5ef2c3a9edfbe2cf68d0645be65b920255abff
ref: 9afc98999010d48e8277018b3641e0e796beaf44
path: .dependencies/base-bash-libs

- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-cli
ref: 9f3ed25fc0991e3aa9de8411878805c122f90a11
ref: v0.4.0
path: .dependencies/base-cli

- name: Expose standalone Python package checkout as sibling
Expand Down Expand Up @@ -119,13 +119,13 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-bash-libs
ref: 2c5ef2c3a9edfbe2cf68d0645be65b920255abff
ref: 9afc98999010d48e8277018b3641e0e796beaf44
path: .dependencies/base-bash-libs

- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-cli
ref: 9f3ed25fc0991e3aa9de8411878805c122f90a11
ref: v0.4.0
path: .dependencies/base-cli

- name: Expose standalone Python package checkout as sibling
Expand Down Expand Up @@ -211,13 +211,13 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-bash-libs
ref: 2c5ef2c3a9edfbe2cf68d0645be65b920255abff
ref: 9afc98999010d48e8277018b3641e0e796beaf44
path: .dependencies/base-bash-libs

- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-cli
ref: 9f3ed25fc0991e3aa9de8411878805c122f90a11
ref: v0.4.0
path: .dependencies/base-cli

- name: Expose standalone Python package checkout as sibling
Expand Down Expand Up @@ -275,13 +275,13 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-bash-libs
ref: 2c5ef2c3a9edfbe2cf68d0645be65b920255abff
ref: 9afc98999010d48e8277018b3641e0e796beaf44
path: .dependencies/base-bash-libs

- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-cli
ref: 9f3ed25fc0991e3aa9de8411878805c122f90a11
ref: v0.4.0
path: .dependencies/base-cli

- name: Expose reusable Bash library checkout as sibling
Expand Down Expand Up @@ -343,7 +343,7 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-cli
ref: 9f3ed25fc0991e3aa9de8411878805c122f90a11
ref: v0.4.0
path: .dependencies/base-cli

- name: Set up Python
Expand Down
6 changes: 3 additions & 3 deletions STANDARDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,9 @@ source-fragment graph.
into Base-owned executable shell files.
2. Do not rely on implicit shell exit behavior for control flow.
3. Prefer explicit error handling using helper functions such as:
- `run`
- `exit_if_error`
- `fatal_error`
- `base_std_run`
- `base_std_exit_if_error`
- `base_std_fatal_error`
4. When a command may fail as part of normal flow, handle that failure with
`if`, `case`, `||`, or an explicit return-code check.
5. A script should make its error-handling strategy obvious to the reader.
Expand Down
50 changes: 34 additions & 16 deletions base_init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@
# - export the BASE_* paths that downstream scripts may rely on
# - export BASE_OS, BASE_PLATFORM, BASE_HOST_ENV, and BASE_HOST runtime metadata
# - resolve and source the reusable Bash standard library
# - require a compatible 1.x base-bash-libs release line
# - require a base-bash-libs release with the v2 `base_` API surface
# - add BASE_BIN_DIR to PATH
# - provide import_base_lib for convention-based Base Bash library imports
#
# Downstream scripts should not rediscover Base's directory layout on their own.
# They should use the exported BASE_* variables and import libraries with:
# They should use the exported BASE_* variables and import Base Bash libraries with:
#
# import_base_lib file/lib_file.sh
#
# import_base_lib loads reusable libraries from base-bash-libs. It reports
# missing or invalid libraries through Base stdlib error handling and fails
# immediately, so callers do not need duplicate checks.
# import_base_lib delegates to the v2 package importer. It reports missing or
# invalid libraries through Base stdlib error handling and fails immediately,
# so callers do not need duplicate checks.
#

[[ -n "${_base_init_sourced:-}" ]] && return 0
Expand Down Expand Up @@ -277,6 +277,8 @@ base_init_export_contract() {

base_init_source_stdlib() {
local stdlib_path="$BASE_BASH_LIBS_DIR/std/lib_std.sh"
local runtime_source
local -a runtime_args=()

[[ -f "$stdlib_path" ]] || {
base_init_error "Base Bash stdlib '$stdlib_path' was not found."
Expand All @@ -285,17 +287,29 @@ base_init_source_stdlib() {

# shellcheck source=/dev/null
source "$stdlib_path"

runtime_source="${BASE_BASH_LIBS_BOOTSTRAP_SOURCE:-${BASE_BASH_COMMAND_SCRIPT:-$BASE_HOME/base_init.sh}}"
base_init runtime_args --source "$runtime_source" -- "$@" || {
base_init_error "Unable to initialize the base-bash-libs runtime state."
return 1
}
}

base_init_require_bash_libs_version() {
local loaded_version="${BASE_BASH_LIBS_VERSION:-}"

case "$loaded_version" in
1.*)
base_bash_libs_require_version 1.3.0
1.*|2.*)
# The v2 namespace landed before the coordinated v2 release. Keep
# the source checkout usable while the release train is completed;
# the final cutover will raise this floor to 2.0.0.
if ! base_require_version 1.4.0; then
base_init_error "Base requires base-bash-libs 1.4.0 or newer; loaded version is '$loaded_version'."
return 1
fi
;;
*)
base_init_error "Base requires base-bash-libs 1.3.0 or a compatible later 1.x release; loaded version is '$loaded_version'."
base_init_error "Base requires base-bash-libs 1.4.0 or a compatible release with the v2 API; loaded version is '$loaded_version'."
return 1
;;
esac
Expand All @@ -316,21 +330,25 @@ base_init_source_command_protocol() {
import_base_lib() {
local relative_path="${1:-}"
local lib_path
local lib_path

[[ -n "$relative_path" ]] || fatal_error "import_base_lib: no library path provided."
[[ "$relative_path" != /* ]] || fatal_error "import_base_lib: expected a path relative to '$BASE_BASH_LIBS_DIR', got '$relative_path'."
[[ -n "$relative_path" ]] || base_std_fatal_error "import_base_lib: no library path provided."
[[ "$relative_path" != /* ]] || base_std_fatal_error "import_base_lib: expected a path relative to '$BASE_BASH_LIBS_DIR', got '$relative_path'."

case "$relative_path" in
..|../*|*/..|*/../*)
fatal_error "import_base_lib: refusing path outside Base Bash library root: '$relative_path'."
base_std_fatal_error "import_base_lib: refusing path outside Base Bash library root: '$relative_path'."
;;
esac
esac

lib_path="$BASE_BASH_LIBS_DIR/$relative_path"
[[ -f "$lib_path" ]] || fatal_error "Base reusable library '$relative_path' was not found at '$lib_path'."
[[ -f "$lib_path" ]] || {
base_init_error "Base reusable library '$relative_path' was not found at '$lib_path'."
return 1
}

# shellcheck source=/dev/null
source "$lib_path" || fatal_error "Failed to import Base library '$lib_path'."
base_std_import "$relative_path" ||
base_std_fatal_error "Failed to import Base library '$relative_path'."
}

base_init_main() {
Expand All @@ -340,7 +358,7 @@ base_init_main() {
base_init_require_bash_libs_version || return 1
base_init_source_command_protocol || return 1

add_to_path -p "$BASE_BIN_DIR"
base_std_add_to_path -p "$BASE_BIN_DIR"
export PATH
}

Expand Down
3 changes: 2 additions & 1 deletion bin/base-test
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ base_test_unset_env=(
-u BASE_BASH_COMMAND_NAME
-u BASE_BASH_COMMAND_DIR
-u BASE_BASH_COMMAND_SCRIPT
-u BASE_BASH_BOOTSTRAP_SOURCE
-u BASE_BASH_LIBS_BOOTSTRAP_SOURCE
-u BASE_INIT_TEST_OS_RELEASE_PATH
-u BASE_INIT_TEST_KERNEL_OSRELEASE_PATH
-u BASE_INIT_TEST_PROC_VERSION_PATH
Expand All @@ -51,6 +51,7 @@ base_test_unset_env=(
-u BASE_CLI_RUN_ID
-u BASE_CLI_RUN_ROOT
-u BASE_CLI_PRIMARY_LOG
-u BASE_BASH_LIBS_PRIMARY_LOG
-u BASE_CLI_HISTORY_PARENT_RUN_ID
-u BASE_CLI_HISTORY_STARTED_AT
-u BASE_CLI_HISTORY_SCOPE
Expand Down
10 changes: 5 additions & 5 deletions bin/basectl
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,10 @@ basectl_filter_runtime_args() {
elif ((parse_options)); then
case "$1" in
--debug-wrapper)
export LOG_DEBUG=1
export BASE_BASH_LIBS_LOG_DEBUG=1
;;
--utc-wrapper)
export LOG_UTC=1
export BASE_BASH_LIBS_LOG_UTC=1
;;
--color)
# Propagate the explicit color choice to Python-backed child
Expand Down Expand Up @@ -300,10 +300,10 @@ basectl_run_bash_script() {
export BASE_BASH_COMMAND_SCRIPT="$script_path"

# shellcheck disable=SC2034 # Consumed by base_init.sh during this source call.
BASE_BASH_BOOTSTRAP_SOURCE="$script_path"
BASE_BASH_LIBS_BOOTSTRAP_SOURCE="$script_path"
# shellcheck source=/dev/null
source "$base_home/base_init.sh" "$@" || exit $?
unset BASE_BASH_BOOTSTRAP_SOURCE
unset BASE_BASH_LIBS_BOOTSTRAP_SOURCE
readonly BASE_BASH_COMMAND_NAME BASE_BASH_COMMAND_DIR BASE_BASH_COMMAND_SCRIPT

unset -f main
Expand All @@ -312,7 +312,7 @@ basectl_run_bash_script() {
source "$script_path" "${basectl_runtime_args[@]}" || exit $?

if ! declare -F main >/dev/null 2>&1; then
fatal_error "Script '$script_path' did not define main()."
base_std_fatal_error "Script '$script_path' did not define main()."
fi

main "${basectl_runtime_args[@]}"
Expand Down
18 changes: 9 additions & 9 deletions cli/bash/commands/basectl/basectl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,13 @@ basectl_runtime_base_home() {
}

basectl_enable_debug_logging() {
set_log_level DEBUG
export LOG_DEBUG=1
base_std_set_log_level DEBUG
export BASE_BASH_LIBS_LOG_DEBUG=1
}

basectl_source_subcommand_module() {
local module_name="$1"
local subcommand_script="$__SCRIPT_DIR__/subcommands/${module_name}.sh"
local subcommand_script="$BASE_BASH_COMMANDS_DIR/basectl/subcommands/${module_name}.sh"

[[ -f "$subcommand_script" ]] || {
basectl_error "Subcommand module '$subcommand_script' was not found."
Expand Down Expand Up @@ -614,7 +614,7 @@ basectl_initialize_run_bundle() {
BASE_CLI_RUN_ID="${BASE_CLI_RUN_ID%%__*}"
export BASE_CLI_RUN_ID
fi
export BASE_CLI_PRIMARY_LOG="${BASE_CLI_PRIMARY_LOG:-$BASE_CLI_RUN_ROOT/logs/primary.log}"
export BASE_BASH_LIBS_PRIMARY_LOG="${BASE_BASH_LIBS_PRIMARY_LOG:-$BASE_CLI_RUN_ROOT/logs/primary.log}"
export BASE_CLI_HISTORY_PARENT_RUN_ID="${BASE_CLI_HISTORY_PARENT_RUN_ID:-$BASE_CLI_RUN_ID}"
return 0
fi
Expand All @@ -631,12 +631,12 @@ basectl_initialize_run_bundle() {
export BASE_CLI_RUNTIME_OWNER=base
export BASE_CLI_RUN_ID="$run_id"
export BASE_CLI_RUN_ROOT="$run_root"
export BASE_CLI_PRIMARY_LOG="$run_root/logs/primary.log"
export BASE_BASH_LIBS_PRIMARY_LOG="$run_root/logs/primary.log"
export BASE_CLI_HISTORY_PARENT_RUN_ID="$run_id"
printf '{"run_id":"%s","owner":"base","status":"running","started_at":"%s"}\n' \
"$run_id" "$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || true)" >"$run_root/run.json"
: >"$BASE_CLI_PRIMARY_LOG"
chmod 600 "$run_root/run.json" "$BASE_CLI_PRIMARY_LOG" || {
: >"$BASE_BASH_LIBS_PRIMARY_LOG"
chmod 600 "$run_root/run.json" "$BASE_BASH_LIBS_PRIMARY_LOG" || {
basectl_error "Unable to secure Base run bundle '$run_root'. Check file permissions."
return 1
}
Expand All @@ -653,7 +653,7 @@ basectl_finalize_run_bundle() {
"$([[ "$exit_code" == 0 ]] && printf ok || printf error)" "$exit_code" \
"${BASE_CLI_HISTORY_STARTED_AT:-}" \
"$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || true)" >"$tmp_file" && mv -f "$tmp_file" "$run_root/run.json"
chmod 600 "$run_root/run.json" "${BASE_CLI_PRIMARY_LOG:-$run_root/logs/primary.log}" || return 1
chmod 600 "$run_root/run.json" "${BASE_BASH_LIBS_PRIMARY_LOG:-$run_root/logs/primary.log}" || return 1
if [[ "${BASE_CLI_KEEP_TEMP:-}" != true ]]; then
rm -rf -- "$run_root/tmp"
fi
Expand Down Expand Up @@ -797,7 +797,7 @@ basectl_main() {
BASE_CLI_HISTORY_STARTED_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || true)"
export BASE_CLI_HISTORY_STARTED_AT
((base_debug)) && basectl_enable_debug_logging
log_debug "Running basectl command '${command:-<none>}' with args: $*"
base_std_log_debug "Running basectl command '${command:-<none>}' with args: $*"

case "$command" in
activate) basectl_do_activate "$@"; command_status=$? ;;
Expand Down
Loading
Loading