Skip to content

Add cmdio.RenderFiltered to strip fields from rendered output#5450

Open
Divyansh-db wants to merge 2 commits into
mainfrom
input-only-field-handling
Open

Add cmdio.RenderFiltered to strip fields from rendered output#5450
Divyansh-db wants to merge 2 commits into
mainfrom
input-only-field-handling

Conversation

@Divyansh-db
Copy link
Copy Markdown
Contributor

Summary

Adds new cmdio.RenderFiltered and cmdio.RenderIteratorFiltered entry points that mirror Render / RenderIterator but accept a []string of dotted JSON paths to strip from the value before it is marshaled. The path list is consulted only by the JSON render path; text/template rendering is unchanged.

// before
return cmdio.Render(ctx, response)

// after, when the response type has input-only fields
return cmdio.RenderFiltered(ctx, response, []string{"initial_workspace_id"})

Path syntax is dotted (a.b.c); arrays are traversed transparently, so the same path expression works for singleton and list responses without an items[] marker.

Motivation

The Databricks SDK uses a single Go struct per resource for both request and response (transport-layer pattern). Some fields are REQUIRED on the request side, so the SDK marshals them unconditionally, while also being INPUT_ONLY per the OpenAPI spec — they're never populated on responses. Generated CLI commands hand the SDK response struct directly to json.MarshalIndent, so those fields leak into user-visible output as empty strings even when the server omits them.

Existing in-repo precedents for honoring x-databricks-field-behaviors:

  • bundle/direct/tools/generate_resources.py reads INPUT_ONLY / OUTPUT_ONLY from the OpenAPI spec and propagates them into the DABs direct engine's ignore_remote_changes config.
  • bundle/internal/schema/main.go's removeOutputOnlyFields strips OUTPUT_ONLY from the bundle JSON schema.

RenderFiltered is the equivalent seam on the CLI response render path. This PR adds only the entry points; the genkit template change that starts calling them will land separately, followed by the generated-code regeneration in cmd/account/** and cmd/workspace/**.

Design notes

  • Render is unchanged in behavior (now a thin wrapper around RenderFiltered(_, _, nil)). Existing callers don't need to change.
  • Internal helper applyInputOnlyMask in libs/cmdio/filter.go round-trips the value through json.Marshal into a generic map[string]any tree, removes the listed leaf keys, and returns the masked value for the caller to marshal in its preferred format. Operating on the generic tree (rather than on raw bytes) lets defaultRenderer.renderJson and iteratorRenderer.renderJson reuse the same masking logic despite using different MarshalIndent prefixes.
  • Filtering happens before colorizeJSON, so the colorized output stays consistent.

Test plan

  • go test ./libs/cmdio/... — pass (new and existing tests)
  • gofmt -l clean on changed files; go vet ./libs/cmdio/... clean
  • ./task fmt-q / ./task lint-q — 0 issues
  • Unit tests cover: empty paths no-op, flat field strip, nested field strip, slice element strip, multiple paths, missing-path no-op, and an integration test confirming RenderFiltered matches plain Render when no paths are supplied.

Adds new cmdio.RenderFiltered and cmdio.RenderIteratorFiltered entry
points that mirror Render / RenderIterator but accept a list of dotted
JSON paths to strip from the value before it is marshaled. The list is
consulted only on the JSON render path; text/template rendering is
unchanged.

Motivation: the Databricks SDK uses a single transport struct per
resource for both request and response. Some fields are required on the
request side (so the SDK marshals them unconditionally) but
input-only on the response side per the OpenAPI spec. The CLI today
hands the SDK response struct directly to json.MarshalIndent, so those
fields leak into user-visible output even though the server doesn't
populate them. RenderFiltered gives generated CLI commands a way to
strip such fields without modifying the SDK or introducing a separate
view layer.

Nothing in the generated CLI surface calls these new entry points yet;
that switch will land alongside the corresponding codegen change.

Co-authored-by: Isaac
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Waiting for approval

Based on git history, these people are best suited to review:

  • @pietern -- recent work in libs/cmdio/

Eligible reviewers: @chrisst, @hectorcast-db, @mihaimitrea-db, @parthban-db, @rauchy, @renaudhartert-db, @simonfaltum, @tanmay-db, @tejaskochar-db

Suggestions based on git history. See OWNERS for ownership rules.

@eng-dev-ecosystem-bot
Copy link
Copy Markdown
Collaborator

eng-dev-ecosystem-bot commented Jun 5, 2026

Commit: e3d5421

Run: 27016619624

@Divyansh-db Divyansh-db requested a review from hectorcast-db June 5, 2026 12:52
deletePath was traversing arrays transparently but not maps. When the
generator emits a path like "tags.initial_workspace_id" for a
map[string]V field whose value type has an INPUT_ONLY field, the literal
"initial_workspace_id" key doesn't exist directly under "tags" — it
lives inside each map value — so the path was silently a no-op at
render time.

Mirror the array behavior: when a path component doesn't match a
literal key on the current object, descend into every value with the
same key list. The literal-match path is still preferred, so struct
field paths keep working unchanged.

Adds two tests: a top-level map field and a map nested inside another
struct, both checking that the inner field is stripped from every
value.

Co-authored-by: Isaac
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