Skip to content

Latest commit

 

History

History
87 lines (71 loc) · 4.23 KB

File metadata and controls

87 lines (71 loc) · 4.23 KB

lib_cli.sh

Declarative command contracts for professional Bash applications. The module keeps the command model, parser, validation rules, help output, and completion metadata in one source of truth. It is one sourceable file and requires lib/bash/std/lib_std.sh first.

Public API

  • base_cli_model_init MODEL [name=PROGRAM] [version=VERSION] [description=TEXT] [handler=FUNCTION] starts or replaces a model. MODEL is an in-process identifier and name is the executable name shown in usage and completion output.
  • base_cli_command MODEL PATH DESCRIPTION [HANDLER] [aliases=A,B] declares a nested command. PATH uses slash-separated command segments, and aliases are accepted at every segment while parsing and completing.
  • base_cli_option MODEL PATH NAME TYPE TOKEN... [help=TEXT] [metavar=NAME] [default=VALUE] [required=true|false] [enum=A,B] [validator=FUNCTION] [conflicts=A,B] [sensitive=true|false] [hidden=true|false] declares a flag, single value, or repeatable option. Tokens are exact -x or --long spellings; long options also accept --long=value for value kinds.
  • base_cli_positional MODEL PATH NAME [required=true|false] [repeatable=true|false] [default=VALUE] [enum=A,B] [validator=FUNCTION] [help=TEXT] [metavar=NAME] declares a positional argument. A repeatable positional must be the final positional in its command.
  • base_cli_help MODEL [PATH] renders deterministic help to stdout.
  • base_cli_parse MODEL -- [ARGV...] parses and validates an invocation. It returns 0 on success, 2 for usage/validation errors, and publishes the result in the BASE_BASH_LIBS_CLI_RESULT_* globals described below.
  • base_cli_run MODEL -- [ARGV...] parses, then invokes the declared handler for the selected command. A handler receives positional values as ordinary Bash arguments and reads options through the result helpers.
  • base_cli_complete MODEL -- [WORDS...] prints one completion candidate per line for the current prefix (the final word). base_cli_completion_script MODEL FUNCTION emits a portable Bash completion function.
  • base_cli_result_get KEY RESULT_VARIABLE, base_cli_result_get_positional INDEX RESULT_VARIABLE, and base_cli_result_count KEY RESULT_VARIABLE copy parsed values into caller-owned variables without command substitution.

Result contract

After a successful run parse:

  • BASE_BASH_LIBS_CLI_RESULT_OPTIONS is an associative array of scalar option values. Flags have value 1 when present.
  • BASE_BASH_LIBS_CLI_RESULT_REPEATED is keyed by NAME|INDEX, and BASE_BASH_LIBS_CLI_RESULT_REPEATABLE_COUNTS[NAME] records the count.
  • BASE_BASH_LIBS_CLI_RESULT_POSITIONALS preserves positional boundaries, including empty values and values beginning with - after --.
  • BASE_BASH_LIBS_CLI_RESULT_MODEL, ..._COMMAND, and ..._ACTION identify the model, canonical command path, and run, help, or version action.

Results are valid after a successful parse. A failed parse returns status 2 and may have partially inspected input, but does not claim a valid result.

Example

source "/path/to/base-bash-libs/lib/bash/std/lib_std.sh"
base_std_import cli/lib_cli.sh

base_cli_model_init deploy name=deploy version=2.0.0 description="Release tooling"
base_cli_command deploy release "Create a release" handler=deploy_release aliases=r
base_cli_option deploy release dry_run flag --dry-run -n help="Do not mutate"
base_cli_option deploy release channel value --channel default=stable enum=stable,canary
base_cli_option deploy release artifact repeatable --artifact help="Input artifact"
base_cli_positional deploy release target required=true metavar=TARGET

deploy_release() {
    local channel
    base_cli_result_get channel channel
    printf 'releasing %s via %s\n' "${1-}" "$channel"
}

base_cli_run deploy -- release target --channel canary --artifact app.tgz

Adapter boundary

The native model above is the canonical runtime contract. Projects may generate the same model from Bashly, Argc, Argbash, or another generator, but generated artifacts belong at an adapter/build boundary. The runtime does not detect, install, or require Python, Ruby, Node, jq, or any external generator.

Tests

BATS coverage lives in lib/bash/cli/tests/lib_cli.bats.