Skip to content

docs: guard timeout for portability, validate capability-probe output - #40

Merged
CybotTM merged 1 commit into
mainfrom
feat/retro-timeout-portability
Jul 22, 2026
Merged

docs: guard timeout for portability, validate capability-probe output#40
CybotTM merged 1 commit into
mainfrom
feat/retro-timeout-portability

Conversation

@CybotTM

@CybotTM CybotTM commented Jul 22, 2026

Copy link
Copy Markdown
Member

Two gotchas hit while auto-detecting bash-completion support across ~112 CLI tools.

1. timeout is not portable

timeout is GNU coreutils; a stock macOS does not ship it. A hard-coded
timeout 30 <tool> … therefore fails with timeout: command not found and produces
empty output — and wrapped in the usual || true / 2>/dev/null, that failure is
silent, so every downstream check reads "the tool produced nothing" instead of "the
guard is missing".

Concretely: this passed on ubuntu-latest and failed on macos-latest, where every
probed tool looked incapable. Documents a run_bounded helper (timeoutgtimeout
→ unbounded), and notes that </dev/null — not the timeout — is what actually prevents
the common hang, and is portable.

2. Validate the shape of a capability probe's output

Detecting support by running the tool has a failure mode beyond "non-zero exit" and
"empty output": a tool that doesn't recognise the subcommand may treat the probe words
as arguments and do real work. bandit complete bash runs a security scan over
paths named complete/bash, exits 0, and prints a report containing the word
"complete" — passing any keyword grep.

Adds three rules: require a real registration (complete -…/compgen/COMPREPLY),
probe from a scratch dir with stdin detached, and confirm the output refers to the tool
you probed — a wrapper can return its host's answer (rga --generate complete-bash
returns ripgrep's script verbatim; a gh extension's completion emits gh's own).

Follow-up, not in this PR

Four shipped installers use bare timeout for version detection and so hit item 1 on
macOS (version reported as <none>):
installers/package_manager.sh, uv_tool.sh, github_release_binary.sh,
npm_self_update.sh. Fixing them properly means a shared helper in scripts/lib/
plus all four call sites — worth doing as its own change, and I can't exercise macOS
here to verify it. Flagging rather than folding a partly-untestable installer refactor
into a docs PR.

Came from /retro: yes

`timeout` is GNU coreutils and absent from a stock macOS, so a hard-coded
`timeout 2 <tool> --version` fails outright with "command not found" and yields
empty output; wrapped in the usual `|| true`, that reads downstream as "the tool
produced nothing". Symptom: a step green on ubuntu-latest, failing on
macos-latest with the tool reported absent. Document a run_bounded helper
(timeout → gtimeout → unbounded), noting that `</dev/null` is what actually
prevents the common hang and is portable.

Also document validating the shape of a capability probe's output: a tool that
does not recognise the subcommand may treat the probe words as arguments and do
real work — `bandit complete bash` runs a scan, exits 0, and prints output
containing "complete". And confirm the result refers to the tool probed, since a
wrapper can return its host's answer (`rga --generate complete-bash` returns
ripgrep's script verbatim).

Came from /retro: yes

Signed-off-by: Sebastian Mendel <github@sebastianmendel.de>
Copilot AI review requested due to automatic review settings July 22, 2026 10:47
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@sonarqubecloud

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@CybotTM
CybotTM merged commit 1c2c1b7 into main Jul 22, 2026
17 of 18 checks passed
@CybotTM
CybotTM deleted the feat/retro-timeout-portability branch July 22, 2026 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants