Skip to content

[Feat] Add global --output json flag for structured output#60

Merged
samzong merged 1 commit intomainfrom
fix/output-json
Mar 30, 2026
Merged

[Feat] Add global --output json flag for structured output#60
samzong merged 1 commit intomainfrom
fix/output-json

Conversation

@samzong
Copy link
Copy Markdown
Owner

@samzong samzong commented Mar 30, 2026

What's changed?

  • Add global --output (-o) persistent flag on root command with text (default) and json values
  • Validate at flag parse time via custom pflag.Value (no PersistentPreRunE chaining issues)
  • gmc wt ls -o json / gmc wt -o json: emit WorktreeJSON array with full commit hashes
  • gmc wt prune --dry-run -o json / gmc wt prune -o json: emit structured PruneJSON array via PruneResult.Candidates
  • gmc wt share list -o json: emit ShareJSON array
  • gmc config get -o json: emit config as JSON object (deprecates --json flag)
  • gmc tag -o json: emit TagJSON with current tag, suggested version, and commit messages
  • Shell completion for --output flag
  • Extract resolveWorktreeStatus to deduplicate status logic between text and JSON paths
  • Add PruneCandidate / PruneResult to internal worktree package for structured prune data
  • 10 new tests covering flag validation, JSON round-trip, worktree list/default JSON, text regression, and status resolution

Why

Signed-off-by: samzong <samzong.lu@gmail.com>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a global --output (or -o) flag to support both text and JSON output formats across multiple commands, including config get, tag, and several worktree subcommands. The existing --json flag in the config get command has been deprecated in favor of this new unified approach. A regression was identified in the worktree prune command where the new implementation fails to display partial reports when an error occurs mid-operation, which differs from the previous behavior.

Comment thread cmd/worktree_prune.go
Comment on lines +40 to +61
result, err := wtClient.Prune(opts)
if err != nil {
return err
}
if outputFormat() == "json" {
action := "removed"
if opts.DryRun {
action = "would-remove"
}
items := make([]PruneJSON, len(result.Candidates))
for i, c := range result.Candidates {
items[i] = PruneJSON{
Name: c.Name,
Branch: c.Branch,
Status: c.Status,
Action: action,
}
}
return printJSON(outWriter(), items)
}
printWorktreeReport(result.Report)
return nil
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This change introduces a regression in error handling. Previously, if wtClient.Prune failed mid-operation, the partial report was still printed, giving the user information about what succeeded before the failure. With the new logic, if an error occurs, the function returns immediately, and no report (neither text nor JSON) is printed.

To preserve the old behavior and provide a better user experience, the report/JSON output should be generated before returning the error from the Prune operation.

result, err := wtClient.Prune(opts)
	if outputFormat() == "json" {
		action := "removed"
		if opts.DryRun {
			action = "would-remove"
		}
		items := make([]PruneJSON, len(result.Candidates))
		for i, c := range result.Candidates {
			items[i] = PruneJSON{
				Name:   c.Name,
				Branch: c.Branch,
				Status: c.Status,
				Action: action,
			}
		}
		if printErr := printJSON(outWriter(), items); printErr != nil {
			return printErr
		}
	} else {
		printWorktreeReport(result.Report)
	}
	return err

@samzong samzong merged commit 848de2f into main Mar 30, 2026
1 check passed
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