Skip to content

cli: absorb jsonOut bool into outputModeWriter; parseFlagSet promotes at parse boundary#212

Merged
brandon-fryslie merged 2 commits into
masterfrom
va-001-jsonout-writer-mode
Jun 11, 2026
Merged

cli: absorb jsonOut bool into outputModeWriter; parseFlagSet promotes at parse boundary#212
brandon-fryslie merged 2 commits into
masterfrom
va-001-jsonout-writer-mode

Conversation

@brandon-fryslie

Copy link
Copy Markdown
Collaborator

Summary

Closes links-va-001-jsonout-b4u.1 — absorption of the redundant jsonOut bool param threaded through 20+ printValue call sites.

  • Removed jsonOut bool from printValue signature and all call sites across backup.go, bulk.go, cli.go, dependency.go, doctor.go, hooks.go, issue_relations.go, sync.go, and more
  • parseFlagSet now absorbs --json flag directly into the outputModeWriter at the parse boundary — the bool never escapes flag parsing
  • printValue reads output mode from the writer via outputModeFromWriter; no parallel signal
  • Added TestSubcommandJSONFlagPromotesWriterMode to pin the promoted-mode behavior

Test plan

  • go test ./... green
  • TestSubcommandJSONFlagPromotesWriterMode verifies --json flag correctly promotes writer mode at the parse boundary
  • Existing output_mode_test.go tests unaffected

… at parse boundary (links-va-001-jsonout-b4u.1)

Remove the redundant `jsonOut bool` parameter from printValue and all 20+
call sites. The outputModeWriter already carries the mode; parseFlagSet now
promotes it to JSON when --json is parsed, so consumers read the mode from
the writer. Adds JSONFlag() on cobraFlagSet as the single parse-boundary
declaration; newOutputModeWriter wraps a *outputMode so promotion propagates
through interface copies. Test harnesses updated to pass newOutputModeWriter
instead of raw *bytes.Buffer when exercising --json paths.

@brandon-fryslie brandon-fryslie left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

One blocking finding; everything else is correct.

What I verified as sound

Pointer cell design is correct. newOutputModeWriter takes mode by value, takes its address (&mode), and Go heap-escapes it. Every copy of the outputModeWriter struct shares the same *outputMode cell, so promoteToJSON() through any interface copy (including the one extracted by stdout.(jsonPromoter)) mutates the shared cell and is visible to all subsequent readers. The value-receiver on promoteToJSON() is not a bug: the mutation is through the pointer, not the struct value.

Sequencing is correct. In both runRank and runRankSet, parseFlagSet runs before the outputModeFromWriter(stdout) checks that guard the substitution notices. The promotion happens at the right time.

Global --json + subcommand --json interaction is correct. Run() wraps the writer in JSON mode when global --json is present. If parseFlagSet then sees a subcommand --json, it promotes JSON to JSON, which is idempotent.

GetBool("json") on unregistered flag is safe. If a subcommand omits JSONFlag(), GetBool returns an error and the err == nil guard skips the promotion block. Passing --json to such a subcommand correctly errors at fs.Parse() with "unknown flag."

Blocking: internal error path is untested

See inline comment on output_mode_test.go:115. The guard "internal: --json parsed but output writer cannot carry JSON mode" has no test coverage. [LAW:verifiable-goals]

Comment thread internal/cli/output_mode_test.go
…SON mode

[LAW:verifiable-goals] The guard that refuses --json on a non-promotable
writer had no behavioral test; add the failing-case assertion to
TestSubcommandJSONFlagPromotesWriterMode so the contract is
machine-checkable.
@brandon-fryslie brandon-fryslie merged commit 8d493dd into master Jun 11, 2026
5 of 6 checks passed
@brandon-fryslie brandon-fryslie deleted the va-001-jsonout-writer-mode branch June 11, 2026 08:12
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.

1 participant