Skip to content

feat: add --json-schema flag to xrd convert#142

Open
fernandezcuesta wants to merge 3 commits into
crossplane:mainfrom
fernandezcuesta:141--xrd-convert-jsonschema
Open

feat: add --json-schema flag to xrd convert#142
fernandezcuesta wants to merge 3 commits into
crossplane:mainfrom
fernandezcuesta:141--xrd-convert-jsonschema

Conversation

@fernandezcuesta

@fernandezcuesta fernandezcuesta commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Description of your changes

Add --json-schema flag to xrd convert subcommand, similarly as what xpkg get-crds subcommand already provides.

Refactor the common logic to avoid duplication.

Fixes #141

I have:

Need help with this checklist? See the cheat sheet.

Signed-off-by: Jesús Fernández <7312236+fernandezcuesta@users.noreply.github.com>
@fernandezcuesta fernandezcuesta force-pushed the 141--xrd-convert-jsonschema branch from 9e0abf8 to a92acf9 Compare June 24, 2026 11:34
Signed-off-by: Jesús Fernández <7312236+fernandezcuesta@users.noreply.github.com>
@fernandezcuesta fernandezcuesta marked this pull request as ready for review June 24, 2026 11:39
@fernandezcuesta fernandezcuesta requested review from a team, jcogilvie and tampakrap as code owners June 24, 2026 11:39
@fernandezcuesta fernandezcuesta requested review from phisco and removed request for a team June 24, 2026 11:39
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds shared CRD-to-JSON-Schema generation, refactors xpkg get-crds to use it, and extends xrd convert with a --json-schema mode, unified output writing, tests, and help examples.

Changes

JSON Schema generation for xrd convert and xpkg get-crds

Layer / File(s) Summary
CRDJSONSchema and CRDsToJSONSchemas
internal/schemas/generator/json.go
Adds the CRD v1 import alias, exported CRDJSONSchema struct, and CRDsToJSONSchemas that converts CRD OpenAPI v3 schemas into indented JSON schema payloads with metadata.
xpkg get-crds uses shared JSON schema outputs
cmd/crossplane/xpkg/get_crds.go
Removes local JSON marshalling and GVK construction, calls CRDsToJSONSchemas, writes each generated schema payload to the derived .json path, and reports the number of schemas written.
xrd convert JSON Schema output path
cmd/crossplane/xrd/convert.go
Adds the JSONSchema flag, convertOutput, CRD and JSON Schema output builders, and writeOutputs for stdout, single-file, and output-directory persistence with multi-schema file rejection for single-file modes.
JSON Schema tests and convert docs
cmd/crossplane/xrd/convert_test.go, cmd/crossplane/xrd/help/convert.md
Adds JSON Schema conversion tests with stdout, file, and directory cases, multi-schema error coverage, a kong context helper, and new usage examples in the convert command help.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • crossplane/cli#12: Introduces the crossplane xrd convert command that this PR extends with --json-schema output.
  • crossplane/cli#26: Adds the earlier xpkg get-crds JSON schema path and related generator work that this PR refactors and reuses.

Suggested reviewers

  • jcogilvie
  • tampakrap
  • bobh66
🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the addition of the --json-schema flag to xrd convert.
Description check ✅ Passed The description matches the implemented flag addition, refactor, tests, and docs.
Linked Issues check ✅ Passed The change implements #141 by adding --json-schema support to xrd convert and matching xpkg get-crds behavior.
Out of Scope Changes check ✅ Passed All changes support JSON Schema output, refactoring, docs, and tests for the same feature.
Breaking Changes ✅ Passed Only additive --json-schema support and shared refactors; I found no removed/renamed public cmd flags or required flags, and existing CRD behavior remains intact.
Feature Gate Requirement ✅ Passed xrd convert sits under the beta-gated XRD command, and this PR only adds a CLI output mode; it doesn’t touch apis/** or add an ungated API feature.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
cmd/crossplane/xrd/convert_test.go (1)

109-189: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Solid coverage of the three output modes — thank you for adding this!

One coverage suggestion that ties into the writeOutputs concern: every case here uses minimalXRD(...Namespaced, nil), which yields a single schema, so the OutputFile/Stdout concatenation path never sees more than one output. Adding a legacy-XRD-with-Claim case (which TestToCRDs already shows produces two CRDs) would exercise the multi-schema behavior and lock in whatever decision we land on for that path. Would you be open to adding it?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/crossplane/xrd/convert_test.go` around lines 109 - 189,
TestConvertJSONSchema only covers a single-schema case, so writeOutputs is not
validated when multiple JSON Schemas are produced. Update TestConvertJSONSchema
to add a legacy XRD with Claim-enabled case, reusing the existing toCRDs and
toJSONSchemaOutputs flow, so the OutputFile and Stdout paths are exercised with
more than one schema. Keep the existing minimalXRD coverage, but add a case that
mirrors the multi-CRD behavior already demonstrated in TestToCRDs and assert the
expected multi-output behavior through convertCmd.writeOutputs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/crossplane/xrd/convert.go`:
- Around line 116-146: `toJSONSchemaOutputs` can return multiple `convertOutput`
entries for a single XRD, but the concatenating branch in `writeOutputs` appears
to assume only one JSON schema output and may merge or overwrite them
incorrectly. Update `writeOutputs` to iterate over all outputs returned by
`toJSONSchemaOutputs` (and keep the `toCRDOutputs` behavior consistent) so every
schema emitted by `CRDsToJSONSchemas` is preserved, using the existing
`toJSONSchemaOutputs` and `writeOutputs` flow as the main places to adjust.
- Around line 163-179: The JSON schema output path in convert.go currently
concatenates multiple schemas into one invalid JSON document when c.OutputFile
or stdout is used. Update the conversion flow around the outputs buffer/write
logic to either reject multi-schema output unless c.OutputDir is set, or
otherwise enforce a single-schema constraint in --json-schema mode. Use the
existing Convert/c.OutputFile/stdout handling to add the guard before writing,
and make sure the multi-schema case is covered explicitly rather than silently
emitting invalid JSON.

---

Nitpick comments:
In `@cmd/crossplane/xrd/convert_test.go`:
- Around line 109-189: TestConvertJSONSchema only covers a single-schema case,
so writeOutputs is not validated when multiple JSON Schemas are produced. Update
TestConvertJSONSchema to add a legacy XRD with Claim-enabled case, reusing the
existing toCRDs and toJSONSchemaOutputs flow, so the OutputFile and Stdout paths
are exercised with more than one schema. Keep the existing minimalXRD coverage,
but add a case that mirrors the multi-CRD behavior already demonstrated in
TestToCRDs and assert the expected multi-output behavior through
convertCmd.writeOutputs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9de61f10-3569-431a-8696-519bc03b87fd

📥 Commits

Reviewing files that changed from the base of the PR and between 28fa74b and b54952d.

📒 Files selected for processing (5)
  • cmd/crossplane/xpkg/get_crds.go
  • cmd/crossplane/xrd/convert.go
  • cmd/crossplane/xrd/convert_test.go
  • cmd/crossplane/xrd/help/convert.md
  • internal/schemas/generator/json.go

Comment thread cmd/crossplane/xrd/convert.go
Comment thread cmd/crossplane/xrd/convert.go
Signed-off-by: Jesús Fernández <7312236+fernandezcuesta@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmd/crossplane/xrd/convert_test.go (1)

129-132: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Please create the parent directory for the -o case.

Thanks for covering the single-file path. One catch: writeOutputs() does not MkdirAll() for OutputFile, so /out/schema.json will fail on afero.NewMemMapFs() before the JSON assertions run. Could we either pre-create /out in the test or write to a top-level file instead?

Suggested tweak
-			cmd:      convertCmd{JSONSchema: true, OutputFile: "/out/schema.json"},
-			wantFile: "/out/schema.json",
+			cmd:      convertCmd{JSONSchema: true, OutputFile: "/schema.json"},
+			wantFile: "/schema.json",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/crossplane/xrd/convert_test.go` around lines 129 - 132, The OutputFile
test case in convert_test.go is using a nested path without creating its parent
directory, so the `writeOutputs()` path for `convertCmd` will fail before the
JSON checks run. Update the `OutputFile` scenario to either pre-create the
parent directory for `/out/schema.json` in the test setup or switch `wantFile`
to a top-level file path, keeping the coverage focused on
`convertCmd.writeOutputs()` behavior.
🧹 Nitpick comments (1)
cmd/crossplane/xrd/convert_test.go (1)

216-226: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Could we make the rejection checks table-driven and assert the actual error?

Thanks for adding coverage for the multi-schema guardrails. Right now err == nil only proves a failure happened; it will not catch regressions in the actionable use --output-dir guidance. Folding these into args/wantErr cases and comparing with cmp.Diff(..., cmpopts.EquateErrors()) would match the repo’s test convention and lock down the CLI UX. As per path instructions, **/*_test.go: “Enforce table-driven test structure: PascalCase test names (no underscores), args/want pattern, use cmp.Diff with cmpopts.EquateErrors() for error testing.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/crossplane/xrd/convert_test.go` around lines 216 - 226, The multi-schema
rejection assertions in convertCmd.writeOutputs tests are still ad hoc and only
check for nil errors; convert these cases in convert_test.go to the repo’s
table-driven args/wantErr style, using cmp.Diff with cmpopts.EquateErrors() to
assert the exact error message and preserve the actionable “use --output-dir”
guidance. Keep the coverage around writeOutputs and the JSONSchema / OutputFile
scenarios, but fold them into a single PascalCase test with structured cases
instead of separate err == nil checks.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@cmd/crossplane/xrd/convert_test.go`:
- Around line 129-132: The OutputFile test case in convert_test.go is using a
nested path without creating its parent directory, so the `writeOutputs()` path
for `convertCmd` will fail before the JSON checks run. Update the `OutputFile`
scenario to either pre-create the parent directory for `/out/schema.json` in the
test setup or switch `wantFile` to a top-level file path, keeping the coverage
focused on `convertCmd.writeOutputs()` behavior.

---

Nitpick comments:
In `@cmd/crossplane/xrd/convert_test.go`:
- Around line 216-226: The multi-schema rejection assertions in
convertCmd.writeOutputs tests are still ad hoc and only check for nil errors;
convert these cases in convert_test.go to the repo’s table-driven args/wantErr
style, using cmp.Diff with cmpopts.EquateErrors() to assert the exact error
message and preserve the actionable “use --output-dir” guidance. Keep the
coverage around writeOutputs and the JSONSchema / OutputFile scenarios, but fold
them into a single PascalCase test with structured cases instead of separate err
== nil checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 387c002c-1e2f-4226-a32f-e7b669528125

📥 Commits

Reviewing files that changed from the base of the PR and between b54952d and a0554e9.

📒 Files selected for processing (2)
  • cmd/crossplane/xrd/convert.go
  • cmd/crossplane/xrd/convert_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/crossplane/xrd/convert.go

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.

Write XRD in jsonschema format

1 participant