Skip to content

Fix: Ensure external refs are propagated to generated code #1389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 25, 2024

Conversation

jamietanna
Copy link
Member

@jamietanna jamietanna commented Dec 18, 2023

As noted in #1378, there are cases where a complex set of $refs
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.


Note that this won't fix every case - we'll review it in #1440

@jamietanna jamietanna force-pushed the feature/external-ref-strict branch from 71813ff to 520ad55 Compare December 18, 2023 12:33
@@ -817,6 +821,19 @@ func GenerateResponseDefinitions(operationID string, responses map[string]*opena
NameTag: tag,
Schema: contentSchema,
}

// TODO finish comment
Copy link
Member Author

Choose a reason for hiding this comment

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

TODO

// TODO finish comment
parts := strings.SplitN(parentRef, "#", 2)
if parentRef != "" && len(parts) == 2 {
// TODO finish comment
Copy link
Member Author

Choose a reason for hiding this comment

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

TODO

rcd.Schema = Schema{
RefType: fmt.Sprintf("%s.%s", pack.Name, contentSchema.GoType),
}
} // TODO log when not found
Copy link
Member Author

Choose a reason for hiding this comment

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

Not as part of this one

@jamietanna jamietanna force-pushed the feature/external-ref-1378 branch from e7cef18 to f4d7d4c Compare December 18, 2023 12:35
@markuswustenberg
Copy link

I'm getting the following error when trying this out:

error generating code: error formatting Go code <generated code here> filename.go:5746:70: expected 'IDENT', found 'struct' (and 7 more errors)

@jamietanna jamietanna force-pushed the feature/external-ref-1378 branch from 14ef705 to 3e25b53 Compare January 19, 2024 10:57
@jamietanna jamietanna force-pushed the feature/external-ref-strict branch from 520ad55 to 1ef78fc Compare January 19, 2024 10:57
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
Copy link
Member Author

Choose a reason for hiding this comment

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

rephrase

@jamietanna jamietanna force-pushed the feature/external-ref-1378 branch from f8b232b to 55e3ce2 Compare January 25, 2024 10:59
@jamietanna jamietanna changed the title Correctly reference externally defined types Fix: Ensure external refs are propagated to generated code Jan 25, 2024
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.
@jamietanna jamietanna force-pushed the feature/external-ref-1378 branch from 55e3ce2 to 0692acc Compare January 25, 2024 11:01
@jamietanna jamietanna marked this pull request as ready for review January 25, 2024 11:25
@jamietanna jamietanna changed the base branch from feature/external-ref-strict to master January 25, 2024 11:26
Copy link

@markuswustenberg markuswustenberg left a comment

Choose a reason for hiding this comment

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

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) {

Choose a reason for hiding this comment

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

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?

Copy link
Member Author

Choose a reason for hiding this comment

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

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 🤔

@jamietanna jamietanna merged commit ad5eada into master Jan 25, 2024
@jamietanna jamietanna added the bug Something isn't working label Jan 25, 2024
@jamietanna jamietanna deleted the feature/external-ref-1378 branch May 5, 2025 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Missing package name on type from common API spec when referencing a path operation from another spec in generated code
2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy