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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and versions are tracked in the repo-root `VERSION` file.

### Documentation

- Repositioned the README around the v2 application framework, added a
runnable CLI/configuration/lifecycle example, and organized the library map
by layer.

- Link the pinned Base Bash Demo v0.1.2 learning path from the README,
documentation index, and v2 quickstart, and refresh the consumer ledger.

Expand Down
54 changes: 46 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,64 @@

The v2.2.1 release is published with a deterministic [bundle archive](https://github.com/basefoundry/base-bash-libs/releases/download/v2.2.1/base-bash-libs-v2.2.1.tar.gz), [checksum manifest](https://github.com/basefoundry/base-bash-libs/releases/download/v2.2.1/base-bash-libs-v2.2.1.SHA256SUMS), [SPDX SBOM](https://github.com/basefoundry/base-bash-libs/releases/download/v2.2.1/base-bash-libs-v2.2.1.spdx.json), and [provenance statement](https://github.com/basefoundry/base-bash-libs/releases/download/v2.2.1/base-bash-libs-v2.2.1.provenance.json). First-party consumers and Homebrew can promote to its exact immutable commit through the coordinated release handoff; the original v2.0.0 cutover is recorded in completed issue #240.

Reusable Bash standard library for reliable shell scripts.
Base Bash is a Bash 4.2.53+ application framework and standard library for
declarative CLIs, typed configuration, lifecycle-safe cleanup, and reliable
shell automation.

base-bash-libs provides sourceable Bash libraries for logging, error handling,
safe command execution, filesystem edits, Git helpers, string utilities, temp
paths, cleanup hooks, and import conventions. It is extracted from
Requires Bash 4.2.53+. On macOS, use Homebrew Bash instead of the system `/bin/bash`.

It gives applications safe execution and filesystem primitives, a structured
command contract, configuration that is data-only and precedence-aware, and
immutable package identity. It is extracted from
[Base](https://github.com/basefoundry/base), but can be installed and used
independently through Homebrew, source checkouts, vendored copies, or git
submodules.

Requires Bash 4.2.53+. On macOS, use Homebrew Bash instead of the system `/bin/bash`.
A minimal v2 application declares its interface and policy before dispatch:

<!-- BEGIN README APPLICATION EXAMPLE -->
```bash
#!/usr/bin/env base-bash

base_launcher_import_base_bash_lib cli/lib_cli.sh app/lib_app.sh
base_cli_model_init hello name=hello version=1.0.0
base_cli_command hello greet "Greet someone" handler=hello_dispatch
base_app_init hello_policy name=hello
base_app_config_define hello_policy name string default=world env=HELLO_NAME
base_app_add_standard_options hello ""
hello_cleanup() { :; }
hello_execute() {
local name=""
base_app_apply_standard_options hello_policy
base_app_config_load hello_policy || return $?
base_app_hook hello_policy cleanup hello_cleanup hello_cleanup || return $?
base_app_config_get hello_policy name name || return $?
printf 'hello=%s\n' "$name"
}
hello_dispatch() { base_app_run hello_policy hello_execute; }
main() { base_cli_run hello -- "$@"; }
```
<!-- END README APPLICATION EXAMPLE -->

Run it with `HELLO_NAME=Base ./hello greet` to get `hello=Base`. Start with
the [v2 quickstart](docs/v2/quickstart.md) and then see the
[pinned Beacon reference consumer](https://github.com/basefoundry/base-bash-libs-demo/blob/v0.1.2/README.md)
for a complete offline application.

The shared Base ecosystem boundary is maintained in the [Base ecosystem
platform, license, and release policy](https://github.com/basefoundry/base/blob/main/docs/ecosystem-policy.md).

## Libraries

- [`lib/bash/std/lib_std.sh`](lib/bash/std/README.md)
The libraries are layered from foundation to application. Start with `std`
for portable primitives, add the building blocks your script needs, and use
`cli` plus `app` when it becomes a user-facing application.

- **Foundation:** [`lib/bash/std/lib_std.sh`](lib/bash/std/README.md)
Foundation helpers for logging, error handling, command execution, PATH
updates, assertions, prompts, imports, and the public
`BASE_BASH_LIBS_VERSION` constant.
- [`lib/bash/process/lib_process.sh`](lib/bash/process/README.md)
- **Building blocks:** [`lib/bash/process/lib_process.sh`](lib/bash/process/README.md)
Preview-only process-supervision primitives for owner-guardian liveness and
asynchronous cleanup, layered on the stdlib. This post-GA module first
shipped in `v2.1.0` and is included in the current immutable `v2.2.1`
Expand All @@ -55,7 +93,7 @@ platform, license, and release policy](https://github.com/basefoundry/base/blob/
- [`lib/bash/list/lib_list.sh`](lib/bash/list/README.md)
Indexed-array helpers built on the stdlib for in-place mutation,
membership checks, deduplication, and length results.
- [`lib/bash/cli/lib_cli.sh`](lib/bash/cli/README.md)
- **Application framework:** [`lib/bash/cli/lib_cli.sh`](lib/bash/cli/README.md)
Declarative command contracts with nested subcommands, validation, help,
completion, and a handler boundary for Bash applications.
- [`lib/bash/app/lib_app.sh`](lib/bash/app/README.md)
Expand Down
59 changes: 59 additions & 0 deletions tests/docs-contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,65 @@ grep -F 'five-minute, offline Beacon application' README.md > /dev/null || {
printf 'README must describe Beacon as a runnable learning path.\n' >&2
exit 1
}
grep -F 'Bash 4.2.53+ application framework and standard library' README.md > /dev/null || {
printf 'README must lead with the v2 application-framework value proposition.\n' >&2
exit 1
}
for readme_application_contract_text in \
'BEGIN README APPLICATION EXAMPLE' \
'base_cli_model_init hello' \
'base_app_config_define hello_policy name string' \
'base_app_hook hello_policy cleanup' \
'base_app_run hello_policy hello_execute' \
'HELLO_NAME=Base'; do
grep -F "$readme_application_contract_text" README.md > /dev/null || {
printf 'README application example is missing: %s\n' "$readme_application_contract_text" >&2
exit 1
}
done
grep -F 'The libraries are layered from foundation to application.' README.md > /dev/null || {
printf 'README must describe the layered library map.\n' >&2
exit 1
}
grep -F '**Foundation:**' README.md > /dev/null || {
printf 'README library map is missing the foundation layer.\n' >&2
exit 1
}
grep -F '**Building blocks:**' README.md > /dev/null || {
printf 'README library map is missing the building-block layer.\n' >&2
exit 1
}
grep -F '**Application framework:**' README.md > /dev/null || {
printf 'README library map is missing the application-framework layer.\n' >&2
exit 1
}

readme_application_example="$(mktemp "${TMPDIR:-/tmp}/base-bash-readme-example.XXXXXX")" || exit 1
awk '
/^<!-- BEGIN README APPLICATION EXAMPLE -->$/ { in_region = 1; next }
/^<!-- END README APPLICATION EXAMPLE -->$/ { exit }
in_region && /^```bash$/ { in_code = 1; next }
in_region && in_code && /^```$/ { in_code = 0; next }
in_region && in_code { print }
' README.md > "$readme_application_example" || exit 1
[[ -s "$readme_application_example" ]] || {
printf 'README application example is empty.\n' >&2
exit 1
}
readme_application_output="$(
HELLO_NAME=Base BASE_BASH_LIBS_DIR="$repo_root/lib/bash" \
"$repo_root/bin/base-bash" "$readme_application_example" greet
)" || {
printf 'README application example did not execute.\n' >&2
rm -f -- "$readme_application_example"
exit 1
}
rm -f -- "$readme_application_example"
[[ "$readme_application_output" == 'hello=Base' ]] || {
printf 'README application example produced unexpected output: %s\n' \
"$readme_application_output" >&2
exit 1
}
grep -F 'See a complete application' docs/v2/quickstart.md > /dev/null || {
printf 'The v2 quickstart must link to the complete Beacon application.\n' >&2
exit 1
Expand Down
Loading