Skip to content

Split stdout/stderr in cluster info for future --output json support #5

@saadqbal

Description

@saadqbal

Problem

`runClusterInfo` today takes a single `out io.Writer` and prints everything to it — discovery info, token state, "Ready for dataset push" footer. There's no separation between data lines (the structured discovery info a customer might pipe into another tool) and diagnostic lines (the friendly footer, status indicators).

When Phase 4 lands `tracebloc dataset push --output json`, we'll want the same split: structured payload to stdout, progress + diagnostic to stderr. Implementing that with the current single-writer API means rewriting every cluster-info caller.

Fix

Change `runClusterInfo` (and the upcoming `runDatasetPush`) to take `(stdout, stderr io.Writer)`:

```go
func runClusterInfo(
ctx context.Context,
stdout, stderr io.Writer,
flags clusterFlags,
) error {
// data lines go to stdout
fmt.Fprintf(stdout, "context: %s\n", ...)
// diagnostic / progress goes to stderr
fmt.Fprintln(stderr, "Discovering parent release...")
...
}
```

The cobra command's `RunE` plumbs `cmd.OutOrStdout()` + `cmd.ErrOrStderr()` in. Tests already capture both via `SetOut`/`SetErr`.

Add `--output {text|json}` as a flag; text mode keeps today's layout, json mode emits a single JSON document with the same fields. Reusable across subcommands via a tiny helper:

```go
type OutputFormat string
const (
OutputText OutputFormat = "text"
OutputJSON OutputFormat = "json"
)
```

Acceptance criteria

  • `tracebloc cluster info > info.txt` captures only the discovery lines (no diagnostic noise)
  • `tracebloc cluster info --output json > info.json` produces parseable JSON
  • `tracebloc cluster info --output json | jq .release.chart_version` works
  • Existing unit tests updated to capture both writers
  • Phase 4's `dataset push` lands on the same shape without reinventing it

Found by

Self-review of PR #2. The current narrow-interface signature was caught as "this won't scale to JSON output mode." Filed pre-emptively so Phase 4 doesn't have to first refactor before adding its real work.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions