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
programgen(go): Handle conflicting names in imported packages #13289
Conversation
Current dependencies on/for this PR: This comment was auto-generated by Graphite. |
Changelog[uncommitted] (2023-07-25)Bug Fixes
|
@@ -1,13 +1,13 @@ | |||
package main | |||
|
|||
import ( | |||
"git.example.org/thirdparty/sdk/go/pkg" | |||
other "git.example.org/thirdparty/sdk/go/pkg" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: basename of import path doesn't match package name, so this makes sense
@@ -1,7 +1,7 @@ | |||
package main | |||
|
|||
import ( | |||
resourceProperties "git.example.org/pulumi-synthetic/resourceProperties" | |||
"git.example.org/pulumi-synthetic/resourceProperties" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
base name matches package name so named import not necessary
bors try |
tryBuild failed: |
Build is green. Only the merge failed (for obvious reasons). |
69b7263
to
200bb9f
Compare
200bb9f
to
0492ff9
Compare
pkg/codegen/go/gen_program.go
Outdated
candidate := strings.Join(parts[len(parts)-2:], "_") | ||
|
||
// Just in case, drop common non-identifier characters. | ||
// e.g., "foo-go" -> "foogo" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we not need to worry about a path like "go.dev/pkg" here? parts would be 2 ["go.dev", "pkg"] but "." isn't valid in the import name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think this logic is more fragile than I intended. I'll have it drop any non-identifier symbols and add some more unit tests.
pkg/codegen/go/gen_program.go
Outdated
} | ||
|
||
// The name is taken. We need a unique unused alias. | ||
// We prefer a simple "$mod_$name" (e.g. "aws_s3", "awsx_s3") for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the underscore is probably better here, but I'm cognisant that Go recommends no underscores in package names and I wonder if we should be trying to maintain that here? "awss3"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that sounds better, especially because this generated code is intended to be read and modified by users.
0492ff9
to
cb91c5b
Compare
Updated:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Adds a minimal reproduction of the duplicate import issues reported in #11176.
This fixes how programgen generates import statements to handle conflicting imports when two imported packages have the same name, e.g. github.com/pulumi/pulumi-aws/sdk/v5/go/aws/ecs github.com/pulumi/pulumi-awsx/sdk/go/awsx/ecs To do this, we add a fileImporter type that tracks these imports. It prefers unnamed imports for packages unless one of the following is true: - the name of the package has already been used by another import - the name of the package does not match the last component of the import path (e.g., `example.com/foo-go` with `package foo`). If the name has already been used by another import, it attempts the following in-order: - Combine the last two path components of the import path into an identifier and use that if available. e.g., `awsxs3` from `sdk/go/awsx/s3`. - Append a number to the package name and increment it until an unused name is found. e.g. `ecs2`, `ecs3`, and so on. There's a change in how this information is tracked as well. Previously, this was a pull approach: various calls returned programImports objects which all got merged together. This change switches to a push approach: as code is generated and imports are requested, they're submitted to the fileImporter which keeps track of them until the next `Reset()` call. The above also has a nice side effect of dropping a parameter. Another change worth explicitly calling out: Previously, getModOrAlias partially duplicated some of the logic implemented in getPulumiImport, and used `mod`, `originalMod` in a non-obvious way. This generated incorrect imports like the following (note the two `/aws` at the end): github.com/pulumi/pulumi-aws/sdk/v5/go/aws/aws This change replicates more of the logic of getPulumiImport (now called addPulumiImport) into this function, and addresses the discrepancy in codegen caused by `mod`/`originalMod`. The result leaves most existing code unchanged, except in a couple existing cases where the resulting changes make sense given the logic for named imports outlined above. Resolves #11176
cb91c5b
to
a24ad18
Compare
bors merge |
Build succeeded! The publicly hosted instance of bors-ng is deprecated and will go away soon. If you want to self-host your own instance, instructions are here. If you want to switch to GitHub's built-in merge queue, visit their help page. |
This fixes how programgen generates import statements
to handle conflicting imports when two imported packages
have the same name, e.g.
To do this, we add a fileImporter type that tracks these imports.
It prefers unnamed imports for packages unless one of the following is
true:
of the import path (e.g.,
example.com/foo-go
withpackage foo
).If the name has already been used by another import,
it attempts the following in-order:
into an identifier and use that if available.
e.g.,
awsxs3
fromsdk/go/awsx/s3
.until an unused name is found.
e.g.
ecs2
,ecs3
, and so on.There's a change in how this information is tracked as well.
Previously, this was a pull approach: various calls returned
programImports objects which all got merged together.
This change switches to a push approach:
as code is generated and imports are requested,
they're submitted to the fileImporter which keeps track of them
until the next
Reset()
call.The above also has a nice side effect of dropping a parameter.
Another change worth explicitly calling out:
Previously, getModOrAlias partially duplicated some of the logic
implemented in getPulumiImport, and used
mod
,originalMod
in a non-obvious way.
This generated incorrect imports like the following
(note the two
/aws
at the end):This change replicates more of the logic of getPulumiImport
(now called addPulumiImport) into this function,
and addresses the discrepancy in codegen caused by
mod
/originalMod
.The result leaves most existing code unchanged,
except in a couple existing cases where the resulting changes make sense
given the logic for named imports outlined above.
Resolves #11176