diff --git a/CHANGELOG.md b/CHANGELOG.md index a4036ef..9c96a24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,8 @@ and versions are tracked in the repo-root `VERSION` file. grace period. - Changed list and string array helpers to require caller-declared indexed arrays instead of silently coercing scalar variables. +- Changed repository validation to run a warning-level ShellCheck profile for + production libraries, examples, validation scripts, and shared test helpers. ## [1.0.0] - 2026-06-21 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba853f6..8186899 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,6 +44,8 @@ boundary. Useful commands: ```bash +./tests/validate.sh +tests/lint-warnings.sh basectl check base-bash-libs basectl doctor base-bash-libs basectl test base-bash-libs diff --git a/bin/base-bash b/bin/base-bash index d978dbc..49e3b8b 100755 --- a/bin/base-bash +++ b/bin/base-bash @@ -72,6 +72,8 @@ base_bash_ensure_supported_bash() { for candidate in "${candidates[@]}"; do [[ -x "$candidate" ]] || continue [[ "$candidate" == "${BASH:-}" ]] && continue + # Re-exec under a supported Bash; the current process should not continue. + # shellcheck disable=SC2093 exec "$candidate" "$0" "$@" done @@ -123,6 +125,8 @@ base_bash_source_stdlib() { local stdlib_path="$BASE_BASH_LIBS_DIR/std/lib_std.sh" shift + # Consumed by lib_std.sh while it is being sourced below. + # shellcheck disable=SC2034 BASE_BASH_BOOTSTRAP_SOURCE="$script_path" # shellcheck source=/dev/null source "$stdlib_path" "$@" || exit $? diff --git a/examples/cookbook-args-lists-strings.sh b/examples/cookbook-args-lists-strings.sh index 8b5d8db..6f6fc8d 100755 --- a/examples/cookbook-args-lists-strings.sh +++ b/examples/cookbook-args-lists-strings.sh @@ -11,6 +11,8 @@ import "$repo_root/lib/bash/str/lib_str.sh" declare -A options=() declare -a positionals=() +# Passed by name to arg_parse. +# shellcheck disable=SC2034 declare -a specs=( "verbose|flag|--verbose|-v" "tag|value|--tag|-t" @@ -22,7 +24,11 @@ tag="${options[tag]-default}" str_trim tag str_lower tag +# Mutated by name through list helpers. +# shellcheck disable=SC2034 declare -a values=() +# Mutated by name through list helpers. +# shellcheck disable=SC2034 declare -a unique_values=() summary="" count="" diff --git a/lib/bash/std/lib_std.sh b/lib/bash/std/lib_std.sh index 67d3d1c..18f6b9a 100644 --- a/lib/bash/std/lib_std.sh +++ b/lib/bash/std/lib_std.sh @@ -326,6 +326,7 @@ import() { import_path="$__SCRIPT_DIR__/$lib" fi if [[ -f "$import_path" ]]; then + # shellcheck disable=SC1090 source "$import_path" exit_if_error $? "Import of library '$lib' not successful." else @@ -1987,6 +1988,8 @@ wait_for_enter() { # The only function that would be called upon sourcing of the library # __stdlib_init__ +# Used by companion libraries as a source-order guard. +# shellcheck disable=SC2034 readonly BASE_BASH_LIBS_STDLIB_LOADED=1 # This is the crucial step: it resets the positional parameters ($@, $1, etc.) diff --git a/lib/bash/tests/test_helper.sh b/lib/bash/tests/test_helper.sh index a161505..49af9f4 100644 --- a/lib/bash/tests/test_helper.sh +++ b/lib/bash/tests/test_helper.sh @@ -6,11 +6,18 @@ if declare -f run >/dev/null 2>&1; then eval "$(declare -f run | sed '1 s/^run /bats_run /')" fi -readonly BASE_BASH_TESTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" -readonly BASE_BASH_DIR="$(cd "$BASE_BASH_TESTS_DIR/.." && pwd -P)" -readonly BASE_REPO_ROOT="$(cd "$BASE_BASH_DIR/../.." && pwd -P)" -readonly BASE_CLI_BASH_DIR="$BASE_REPO_ROOT/cli/bash" -readonly BASE_TEST_ORIG_PATH="$PATH" +BASE_BASH_TESTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" +readonly BASE_BASH_TESTS_DIR +BASE_BASH_DIR="$(cd "$BASE_BASH_TESTS_DIR/.." && pwd -P)" +readonly BASE_BASH_DIR +BASE_REPO_ROOT="$(cd "$BASE_BASH_DIR/../.." && pwd -P)" +# Used by BATS suites loaded after this helper. +# shellcheck disable=SC2034 +readonly BASE_REPO_ROOT +# Used by BATS suites loaded after this helper. +BASE_TEST_ORIG_PATH="$PATH" +# shellcheck disable=SC2034 +readonly BASE_TEST_ORIG_PATH unset_base_runtime_env() { local var_name @@ -57,10 +64,14 @@ capture_command() { set +e "$@" >"$capture_file" 2>&1 + # BATS-compatible globals consumed by individual test cases after capture_command returns. + # shellcheck disable=SC2034 status=$? set -e + # shellcheck disable=SC2034 output="$(cat "$capture_file")" + # shellcheck disable=SC2034 IFS=$'\n' read -r -d '' -a lines < "$capture_file" || true } diff --git a/tests/lint-warnings.sh b/tests/lint-warnings.sh new file mode 100755 index 0000000..1002434 --- /dev/null +++ b/tests/lint-warnings.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -e + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" || exit 1 +cd "$repo_root" || exit 1 + +lint_files=( + bin/base-bash + tests/validate.sh + tests/lint-warnings.sh + examples/std-usage.sh + examples/cookbook-cleanup-temp.sh + examples/cookbook-args-lists-strings.sh + lib/bash/std/lib_std.sh + lib/bash/file/lib_file.sh + lib/bash/git/lib_git.sh + lib/bash/str/lib_str.sh + lib/bash/arg/lib_arg.sh + lib/bash/list/lib_list.sh + lib/bash/tests/test_helper.sh + tests/launcher.bats +) + +shellcheck --severity=warning "${lint_files[@]}" diff --git a/tests/validate.sh b/tests/validate.sh index b9972f9..4c4c640 100755 --- a/tests/validate.sh +++ b/tests/validate.sh @@ -38,6 +38,7 @@ required_files=( lib/bash/list/tests/lib_list.bats lib/bash/tests/test_helper.sh tests/launcher.bats + tests/lint-warnings.sh ) cd "$repo_root" || exit 1 @@ -94,6 +95,7 @@ done shellcheck --severity=error \ bin/base-bash \ tests/validate.sh \ + tests/lint-warnings.sh \ examples/std-usage.sh \ examples/cookbook-cleanup-temp.sh \ examples/cookbook-args-lists-strings.sh \