Repository navigation
fix(generator): keep version in CRD schema names and merge multi-document CRDs into one spec - #182
Merged
Merged
Conversation
…ment CRDs into one spec Fixes #181. Since #180, importing a CRD with exactly one version produced schema names after the bare Kind (e.g. Widget), dropping the version qualifier. Two defects, one root cause: A. kcl import groups the generated files into per-version directories by extracting the version from the file name (_v1, _v1alpha1, ...). A single-version CRD rendered as models/unknown/widget.k instead of models/v1/example_com_v1_widget.k, silently changing the import path of published modules (e.g. strimzi_kafka_operator.v1 -> ...unknown). B. Two CRDs sharing a Kind across different API groups both rendered as models/widget.k: the CLI converts each YAML document of the input file into its own spec and generates each separately, so the second file silently overwrote the first with exit code 0. Fixes: - pkg/swagger/generator/names.go: append the version to the short root name unconditionally (Widget -> WidgetV1), so the file name always carries the version. When the same Kind+Version is declared by several API groups, every root of that class is additionally qualified with its group segments (example.com/other.com Widget -> ExampleComWidgetV1 / OtherComWidgetV1), keeping both definitions and preserving the group identity #180 removed. - pkg/kube_resource/generator/generator.go: GetSpecs/GetSpec now merge all YAML documents of one file into a single swagger spec, so every CRD of the file is generated in one run against a shared name registry instead of one overwrite-prone generation per document. As a side effect the standalone binary handles multi-document files too instead of silently converting only the first document. - pkg/swagger/generator/{model,language}.go: make the rendered default and example values deterministic. RecoverMapValueOrder filled MapSlice slots from value.MapKeys() (random order) and toKclValue iterated maps via MapRange (random order), so golden tests failed intermittently (~1 in 3 runs) on JSON key order. Multi-version CRDs keep the names #180 introduced (WidgetV1 / WidgetV1alpha1); --long-names is unchanged. Golden fixtures regenerated: single-version model files now carry the _v<version> suffix. Verified against the reproducer in the issue: two single-version Widget CRDs in one file now render as models/v1/example_com_widget_v1.k and models/v1/other_com_widget_v1.k, both fields intact, and the generated package compiles and runs with kcl (schema instantiation, apiVersion defaults). go test ./... passes; the golden suite was run repeatedly to confirm the flake is gone. Known limitation: the same Kind in different groups split across separate input files (kcl import -m crd a.yaml b.yaml) can still collide; 0.12.x avoided this via fully qualified names. The issue's repro is a single multi-document file, which this fix covers. Signed-off-by: Claude Opus 4.6 <noreply@anthropic.com>
Peefy
pushed a commit
that referenced
this pull request
Oct 9, 2026
…mp dir The generator wrote the bundled k8s.json next to the converted swagger spec to a fixed path in the shared temp dir on every GetSpec/GetSpecs call. go test runs the cmds and swagger/generator suites concurrently, and both invoke the converter (one in-process, one via the binary subprocess), so one run truncated the file while the other was reading it: "could not resolve schema: unexpected end of JSON input". CI failed intermittently on random CRD cases because of this (kcl-lang/kcl-openapi #182). Write the k8s.json and the spec into a fresh os.MkdirTemp directory per call instead. The relative "k8s.json#/definitions/..." references still resolve, now against the spec file's own private directory, and concurrent runs no longer share a file.
…mp dir The generator wrote the bundled k8s.json next to the converted swagger spec to a fixed path in the shared temp dir on every GetSpec/GetSpecs call. go test runs the cmds and swagger/generator suites concurrently, and both invoke the converter (one in-process, one via the binary subprocess), so one run truncated the file while the other was reading it: "could not resolve schema: unexpected end of JSON input". CI failed intermittently on random CRD cases because of this (kcl-lang/kcl-openapi #182). Write the k8s.json and the spec into a fresh os.MkdirTemp directory per call instead. The relative "k8s.json#/definitions/..." references still resolve, now against the spec file's own private directory, and concurrent runs no longer share a file. Signed-off-by: Claude Opus 4.6 <noreply@anthropic.com>
Peefy
force-pushed
the
fix/181-crd-single-version-names
branch
from
October 9, 2026 15:58
09939fb to
b50fd5b
Compare
WithXOrder wrote the rewritten spec to the temp dir root, away from the original document. Relative $refs in the spec (e.g. the k8s.json sidecar written next to converted CRD specs) resolve against the directory of the document being loaded, so the rewrite broke that resolution and the flatten step failed with "cannot load spec: open <tmp>/k8s.json: no such file or directory" on machines without a stale copy there. Local macOS runs passed only because earlier versions had left exactly such a stale file behind in the per-user temp dir. Write the rewrite into the original spec's directory instead, and remove both intermediate files at the end of analyzeSpec: the document content lives in the loaded specDoc by then, and the old behavior leaked the rewritten specs next to the sources whenever those lived outside the temp dir. Signed-off-by: Claude Opus 4.6 <noreply@anthropic.com>
Collaborator
Coverage Report for CI Build 37960217708Coverage increased (+2.0%) to 66.742%Details
Uncovered ChangesNo uncovered changes found. Coverage Regressions136 previously-covered lines in 5 files lost coverage.
Coverage Stats
💛 - Coveralls |
WithXOrder and getSpecFiles created their temp files with os.CreateTemp but never closed the returned handle (the content was written through a second handle, or written but left open). Harmless on unix, where tests remove temp dirs with open files just fine; on Windows the test cleanup fails with "The process cannot access the file because it is being used by another process" once the rewritten spec lives next to the input inside t.TempDir. Signed-off-by: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #181.
Since #180, a CRD with exactly one version gets a schema name after the bare Kind (e.g.
Widget), dropping the version qualifier. Two defects, one root cause:A.
kcl importgroups generated files into per-version directories by extracting the version from the file name (_v1,_v1alpha1, ...). A single-version CRD rendered asmodels/unknown/widget.kinstead ofmodels/v1/..., silently changing the import path of published modules (strimzi_kafka_operator.v1->...unknown).B. Two CRDs sharing a Kind across different API groups both rendered as
models/widget.k: the CLI converts each YAML document of the input file into its own spec and generates each separately, so the second file silently overwrote the first (exit code 0).Fix
pkg/swagger/generator/names.go: append the version to the short root name unconditionally (Widget->WidgetV1), so the file name always carries the version. When the same Kind+Version is declared by several API groups, every root of that class is additionally qualified with its group segments (example.com/other.comWidget->ExampleComWidgetV1/OtherComWidgetV1), keeping both definitions and preserving the group identity.pkg/kube_resource/generator/generator.go:GetSpecs/GetSpecnow merge all YAML documents of one file into a single swagger spec, so every CRD of the file is generated in one run against a shared name registry, instead of one overwrite-prone generation per document. Side effect: the standalone binary now handles multi-document files instead of silently converting only the first document.pkg/swagger/generator/{model,language}.go: make rendered default/example values deterministic.RecoverMapValueOrderfilledMapSliceslots fromvalue.MapKeys()(random order) andtoKclValueiterated maps viaMapRange(random order), so the golden suite failed intermittently (~1 in 3 runs) on JSON key order.Multi-version CRDs keep the names #180 introduced (
WidgetV1/WidgetV1alpha1);--long-namesis unchanged. Golden fixtures regenerated: single-version model files now carry the_v<version>suffix.Verification
The issue's reproducer now yields:
and the generated package compiles and runs with kcl (schema instantiation, correct
apiVersiondefaults).go test ./...passes; the golden suite was run repeatedly to confirm the flake is gone.Known limitation: the same Kind in different groups split across separate input files (
kcl import -m crd a.yaml b.yaml) can still collide; 0.12.x avoided this via fully qualified names. The reported repro is a single multi-document file, which this fix covers.