From 201c9c7a2ec52cb281df4e09cb8cffcc9a36a366 Mon Sep 17 00:00:00 2001 From: Brad Moylan Date: Wed, 1 Feb 2023 09:45:09 -0800 Subject: [PATCH] fix: Force import alias when package ends in /v[0-9]+$ (#409) --- changelog/@unreleased/pr-409.v2.yml | 5 ++ conjure/conjure.go | 11 +++- .../testgenerated/imports/imports.yml | 10 +++ .../testgenerated/imports/imports_test.go | 13 ---- .../imports/pkg3/api/unions.conjure.go | 64 ++++++++++++++++--- .../pkg3/api/unions_generics.conjure.go | 8 +++ .../imports/pkg4/v2/structs.conjure.go | 28 ++++++++ .../imports/pkg5/v2/structs.conjure.go | 28 ++++++++ 8 files changed, 145 insertions(+), 22 deletions(-) create mode 100644 changelog/@unreleased/pr-409.v2.yml delete mode 100644 integration_test/testgenerated/imports/imports_test.go create mode 100644 integration_test/testgenerated/imports/pkg4/v2/structs.conjure.go create mode 100644 integration_test/testgenerated/imports/pkg5/v2/structs.conjure.go diff --git a/changelog/@unreleased/pr-409.v2.yml b/changelog/@unreleased/pr-409.v2.yml new file mode 100644 index 00000000..48794353 --- /dev/null +++ b/changelog/@unreleased/pr-409.v2.yml @@ -0,0 +1,5 @@ +type: fix +fix: + description: Force import alias when package ends in /v[0-9]+$ + links: + - https://github.com/palantir/conjure-go/pull/409 diff --git a/conjure/conjure.go b/conjure/conjure.go index 3214a9c1..cf9fc707 100644 --- a/conjure/conjure.go +++ b/conjure/conjure.go @@ -16,6 +16,7 @@ package conjure import ( "path/filepath" + "regexp" "sort" "github.com/dave/jennifer/jen" @@ -118,7 +119,11 @@ func newJenFile(pkg types.ConjurePackage, def *types.ConjureDefinition) *jen.Fil f := jen.NewFilePathName(pkg.ImportPath, pkg.PackageName) f.ImportNames(snip.DefaultImportsToPackageNames) for _, conjurePackage := range def.Packages { - f.ImportName(conjurePackage.ImportPath, conjurePackage.PackageName) + if packageSuffixRequiresAlias(conjurePackage.ImportPath) { + f.ImportAlias(conjurePackage.ImportPath, conjurePackage.PackageName) + } else { + f.ImportName(conjurePackage.ImportPath, conjurePackage.PackageName) + } } return f } @@ -129,3 +134,7 @@ func newGoFile(filePath string, file *jen.File) *OutputFile { file: file, } } + +func packageSuffixRequiresAlias(importPath string) bool { + return regexp.MustCompile(`/v[0-9]+$`).MatchString(importPath) +} diff --git a/integration_test/testgenerated/imports/imports.yml b/integration_test/testgenerated/imports/imports.yml index f48295e1..240ad097 100644 --- a/integration_test/testgenerated/imports/imports.yml +++ b/integration_test/testgenerated/imports/imports.yml @@ -9,8 +9,18 @@ types: package: com.palantir.pkg2.api fields: data: Struct1 + ObjectInPackageEndingInVersion: + package: com.palantir.pkg4.v2 + fields: + name: string + DifferentPackageEndingInVersion: + package: com.palantir.pkg5.v2 + fields: + name: string Union: package: com.palantir.pkg3.api union: one: Struct1 two: Struct2 + three: ObjectInPackageEndingInVersion + four: DifferentPackageEndingInVersion diff --git a/integration_test/testgenerated/imports/imports_test.go b/integration_test/testgenerated/imports/imports_test.go deleted file mode 100644 index 1de11118..00000000 --- a/integration_test/testgenerated/imports/imports_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package imports - -import ( - "testing" - - "github.com/palantir/conjure-go/v6/integration_test/testgenerated/imports/pkg3/api" -) - -// TestImportNameConflict ensures that we can import a type which includes types of the same package name. -// This is only testing that the relevant code compiles, and does not do anything in the test body. -func TestImportNameConflict(t *testing.T) { - _ = api.Union{} -} diff --git a/integration_test/testgenerated/imports/pkg3/api/unions.conjure.go b/integration_test/testgenerated/imports/pkg3/api/unions.conjure.go index c855b064..3dfa3492 100644 --- a/integration_test/testgenerated/imports/pkg3/api/unions.conjure.go +++ b/integration_test/testgenerated/imports/pkg3/api/unions.conjure.go @@ -8,24 +8,30 @@ import ( "github.com/palantir/conjure-go/v6/integration_test/testgenerated/imports/pkg1/api" api1 "github.com/palantir/conjure-go/v6/integration_test/testgenerated/imports/pkg2/api" + v2 "github.com/palantir/conjure-go/v6/integration_test/testgenerated/imports/pkg4/v2" + v21 "github.com/palantir/conjure-go/v6/integration_test/testgenerated/imports/pkg5/v2" "github.com/palantir/pkg/safejson" "github.com/palantir/pkg/safeyaml" ) type Union struct { - typ string - one *api.Struct1 - two *api1.Struct2 + typ string + one *api.Struct1 + two *api1.Struct2 + three *v2.ObjectInPackageEndingInVersion + four *v21.DifferentPackageEndingInVersion } type unionDeserializer struct { - Type string `json:"type"` - One *api.Struct1 `json:"one"` - Two *api1.Struct2 `json:"two"` + Type string `json:"type"` + One *api.Struct1 `json:"one"` + Two *api1.Struct2 `json:"two"` + Three *v2.ObjectInPackageEndingInVersion `json:"three"` + Four *v21.DifferentPackageEndingInVersion `json:"four"` } func (u *unionDeserializer) toStruct() Union { - return Union{typ: u.Type, one: u.One, two: u.Two} + return Union{typ: u.Type, one: u.One, two: u.Two, three: u.Three, four: u.Four} } func (u *Union) toSerializer() (interface{}, error) { @@ -42,6 +48,16 @@ func (u *Union) toSerializer() (interface{}, error) { Type string `json:"type"` Two api1.Struct2 `json:"two"` }{Type: "two", Two: *u.two}, nil + case "three": + return struct { + Type string `json:"type"` + Three v2.ObjectInPackageEndingInVersion `json:"three"` + }{Type: "three", Three: *u.three}, nil + case "four": + return struct { + Type string `json:"type"` + Four v21.DifferentPackageEndingInVersion `json:"four"` + }{Type: "four", Four: *u.four}, nil } } @@ -78,7 +94,7 @@ func (u *Union) UnmarshalYAML(unmarshal func(interface{}) error) error { return safejson.Unmarshal(jsonBytes, *&u) } -func (u *Union) AcceptFuncs(oneFunc func(api.Struct1) error, twoFunc func(api1.Struct2) error, unknownFunc func(string) error) error { +func (u *Union) AcceptFuncs(oneFunc func(api.Struct1) error, twoFunc func(api1.Struct2) error, threeFunc func(v2.ObjectInPackageEndingInVersion) error, fourFunc func(v21.DifferentPackageEndingInVersion) error, unknownFunc func(string) error) error { switch u.typ { default: if u.typ == "" { @@ -89,6 +105,10 @@ func (u *Union) AcceptFuncs(oneFunc func(api.Struct1) error, twoFunc func(api1.S return oneFunc(*u.one) case "two": return twoFunc(*u.two) + case "three": + return threeFunc(*u.three) + case "four": + return fourFunc(*u.four) } } @@ -100,6 +120,14 @@ func (u *Union) TwoNoopSuccess(api1.Struct2) error { return nil } +func (u *Union) ThreeNoopSuccess(v2.ObjectInPackageEndingInVersion) error { + return nil +} + +func (u *Union) FourNoopSuccess(v21.DifferentPackageEndingInVersion) error { + return nil +} + func (u *Union) ErrorOnUnknown(typeName string) error { return fmt.Errorf("invalid value in union type. Type name: %s", typeName) } @@ -115,12 +143,18 @@ func (u *Union) Accept(v UnionVisitor) error { return v.VisitOne(*u.one) case "two": return v.VisitTwo(*u.two) + case "three": + return v.VisitThree(*u.three) + case "four": + return v.VisitFour(*u.four) } } type UnionVisitor interface { VisitOne(v api.Struct1) error VisitTwo(v api1.Struct2) error + VisitThree(v v2.ObjectInPackageEndingInVersion) error + VisitFour(v v21.DifferentPackageEndingInVersion) error VisitUnknown(typeName string) error } @@ -135,12 +169,18 @@ func (u *Union) AcceptWithContext(ctx context.Context, v UnionVisitorWithContext return v.VisitOneWithContext(ctx, *u.one) case "two": return v.VisitTwoWithContext(ctx, *u.two) + case "three": + return v.VisitThreeWithContext(ctx, *u.three) + case "four": + return v.VisitFourWithContext(ctx, *u.four) } } type UnionVisitorWithContext interface { VisitOneWithContext(ctx context.Context, v api.Struct1) error VisitTwoWithContext(ctx context.Context, v api1.Struct2) error + VisitThreeWithContext(ctx context.Context, v v2.ObjectInPackageEndingInVersion) error + VisitFourWithContext(ctx context.Context, v v21.DifferentPackageEndingInVersion) error VisitUnknownWithContext(ctx context.Context, typeName string) error } @@ -151,3 +191,11 @@ func NewUnionFromOne(v api.Struct1) Union { func NewUnionFromTwo(v api1.Struct2) Union { return Union{typ: "two", two: &v} } + +func NewUnionFromThree(v v2.ObjectInPackageEndingInVersion) Union { + return Union{typ: "three", three: &v} +} + +func NewUnionFromFour(v v21.DifferentPackageEndingInVersion) Union { + return Union{typ: "four", four: &v} +} diff --git a/integration_test/testgenerated/imports/pkg3/api/unions_generics.conjure.go b/integration_test/testgenerated/imports/pkg3/api/unions_generics.conjure.go index 28c64509..565670ab 100644 --- a/integration_test/testgenerated/imports/pkg3/api/unions_generics.conjure.go +++ b/integration_test/testgenerated/imports/pkg3/api/unions_generics.conjure.go @@ -10,6 +10,8 @@ import ( "github.com/palantir/conjure-go/v6/integration_test/testgenerated/imports/pkg1/api" api1 "github.com/palantir/conjure-go/v6/integration_test/testgenerated/imports/pkg2/api" + v2 "github.com/palantir/conjure-go/v6/integration_test/testgenerated/imports/pkg4/v2" + v21 "github.com/palantir/conjure-go/v6/integration_test/testgenerated/imports/pkg5/v2" ) type UnionWithT[T any] Union @@ -26,11 +28,17 @@ func (u *UnionWithT[T]) Accept(ctx context.Context, v UnionVisitorWithT[T]) (T, return v.VisitOne(ctx, *u.one) case "two": return v.VisitTwo(ctx, *u.two) + case "three": + return v.VisitThree(ctx, *u.three) + case "four": + return v.VisitFour(ctx, *u.four) } } type UnionVisitorWithT[T any] interface { VisitOne(ctx context.Context, v api.Struct1) (T, error) VisitTwo(ctx context.Context, v api1.Struct2) (T, error) + VisitThree(ctx context.Context, v v2.ObjectInPackageEndingInVersion) (T, error) + VisitFour(ctx context.Context, v v21.DifferentPackageEndingInVersion) (T, error) VisitUnknown(ctx context.Context, typ string) (T, error) } diff --git a/integration_test/testgenerated/imports/pkg4/v2/structs.conjure.go b/integration_test/testgenerated/imports/pkg4/v2/structs.conjure.go new file mode 100644 index 00000000..e52c8ccd --- /dev/null +++ b/integration_test/testgenerated/imports/pkg4/v2/structs.conjure.go @@ -0,0 +1,28 @@ +// This file was generated by Conjure and should not be manually edited. + +package v2 + +import ( + "github.com/palantir/pkg/safejson" + "github.com/palantir/pkg/safeyaml" +) + +type ObjectInPackageEndingInVersion struct { + Name string `json:"name"` +} + +func (o ObjectInPackageEndingInVersion) MarshalYAML() (interface{}, error) { + jsonBytes, err := safejson.Marshal(o) + if err != nil { + return nil, err + } + return safeyaml.JSONtoYAMLMapSlice(jsonBytes) +} + +func (o *ObjectInPackageEndingInVersion) UnmarshalYAML(unmarshal func(interface{}) error) error { + jsonBytes, err := safeyaml.UnmarshalerToJSONBytes(unmarshal) + if err != nil { + return err + } + return safejson.Unmarshal(jsonBytes, *&o) +} diff --git a/integration_test/testgenerated/imports/pkg5/v2/structs.conjure.go b/integration_test/testgenerated/imports/pkg5/v2/structs.conjure.go new file mode 100644 index 00000000..cf8a6154 --- /dev/null +++ b/integration_test/testgenerated/imports/pkg5/v2/structs.conjure.go @@ -0,0 +1,28 @@ +// This file was generated by Conjure and should not be manually edited. + +package v2 + +import ( + "github.com/palantir/pkg/safejson" + "github.com/palantir/pkg/safeyaml" +) + +type DifferentPackageEndingInVersion struct { + Name string `json:"name"` +} + +func (o DifferentPackageEndingInVersion) MarshalYAML() (interface{}, error) { + jsonBytes, err := safejson.Marshal(o) + if err != nil { + return nil, err + } + return safeyaml.JSONtoYAMLMapSlice(jsonBytes) +} + +func (o *DifferentPackageEndingInVersion) UnmarshalYAML(unmarshal func(interface{}) error) error { + jsonBytes, err := safeyaml.UnmarshalerToJSONBytes(unmarshal) + if err != nil { + return err + } + return safejson.Unmarshal(jsonBytes, *&o) +}