Propagate external refs into allOf#2299
Propagate external refs into allOf#2299mromaszewicz wants to merge 1 commit intooapi-codegen:mainfrom
Conversation
Greptile SummaryThis PR fixes a bug where
Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| pkg/codegen/merge_schemas.go | Extracts inline property-ref propagation into a recursive propagateRemoteRefs helper that also walks Items and AdditionalProperties; correctly fixes the reported issue but does not cover AnyOf/OneOf/AllOf/Not sub-schema refs. |
| internal/test/externalref/packageA/spec.yaml | Adds EnrichedUser schema that extends the external User type via allOf, reproducing the cross-file array-items ref qualification bug from issue #2288; missing newline at end of file (pre-existing). |
| internal/test/externalref/packageB/spec.yaml | Adds Role enum and User object (with a roles: []Role array) to packageB's spec, providing the external types needed to exercise the fix. |
Reviews (1): Last reviewed commit: "Propagate external refs into allOf" | Re-trigger Greptile
0ecc287 to
ee50af8
Compare
|
I tested your patch with the following files, which is an extract of a bigger api in which I encountered the same issue. cfg-api.yaml: package: api
output: api.gen.go
generate:
models: true
output-options:
# to make sure that all types are generated
skip-prune: true
import-mapping:
./types.yaml: "types"api.yaml: components:
schemas:
CustomerStatusPostPayloadV1:
allOf:
- $ref: './types.yaml#/components/schemas/CustomerStatusV1'
- type: object
properties:
name:
type: stringtypes.yaml components:
schemas:
CustomerStatusEnum:
type: string
enum:
- Approved
- Disputed
- Suspended
CustomerStatusV1:
allOf:
- type: object
properties:
status:
$ref: '#/components/schemas/CustomerStatusEnum'The generated files still doesn't reference the enum properly: // Package api provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.6.0 DO NOT EDIT.
package api
// CustomerStatusPostPayloadV1 defines model for CustomerStatusPostPayloadV1.
type CustomerStatusPostPayloadV1 struct {
Name *string `json:"name,omitempty"`
Status *CustomerStatusEnum `json:"status,omitempty"`
} |
When an external schema is flattened via allOf, local #/... refs nested within properties, items, additionalProperties, and composition keywords (allOf, anyOf, oneOf, not) must be rewritten to include the remote component path. Without this, generated Go code references unqualified types that don't exist in the local package. Extracts ref-rewriting into a recursive propagateRemoteRefs helper and extends it to walk the full schema tree. Fixes oapi-codegen#2288 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ee50af8 to
f673c70
Compare
|
@cdevienne , thanks for this example. I'm very minimalist with this code because this aggregate schema traversal is so fragile. Could you see if this latest PR works for you? I've reproduced your test case in our unit tests, and it failed before my changes, and passes after. |
|
@mromaszewicz Tested it, it works! I have another similar issue though, will report it separately. Thanks a lot |
|
Just in case, the similar issue I got is: #2308 |
Closes: #2288
When allOf references an external schema, valueWithPropagatedRef was only rewriting direct property $refs to include the remote file path. Nested refs — array items, additionalProperties, and sub-object properties — were left as local "#/..." refs, producing unqualified Go type names that fail to compile.
Extract the propagation logic into a recursive propagateRemoteRefs function that walks Properties, Items, and AdditionalProperties, rewriting any local ref it finds. This ensures types like
*[]externalRef0.Roleare correctly qualified instead of the broken*[]Role.Extend the externalref test with a User/Role/EnrichedUser scenario that exercises the array-items case from the issue report.