Skip to content

Hide deprecated fields from CLI output (#228)#230

Merged
sdairs merged 5 commits into
mainfrom
issue-228-hide-deprecated-fields
Jun 4, 2026
Merged

Hide deprecated fields from CLI output (#228)#230
sdairs merged 5 commits into
mainfrom
issue-228-hide-deprecated-fields

Conversation

@sdairs
Copy link
Copy Markdown
Collaborator

@sdairs sdairs commented Jun 2, 2026

Closes #228.

The CLI surfaced every field the OpenAPI response carries, including deprecated ones — confusing for agents/users who can't tell a field is deprecated. This hides them while keeping deserialization intact, and extends the same treatment to deprecated request fields so callers can't set them either.

Library (clickhouse-cloud-api)

  • Add a deprecated-fields Cargo feature (off by default). Fields the spec marks deprecated: true — on both response schemas (Service.tier, ApiKey.roles, …) and request schemas (ServicePostRequest.tier, InvitationPostRequest.role, …) — are gated behind #[cfg(feature = "deprecated-fields")], so they're absent from the struct by default. Reading a deprecated response field is a compile error; deprecated request fields can't be set and never hit the wire.
  • A deprecated required request field (per the description heuristic) is modelled Option<T> so it can be gated out and omitted, with a matching OPTIONALITY_EXEMPTIONS entry.
  • Add DEPRECATED_FIELDS to meta.rs; scripts/regenerate-deprecated-fields.py regenerates it from the snapshot. deprecated_fields_match_spec (constant vs spec) and deprecated_fields_hidden (constant vs models.rs markers) keep all three in lockstep.

CLI (clickhousectl)

  • Enable serde_json preserve_order; add cloud/output.rs::print_human, which renders responses as an indented tree from their serialized form. Detail/get human output now flows through serde — so deprecated fields disappear from both human and --json output via one path, in declaration order.
  • List columns that referenced a deprecated field switch to its non-deprecated replacement (e.g. Member.roleassignedRoles); request builders drop the deprecated fields.

Scripts/docs

  • Extend scripts/check-openapi-drift.py to report deprecation drift. Document the mechanism in both READMEs and CLAUDE.md.

Testing

  • cargo build/cargo test pass with the feature both off and on.
  • New unit tests in output.rs cover the renderer; models_test.rs covers deprecated-field (de)serialization under both feature configs; spec_coverage_test.rs gains the drift/hidden assertions.

🤖 Generated with Claude Code


Note

Medium Risk
Touches org membership, invitations, API keys, and service create/scaling request shapes; default behavior omits deprecated fields but changes visible CLI columns and wire payloads for those flows.

Overview
Adds a deprecated-fields Cargo feature (off by default) so OpenAPI deprecated: true fields are removed from models.rs unless the feature is on—blocking compile-time access and keeping them off the wire for requests and out of serialized output for responses. DEPRECATED_FIELDS in meta.rs, regenerate-deprecated-fields.py, and spec_coverage_test / check-openapi-drift.py keep the list aligned with the spec.

The CLI forwards the feature, switches detail views to print_human (serde-driven trees with preserve_order), updates member/invitation list tables to assignedRoles, and stops sending deprecated fields in request builders. Docs and tests cover both feature configurations.

Reviewed by Cursor Bugbot for commit c8a5ffc. Bugbot is set up for automated code reviews on this repo. Configure here.

sdairs and others added 4 commits June 2, 2026 12:32
The CLI surfaced every field returned by the OpenAPI response, including
deprecated ones — confusing for agents that can't tell a field is
deprecated. Hide them from output while keeping deserialization intact.

Library (clickhouse-cloud-api):
- Add `deprecated-fields` Cargo feature (off by default). Deprecated
  response fields carry
  `#[cfg_attr(not(feature = "deprecated-fields"), serde(skip_serializing))]`
  so they deserialize normally but are omitted from serialization unless
  the feature is enabled. Request-side schemas are left untouched.
- Add `DEPRECATED_OUTPUT_FIELDS` + `is_deprecated_output_field` to meta.rs,
  and tests `deprecated_output_fields_match_spec` (constant vs spec) and
  `deprecated_output_fields_hidden` (constant vs models.rs markers).

CLI (clickhousectl):
- Enable serde_json `preserve_order`; add `cloud/output.rs::print_human`
  rendering responses as an indented tree from their serialized form.
- Convert detail/get human-output branches to `print_human`, so deprecated
  fields disappear from both human and `--json` output via one serde path.

Scripts/docs:
- Add scripts/regenerate-deprecated-fields.py; extend check-openapi-drift.py
  to report deprecation drift. Document in both READMEs and CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deprecated response fields previously used
`#[cfg_attr(not(feature = "deprecated-fields"), serde(skip_serializing))]`:
they stayed readable in Rust and were only hidden from serialization. That
left a gap — list commands build `tabled` rows by direct field access
(`m.role`), which bypasses serde, so `member list` and `invitation list`
leaked the deprecated `role` field into output.

Switch the marker to `#[cfg(feature = "deprecated-fields")]` so the field is
removed from the struct entirely by default. Referencing a deprecated field is
now a compile error anywhere — tables included — making leaks impossible to
ship rather than caught by a runtime/test heuristic. The existing feature flag
still restores the fields (now via a `clickhousectl` passthrough feature).

- models.rs: gate all 10 deprecated response fields.
- member/invitation list: replace the deprecated Role column with a Roles
  column sourced from the non-deprecated `assignedRoles[].roleName`.
- Gate the ~19 library-test reads of deprecated fields behind the feature;
  add `deprecated_fields_absent_by_default` for the default build.
- spec_coverage_test: detect the new marker form; drift checks unchanged.
- Docs/tooling updated to the new "absent by default" contract.

Verified: build, clippy, and test pass on default features and with
`deprecated-fields` (both crates).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extend deprecated-field hiding to request-side schemas: all 14 fields the
spec marks deprecated on *Request/*Patch/*Input now carry
#[cfg(feature = "deprecated-fields")], so by default callers can't set them
and skip_serializing_if keeps them off the wire — matching the response side.

Two were bare required types (InvitationPostRequest.role,
OrganizationPrivateEndpointsPatch.add); flip them to Option<T> and add
OPTIONALITY_EXEMPTIONS entries. Unify the response-only DEPRECATED_OUTPUT_FIELDS
into a single DEPRECATED_FIELDS (24 entries) / is_deprecated_field covering
both sides; rename the drift tests, regenerate/drift scripts, and docs to match.

CLI request builders drop the deprecated assignments (gated so both feature
configs compile). Tests cfg-gate the affected literals/assertions and the
wiremock body matchers no longer assert deprecated keys.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rename to DEPRECATED_FIELDS and note it now covers request- and response-side
deprecated fields, matching meta.rs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sdairs sdairs requested a review from iskakaushik as a code owner June 2, 2026 14:51
@sdairs sdairs temporarily deployed to cloud-integration June 2, 2026 14:52 — with GitHub Actions Inactive
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3a9881e. Configure here.

Comment thread crates/clickhousectl/src/cloud/output.rs
…ated-fields

# Conflicts:
#	CLAUDE.md
#	CLAUDE.md~HEAD
#	crates/clickhouse-cloud-api/tests/spec_coverage_test.rs
Copy link
Copy Markdown
Collaborator

@iskakaushik iskakaushik left a comment

Choose a reason for hiding this comment

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

LGTM!

@sdairs sdairs merged commit ef7dc88 into main Jun 4, 2026
14 checks passed
@sdairs sdairs deleted the issue-228-hide-deprecated-fields branch June 4, 2026 17:28
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.

Hide deprecated fields from CLI output

2 participants