feat: add global --jq flag for filtering JSON output
Summary
Adds a per-command --jq <expr> flag for filtering JSON output, implemented with gojq (the same library gh CLI uses).
Stacked on !3294 (merged) — depends on every command's JSON output going through IOStreams.PrintJSON, which !3294 (merged) establishes.
Design
Two registration paths so the flag only appears on commands that emit JSON:
cmdutils.EnableJSONOutput(cmd, io, &opts.outputFormat[, desc])— bundles both--output=text|jsonand--jq. ~49 commands now use this single helper for both flags.cmdutils.AddJQFlag(cmd, io)— standalone helper for the ~13 commands with bespoke output flag definitions (e.g.variable exportwithjson/env/export,issuable listwith--output-format), and the ~4 always-JSON commands (orbit/*) that have no--outputflag.
Behavior
- Fail-fast validation: jq expression syntax is checked in
PreRunE. If invalid, the command never runs. - Output mode enforcement: for commands with an
--outputflag,--jqrequires--output=json. The check is inPreRunE, so the command's text output never appears before the error. - Always-JSON commands:
orbit/*commands work directly with--jqsince they have no output flag to coordinate. - Output format: string results emitted raw (matches
jq -r); other results emitted as compact JSON, one result per line. - Error wording: messages lead with a capital word so charm/fang's first-word title-casing doesn't capitalize the
--jqflag name (--Jq).
Examples
glab mr list -F json --jq '.[].iid' # one iid per line, no JSON quoting
glab mr list -F json --jq 'map(select(.draft)) | .[].title'
glab orbit remote tools --jq '.[0]' # always-JSON command
glab variable list -F json --jq 'length'
# Error paths (all fail before the command runs):
glab mr list --jq '.[]' # error: requires --output=json
glab mr list -F text --jq '.[]' # error: explicit conflict
glab mr list -F json --jq '.[' # error: invalid expression
glab version --jq '.foo' # error: unknown flag (not registered)Out of scope
glab api --paginate --output ndjson streams documents and does not route through PrintJSON. The existing | jq shell pipeline keeps working for that command. A follow-up MR will add --jq support for the streaming path.
Test plan
-
go test ./...passes locally -
golangci-lint run ./...reports 0 issues -
--jqshows in--helponly for JSON-emitting commands - All four error paths fail before any command output appears
- Spot-check
glab mr list -F json --jq '.[].iid'against a real project - Spot-check
glab orbit remote tools --jq '.[0]'(always-JSON command) - Verify
glab api projects/...(out of scope) still works with external| jq
Edited by Kai Armstrong