Fix: Ensure external refs are propagated to generated code#1389
Fix: Ensure external refs are propagated to generated code#1389jamietanna merged 1 commit intomasterfrom
Conversation
71813ff to
520ad55
Compare
pkg/codegen/operations.go
Outdated
| Schema: contentSchema, | ||
| } | ||
|
|
||
| // TODO finish comment |
pkg/codegen/operations.go
Outdated
| // TODO finish comment | ||
| parts := strings.SplitN(parentRef, "#", 2) | ||
| if parentRef != "" && len(parts) == 2 { | ||
| // TODO finish comment |
pkg/codegen/operations.go
Outdated
| rcd.Schema = Schema{ | ||
| RefType: fmt.Sprintf("%s.%s", pack.Name, contentSchema.GoType), | ||
| } | ||
| } // TODO log when not found |
There was a problem hiding this comment.
Not as part of this one
e7cef18 to
f4d7d4c
Compare
|
I'm getting the following error when trying this out: |
14ef705 to
3e25b53
Compare
520ad55 to
1ef78fc
Compare
pkg/codegen/operations.go
Outdated
| parts := strings.SplitN(parentRef, "#", 2) | ||
| if parentRef != "" && len(parts) == 2 { | ||
| // TODO finish comment | ||
| // if a locally-defined, but `$ref`'d parent, then we need to make sure that we make this an external ref |
f8b232b to
55e3ce2
Compare
As noted in #1378, there are cases where a complex set of `$ref`s between multiple files can lead to broken generated code, which does not correctly import the package that has been prepared for the external reference. We can handle this by looking up any references, where there is a `.Ref` passed into the type, and then iterate through relevant children. This requires we handle the updating in-place for these by using a bit of pointer + indexing fun. This also adds a relevant test case to validate the fix. Closes #1378.
55e3ce2 to
0692acc
Compare
markuswustenberg
left a comment
There was a problem hiding this comment.
In my limited understanding of the internals of this project, LGTM. :D
| // ensureExternalRefsInRequestBodyDefinitions ensures that when an externalRef (`$ref` that points to a file that isn't the current spec) is encountered, we make sure we update our underlying `RefType` to make sure that we point to that type. | ||
| // This only happens if we have a non-empty `ref` passed in, and that `ref` isn't pointing to something in our file | ||
| // NOTE that the pointer here allows us to pass in a reference and edit in-place | ||
| func ensureExternalRefsInRequestBodyDefinitions(defs *[]RequestBodyDefinition, ref string) { |
There was a problem hiding this comment.
I think it would be easier to understand if the param was defs []*RequestBodyDefinition, since the underlying def could be changed directly in that case, and you wouldn't need the (*defs)[i] = rbd. Or is there something I'm missing?
There was a problem hiding this comment.
That's a fair shout.
I went for this solution, as I could just pass it in from operations.go:
ensureExternalRefsInRequestBodyDefinitions(&bodyDefinitions, pathItem.Ref)Whereas if I went with that solution, I'd need to create a new slice that had a pointer to each value within bodyDefinitions 🤔
As noted in #1378, there are cases where a complex set of
$refsbetween multiple files can lead to broken generated code, which does not
correctly import the package that has been prepared for the external
reference.
We can handle this by looking up any references, where there is a
.Refpassed into the type, and then iterate through relevant children.
This requires we handle the updating in-place for these by using a bit
of pointer + indexing fun.
This also adds a relevant test case to validate the fix.
Closes #1378.
Note that this won't fix every case - we'll review it in #1440