diff --git a/base_api_manifest.yaml b/base_api_manifest.yaml index d1e4102..c456b64 100644 --- a/base_api_manifest.yaml +++ b/base_api_manifest.yaml @@ -94,7 +94,7 @@ modules: signature_source: lib/bash/git/README.md inputs: documented per symbol in the module README and API charter outputs: documented per symbol; named outputs are caller-owned - statuses: documented per symbol; recoverable failures return status + statuses: usage and contract errors return 2; recoverable failures and false predicates return 1 unless a symbol documents a specific status; freshness checks use 3 for dirty, 4 for behind, and 5 for diverged side_effects: documented per symbol; sourcing is passive stability: stable since: 2.0.0 @@ -111,7 +111,7 @@ modules: signature_source: lib/bash/gh/README.md inputs: documented per symbol in the module README and API charter outputs: documented per symbol; named outputs are caller-owned - statuses: documented per symbol; recoverable failures return status + statuses: usage and contract errors return 2; recoverable failures return 1 unless a symbol preserves an underlying gh status side_effects: documented per symbol; sourcing is passive stability: stable since: 2.0.0 diff --git a/docs/api-reference.md b/docs/api-reference.md index 5d68683..230991d 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -132,7 +132,7 @@ statuses, and side effects are normative in the linked module README and - Stability: `stable`; since `2.0.0`; deprecated: `false` - Inputs: documented per symbol in the module README and API charter - Outputs: documented per symbol; named outputs are caller-owned -- Statuses: documented per symbol; recoverable failures return status +- Statuses: usage and contract errors return 2; recoverable failures and false predicates return 1 unless a symbol documents a specific status; freshness checks use 3 for dirty, 4 for behind, and 5 for diverged - Side effects: documented per symbol; sourcing is passive #### Public symbols @@ -158,7 +158,7 @@ statuses, and side effects are normative in the linked module README and - Stability: `stable`; since `2.0.0`; deprecated: `false` - Inputs: documented per symbol in the module README and API charter - Outputs: documented per symbol; named outputs are caller-owned -- Statuses: documented per symbol; recoverable failures return status +- Statuses: usage and contract errors return 2; recoverable failures return 1 unless a symbol preserves an underlying gh status - Side effects: documented per symbol; sourcing is passive #### Public symbols diff --git a/docs/v2-api-contract.md b/docs/v2-api-contract.md index 19a17f9..9d79413 100644 --- a/docs/v2-api-contract.md +++ b/docs/v2-api-contract.md @@ -192,8 +192,8 @@ signature/effects reference; this table makes coverage auditable. | std validation/reflection | `base_std_assert_variable_name`, `base_std_assert_indexed_array`, `base_std_assert_associative_array`, `base_std_command_path`, `base_std_function_exists`, `base_std_assert_function_exists`, `base_std_assert_not_null`, `base_std_assert_integer`, `base_std_assert_integer_range`, `base_std_assert_arg_count`, `base_std_assert_command_exists`, `base_std_assert_file_exists`, `base_std_assert_executable`, `base_std_assert_dir_exists` | Predicates return status; explicit `assert_*` APIs are intentional fail-fast precondition checks; named outputs are validated before writes. | | std miscellaneous | `base_std_safe_cd`, `base_std_safe_unalias`, `base_std_get_my_source_dir`, `base_std_ask_yes_no`, `base_std_wait_for_enter` | `safe_cd` changes `PWD`; source-dir writes one validated output; interactive functions return recoverable EOF/non-TTY statuses. | | file | `base_file_section_exists`, `base_file_section_needs_update`, `base_file_update_file_section` | Read-only predicates do not mutate; update is idempotent, symlink-preserving, atomic, metadata-preserving, and conflict-aware. | -| git | `base_git_detect_default_branch`, `base_git_worktree_path_for_branch`, `base_git_list_worktree_branches`, `base_git_branch_upstream`, `base_git_branch_merged_to_ref`, `base_git_list_remote_branches`, `base_git_update_repo`, `base_git_get_current_branch`, `base_git_check_script_up_to_date` | Read-only inspections use named outputs/stdout as documented; update and freshness helpers return documented recoverable Git statuses. | -| gh | `base_gh_require_cli`, `base_gh_auth_status_diagnostics`, `base_gh_report_command_failure`, `base_gh_run`, `base_gh_repo_from_remote_url`, `base_gh_infer_repo_from_origin`, `base_gh_repo_default_branch`, `base_gh_api_with_retry` | Diagnostics go stderr; repository/API values use named outputs; retries are bounded and mutation-aware. | +| git | `base_git_detect_default_branch`, `base_git_worktree_path_for_branch`, `base_git_list_worktree_branches`, `base_git_branch_upstream`, `base_git_branch_merged_to_ref`, `base_git_list_remote_branches`, `base_git_update_repo`, `base_git_get_current_branch`, `base_git_check_script_up_to_date` | Usage and contract errors return `2`; recoverable Git failures and false predicates return `1` unless a function documents a specific status. Read-only inspections use named outputs/stdout as documented; freshness outcomes are `3` dirty, `4` behind, and `5` diverged. | +| gh | `base_gh_require_cli`, `base_gh_auth_status_diagnostics`, `base_gh_report_command_failure`, `base_gh_run`, `base_gh_repo_from_remote_url`, `base_gh_infer_repo_from_origin`, `base_gh_repo_default_branch`, `base_gh_api_with_retry` | Usage and contract errors return `2`; recoverable GitHub failures return `1` unless the helper preserves the underlying `gh` status. Diagnostics go stderr; repository/API values use named outputs; retries are bounded and mutation-aware. | | str | `base_str_lower`, `base_str_upper`, `base_str_ltrim`, `base_str_rtrim`, `base_str_trim`, `base_str_contains`, `base_str_starts_with`, `base_str_ends_with`, `base_str_split`, `base_str_join` | String transforms/predicates preserve caller values until validation succeeds; split/join use validated named outputs. | | arg | `base_arg_parse` | Parses into caller-owned validated arrays/maps and leaves them unchanged on failure. | | list | `base_list_append`, `base_list_prepend`, `base_list_remove`, `base_list_contains`, `base_list_unique`, `base_list_length` | Indexed-array mutators/predicates use caller-owned arrays; usage and operational errors return rather than exit. | diff --git a/lib/bash/gh/README.md b/lib/bash/gh/README.md index 21a102a..5a797fc 100644 --- a/lib/bash/gh/README.md +++ b/lib/bash/gh/README.md @@ -53,12 +53,14 @@ leave caller-owned result variables unchanged on failure; use `--optional` with `base_gh_infer_repo_from_origin` when a missing or non-GitHub origin is expected. Public functions validate the documented argument count before expanding -required positional parameters. Invalid calls return `1`, including when the -caller has enabled `nounset`; optional flags such as `--optional` are rejected -when misspelled. `base_gh_run` passes every GitHub argument after its optional -protected-diagnostic control prefix through unchanged. `base_gh_api_with_retry` -preserves those caller arguments except for the documented internal -response-metadata instrumentation on compatible retry-authorized calls. +required positional parameters. Usage and contract errors return `2`, including +when the caller has enabled `nounset`; recoverable GitHub failures return `1` +unless the function preserves the underlying `gh` status. Optional flags such +as `--optional` are rejected when misspelled. `base_gh_run` passes every GitHub +argument after its optional protected-diagnostic control prefix through +unchanged. `base_gh_api_with_retry` preserves those caller arguments except for +the documented internal response-metadata instrumentation on compatible +retry-authorized calls. The library does not change the caller's `errexit`, `nounset`, `pipefail`, `noclobber`, `shopt`, `IFS`, `OPTIND`, cwd, umask, traps, or positional diff --git a/lib/bash/gh/lib_gh.sh b/lib/bash/gh/lib_gh.sh index 3292d75..ce18eb7 100644 --- a/lib/bash/gh/lib_gh.sh +++ b/lib/bash/gh/lib_gh.sh @@ -6,7 +6,7 @@ [[ -n "${BASE_BASH_LIBS_GH_LOADED:-}" ]] && return 0 if [[ "${BASE_BASH_LIBS_STDLIB_LOADED:-}" != "1" ]]; then printf '%s\n' "Error: lib_gh.sh requires lib_std.sh to be sourced first." >&2 - return 1 2>/dev/null || exit 1 + return 1 2> /dev/null || exit 1 fi readonly BASE_BASH_LIBS_GH_LOADED=1 @@ -16,12 +16,12 @@ readonly BASE_BASH_LIBS_GH_LOADED=1 base_gh_require_cli() { if (($# > 1)); then base_std_log_error -l base_bash_libs.gh "Usage: base_gh_require_cli [install_hint]" - return 1 + return 2 fi local install_hint="${1:-}" - command -v gh >/dev/null 2>&1 || { + command -v gh > /dev/null 2>&1 || { base_std_log_error -l base_bash_libs.gh "Required command 'gh' was not found on PATH." [[ -z "$install_hint" ]] || base_std_log_error -l base_bash_libs.gh "$install_hint" return 1 @@ -32,14 +32,14 @@ __base_bash_libs_gh_sensitive_controls_usage__() { local __base_bash_libs_gh_controls_helper_name="${1-}" case "$__base_bash_libs_gh_controls_helper_name" in - base_gh_report_command_failure) - base_std_log_error -l base_bash_libs.gh \ - "Usage: base_gh_report_command_failure [gh args...] or base_gh_report_command_failure --sensitive [--safe-display