diff --git a/README.md b/README.md index cf3e8a2..73e68ed 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ This repository provides sourceable Bash libraries for scripts that want consistent logging, command execution, filesystem editing, Git helper behavior, and import conventions without adopting the full Base workspace control plane. +Requires Bash 4.2+. On macOS, use Homebrew Bash instead of the system `/bin/bash`. + ## Libraries - [`lib/bash/std/lib_std.sh`](lib/bash/std/README.md) diff --git a/lib/bash/file/lib_file.sh b/lib/bash/file/lib_file.sh index 6ef864c..aedfa90 100644 --- a/lib/bash/file/lib_file.sh +++ b/lib/bash/file/lib_file.sh @@ -245,7 +245,6 @@ update_file_section() { return 0 fi else - # FIX: This awk script now correctly handles multiple sections. It only replaces the first one. if awk -v START_M="$beginning_marker" -v END_M="$end_marker" -v NEW_TEXT_FILE="$new_content_file" ' BEGIN { processed = 0 # 0 = not yet processed, 1 = processing, 2 = done diff --git a/lib/bash/std/lib_std.sh b/lib/bash/std/lib_std.sh index e29456f..cd4efab 100644 --- a/lib/bash/std/lib_std.sh +++ b/lib/bash/std/lib_std.sh @@ -73,6 +73,8 @@ unset -f __lib_std_require_supported_bash__ __stdlib_sourced__=1 readonly __LIB_STD_PATH__="${BASH_SOURCE[0]}" +# lib_std.sh lives at lib/bash/std/lib_std.sh in the packaged repository. +# Walking three levels up reaches the package root that owns VERSION. __BASE_BASH_LIBS_ROOT__="$( cd -- "$(dirname -- "$__LIB_STD_PATH__")/../../.." &>/dev/null && pwd -P )" || { @@ -1005,8 +1007,14 @@ assert_integer_range() { if ! __is_valid_variable_name__ "$var_name"; then fatal_error "assert_integer_range expects a variable name as its first argument." fi + if ! [[ "$min" =~ ^[-+]?[0-9]+$ ]]; then + fatal_error "assert_integer_range minimum bound '$min' is not a valid integer." + fi + if ! [[ "$max" =~ ^[-+]?[0-9]+$ ]]; then + fatal_error "assert_integer_range maximum bound '$max' is not a valid integer." + fi local value="${!var_name-}" - assert_integer "$var_name" min max + assert_integer "$var_name" ((value < min || value > max)) && fatal_error "Variable '$var_name' ($value) is out of range [$min, $max]." return 0 } diff --git a/lib/bash/std/tests/lib_std.bats b/lib/bash/std/tests/lib_std.bats index 71f4465..5052970 100644 --- a/lib/bash/std/tests/lib_std.bats +++ b/lib/bash/std/tests/lib_std.bats @@ -1128,6 +1128,36 @@ EOF [[ "$output" != *"invalid variable name"* ]] } +@test "assert_integer_range rejects non-integer bounds directly" { + local script="$TEST_TMPDIR/assert-range-bounds.sh" + + create_script "$script" </dev/null; th exit 1 fi +if ! sed -n '1,30p' README.md | grep -F 'Requires Bash 4.2+' >/dev/null; then + printf 'README.md must state the Bash 4.2+ requirement near the top-level entry point.\n' >&2 + exit 1 +fi + +fix_comments="$(grep -R -n '# FIX:' lib/bash || true)" +if [[ -n "$fix_comments" ]]; then + printf 'Production library files must not contain development # FIX: comments:\n%s\n' "$fix_comments" >&2 + exit 1 +fi + for command in shellcheck bats; do command -v "$command" >/dev/null 2>&1 || { printf "Required validation command '%s' was not found.\n" "$command" >&2