Skip to content

Commit

Permalink
code-gen: allow overlapping prefixes in GroupNames
Browse files Browse the repository at this point in the history
  • Loading branch information
sttts committed Nov 6, 2017
1 parent 2106265 commit a62e631
Show file tree
Hide file tree
Showing 18 changed files with 206 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ func (s *gvPackagesValue) set(vs []string) error {
seenGroups[gv.Group].Versions = append(group.Versions, gv.Version)
} else {
seenGroups[gv.Group] = &types.GroupVersions{
Group: gv.Group,
Versions: []types.Version{gv.Version},
PackageName: gv.Group.NonEmpty(),
Group: gv.Group,
Versions: []types.Version{gv.Version},
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ func TestGVPackageFlag(t *testing.T) {
{Group: "foo", Version: "v1"}: "foo/v1",
},
expectedGroups: []types.GroupVersions{
{Group: types.Group("bar"), Versions: []types.Version{types.Version("v1"), types.Version("v2"), types.Version("")}},
{Group: types.Group("foo"), Versions: []types.Version{types.Version("v1")}},
{PackageName: "bar", Group: types.Group("bar"), Versions: []types.Version{types.Version("v1"), types.Version("v2"), types.Version("")}},
{PackageName: "foo", Group: types.Group("foo"), Versions: []types.Version{types.Version("v1")}},
},
},
{
Expand All @@ -63,8 +63,8 @@ func TestGVPackageFlag(t *testing.T) {
{Group: "foo", Version: "v1"}: "foo/v1",
},
expectedGroups: []types.GroupVersions{
{Group: types.Group("bar"), Versions: []types.Version{types.Version("v1"), types.Version("v2"), types.Version("")}},
{Group: types.Group("foo"), Versions: []types.Version{types.Version("v1")}},
{PackageName: "bar", Group: types.Group("bar"), Versions: []types.Version{types.Version("v1"), types.Version("v2"), types.Version("")}},
{PackageName: "foo", Group: types.Group("foo"), Versions: []types.Version{types.Version("v1")}},
},
},
{
Expand All @@ -74,7 +74,7 @@ func TestGVPackageFlag(t *testing.T) {
{Group: "api", Version: ""}: "../api",
},
expectedGroups: []types.GroupVersions{
{Group: types.Group("api"), Versions: []types.Version{types.Version("v1"), types.Version("")}},
{PackageName: "core", Group: types.Group("api"), Versions: []types.Version{types.Version("v1"), types.Version("")}},
},
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ func DefaultNameSystem() string {
return "public"
}

func packageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetPackage string, apiPath string, srcTreePath string, inputPackage string, boilerplate []byte) generator.Package {
groupVersionClientPackage := strings.ToLower(filepath.Join(clientsetPackage, "typed", gv.Group.NonEmpty(), gv.Version.NonEmpty()))
func packageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetPackage string, groupPackageName string, groupGoName string, apiPath string, srcTreePath string, inputPackage string, boilerplate []byte) generator.Package {
groupVersionClientPackage := strings.ToLower(filepath.Join(clientsetPackage, "typed", groupPackageName, gv.Version.NonEmpty()))
return &generator.DefaultPackage{
PackageName: strings.ToLower(gv.Version.NonEmpty()),
PackagePath: groupVersionClientPackage,
Expand All @@ -130,20 +130,22 @@ func packageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, cli
clientsetPackage: clientsetPackage,
group: gv.Group.NonEmpty(),
version: gv.Version.String(),
groupGoName: groupGoName,
typeToMatch: t,
imports: generator.NewImportTracker(),
})
}

generators = append(generators, &genGroup{
DefaultGen: generator.DefaultGen{
OptionalName: gv.Group.NonEmpty() + "_client",
OptionalName: groupPackageName + "_client",
},
outputPackage: groupVersionClientPackage,
inputPackage: inputPackage,
clientsetPackage: clientsetPackage,
group: gv.Group.NonEmpty(),
version: gv.Version.String(),
groupGoName: groupGoName,
apiPath: apiPath,
types: typeList,
imports: generator.NewImportTracker(),
Expand All @@ -166,7 +168,7 @@ func packageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, cli
}
}

func packageForClientset(customArgs *clientgenargs.CustomArgs, clientsetPackage string, boilerplate []byte) generator.Package {
func packageForClientset(customArgs *clientgenargs.CustomArgs, clientsetPackage string, groupGoNames map[clientgentypes.GroupVersion]string, boilerplate []byte) generator.Package {
return &generator.DefaultPackage{
PackageName: customArgs.ClientsetName,
PackagePath: clientsetPackage,
Expand All @@ -186,6 +188,7 @@ func packageForClientset(customArgs *clientgenargs.CustomArgs, clientsetPackage
OptionalName: "clientset",
},
groups: customArgs.Groups,
groupGoNames: groupGoNames,
clientsetPackage: clientsetPackage,
outputPackage: customArgs.ClientsetName,
imports: generator.NewImportTracker(),
Expand Down Expand Up @@ -245,14 +248,16 @@ NextGroup:
// applyGroupOverrides applies group name overrides to each package, if applicable. If there is a
// comment of the form "// +groupName=somegroup" or "// +groupName=somegroup.foo.bar.io", use the
// first field (somegroup) as the name of the group when generating.
//
// If the first field of the groupName is not unique within the clientset, use "// +groupName=unique
func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.CustomArgs) {
// Create a map from "old GV" to "new GV" so we know what changes we need to make.
changes := make(map[clientgentypes.GroupVersion]clientgentypes.GroupVersion)
for gv, inputDir := range customArgs.GroupVersionToInputPath {
p := universe.Package(inputDir)
if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil {
newGV := clientgentypes.GroupVersion{
Group: clientgentypes.Group(strings.SplitN(override[0], ".", 2)[0]),
Group: clientgentypes.Group(override[0]),
Version: gv.Version,
}
changes[gv] = newGV
Expand All @@ -269,8 +274,9 @@ func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.Cust
if newGV, ok := changes[gv]; ok {
// There's an override, so use it.
newGVS := clientgentypes.GroupVersions{
Group: newGV.Group,
Versions: gvs.Versions,
PackageName: gv.Group.NonEmpty(),
Group: newGV.Group,
Versions: gvs.Versions,
}
newGroups = append(newGroups, newGVS)
} else {
Expand Down Expand Up @@ -310,9 +316,18 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
applyGroupOverrides(context.Universe, customArgs)

gvToTypes := map[clientgentypes.GroupVersion][]*types.Type{}
groupGoNames := make(map[clientgentypes.GroupVersion]string)
for gv, inputDir := range customArgs.GroupVersionToInputPath {
// Package are indexed with the vendor prefix stripped
p := context.Universe.Package(path.Vendorless(inputDir))

// If there's a comment of the form "// +groupGoName=SomeUniqueShortName", use that as
// the Go group identifier in CamelCase. It defaults
groupGoNames[gv] = namer.IC(strings.Split(gv.Group.NonEmpty(), ".")[0])
if override := types.ExtractCommentTags("+", p.Comments)["groupGoName"]; override != nil {
groupGoNames[gv] = namer.IC(override[0])
}

// Package are indexed with the vendor prefix stripped
for n, t := range p.Types {
// filter out types which are not included in user specified overrides.
typesOverride, ok := includedTypesOverrides[gv]
Expand Down Expand Up @@ -344,10 +359,10 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
var packageList []generator.Package
clientsetPackage := filepath.Join(customArgs.ClientsetOutputPath, customArgs.ClientsetName)

packageList = append(packageList, packageForClientset(customArgs, clientsetPackage, boilerplate))
packageList = append(packageList, packageForClientset(customArgs, clientsetPackage, groupGoNames, boilerplate))
packageList = append(packageList, packageForScheme(customArgs, clientsetPackage, arguments.OutputBase, boilerplate))
if customArgs.FakeClient {
packageList = append(packageList, fake.PackageForClientset(customArgs, clientsetPackage, boilerplate))
packageList = append(packageList, fake.PackageForClientset(customArgs, clientsetPackage, groupGoNames, boilerplate))
}

// If --clientset-only=true, we don't regenerate the individual typed clients.
Expand All @@ -361,9 +376,9 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
gv := clientgentypes.GroupVersion{Group: group.Group, Version: version}
types := gvToTypes[gv]
inputPath := customArgs.GroupVersionToInputPath[gv]
packageList = append(packageList, packageForGroup(gv, orderer.OrderTypes(types), clientsetPackage, customArgs.ClientsetAPIPath, arguments.OutputBase, inputPath, boilerplate))
packageList = append(packageList, packageForGroup(gv, orderer.OrderTypes(types), clientsetPackage, group.PackageName, groupGoNames[gv], customArgs.ClientsetAPIPath, arguments.OutputBase, inputPath, boilerplate))
if customArgs.FakeClient {
packageList = append(packageList, fake.PackageForGroup(gv, orderer.OrderTypes(types), clientsetPackage, inputPath, boilerplate))
packageList = append(packageList, fake.PackageForGroup(gv, orderer.OrderTypes(types), clientsetPackage, group.PackageName, groupGoNames[gv], inputPath, boilerplate))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ import (
clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
)

func PackageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetPackage string, inputPackage string, boilerplate []byte) generator.Package {
outputPackage := strings.ToLower(filepath.Join(clientsetPackage, "typed", gv.Group.NonEmpty(), gv.Version.NonEmpty(), "fake"))
func PackageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetPackage string, groupPackageName string, groupGoName string, inputPackage string, boilerplate []byte) generator.Package {
outputPackage := strings.ToLower(filepath.Join(clientsetPackage, "typed", groupPackageName, gv.Version.NonEmpty(), "fake"))
// TODO: should make this a function, called by here and in client-generator.go
realClientPackage := filepath.Join(clientsetPackage, "typed", gv.Group.NonEmpty(), gv.Version.NonEmpty())
realClientPackage := filepath.Join(clientsetPackage, "typed", groupPackageName, gv.Version.NonEmpty())
return &generator.DefaultPackage{
PackageName: "fake",
PackagePath: outputPackage,
Expand All @@ -58,19 +58,21 @@ func PackageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, cli
inputPackage: inputPackage,
group: gv.Group.NonEmpty(),
version: gv.Version.String(),
groupGoName: groupGoName,
typeToMatch: t,
imports: generator.NewImportTracker(),
})
}

generators = append(generators, &genFakeForGroup{
DefaultGen: generator.DefaultGen{
OptionalName: "fake_" + gv.Group.NonEmpty() + "_client",
OptionalName: "fake_" + groupPackageName + "_client",
},
outputPackage: outputPackage,
realClientPackage: realClientPackage,
group: gv.Group.NonEmpty(),
version: gv.Version.String(),
groupGoName: groupGoName,
types: typeList,
imports: generator.NewImportTracker(),
})
Expand All @@ -82,7 +84,7 @@ func PackageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, cli
}
}

func PackageForClientset(customArgs *clientgenargs.CustomArgs, fakeClientsetPackage string, boilerplate []byte) generator.Package {
func PackageForClientset(customArgs *clientgenargs.CustomArgs, fakeClientsetPackage string, groupGoNames map[clientgentypes.GroupVersion]string, boilerplate []byte) generator.Package {
return &generator.DefaultPackage{
// TODO: we'll generate fake clientset for different release in the future.
// Package name and path are hard coded for now.
Expand All @@ -104,6 +106,7 @@ func PackageForClientset(customArgs *clientgenargs.CustomArgs, fakeClientsetPack
OptionalName: "clientset_generated",
},
groups: customArgs.Groups,
groupGoNames: groupGoNames,
fakeClientsetPackage: fakeClientsetPackage,
outputPackage: "fake",
imports: generator.NewImportTracker(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
type genClientset struct {
generator.DefaultGen
groups []clientgentypes.GroupVersions
groupGoNames map[clientgentypes.GroupVersion]string
fakeClientsetPackage string
outputPackage string
imports namer.ImportTracker
Expand Down Expand Up @@ -59,11 +60,11 @@ func (g *genClientset) Imports(c *generator.Context) (imports []string) {
imports = append(imports, g.imports.ImportLines()...)
for _, group := range g.groups {
for _, version := range group.Versions {
groupClientPackage := filepath.Join(g.fakeClientsetPackage, "typed", group.Group.NonEmpty(), version.NonEmpty())
groupClientPackage := filepath.Join(g.fakeClientsetPackage, "typed", group.PackageName, version.NonEmpty())
fakeGroupClientPackage := filepath.Join(groupClientPackage, "fake")

imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", group.Group.NonEmpty(), version.NonEmpty(), groupClientPackage)))
imports = append(imports, strings.ToLower(fmt.Sprintf("fake%s%s \"%s\"", group.Group.NonEmpty(), version.NonEmpty(), fakeGroupClientPackage)))
imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", group.PackageName, version.NonEmpty(), groupClientPackage)))
imports = append(imports, strings.ToLower(fmt.Sprintf("fake%s%s \"%s\"", group.PackageName, version.NonEmpty(), fakeGroupClientPackage)))
}
}
// the package that has the clientset Interface
Expand All @@ -85,16 +86,24 @@ func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Wr
// perhaps we can adapt the go2ild framework to this kind of usage.
sw := generator.NewSnippetWriter(w, c, "$", "$")

allGroups := clientgentypes.ToGroupVersionPackages(g.groups)
allGroups := clientgentypes.ToGroupVersionPackages(g.groups, g.groupGoNames)

sw.Do(common, nil)
sw.Do(checkImpl, nil)

for _, g := range allGroups {
sw.Do(clientsetInterfaceImplTemplate, g)
for _, group := range allGroups {
m := map[string]interface{}{
"group": group.Group,
"version": group.Version,
"PackageName": group.PackageName,
"GroupGoName": group.GroupGoName,
"Version": namer.IC(group.Version.String()),
}

sw.Do(clientsetInterfaceImplTemplate, m)
// don't generated the default method if generating internalversion clientset
if g.IsDefaultVersion && g.Version != "" {
sw.Do(clientsetInterfaceDefaultVersionImpl, g)
if group.IsDefaultVersion && group.Version != "" {
sw.Do(clientsetInterfaceDefaultVersionImpl, m)
}
}

Expand Down Expand Up @@ -140,15 +149,15 @@ var _ clientset.Interface = &Clientset{}
`

var clientsetInterfaceImplTemplate = `
// $.GroupVersion$ retrieves the $.GroupVersion$Client
func (c *Clientset) $.GroupVersion$() $.PackageName$.$.GroupVersion$Interface {
return &fake$.PackageName$.Fake$.GroupVersion${Fake: &c.Fake}
// $.GroupGoName$$.Version$ retrieves the $.GroupGoName$$.Version$Client
func (c *Clientset) $.GroupGoName$$.Version$() $.PackageName$.$.GroupGoName$$.Version$Interface {
return &fake$.PackageName$.Fake$.GroupGoName$$.Version${Fake: &c.Fake}
}
`

var clientsetInterfaceDefaultVersionImpl = `
// $.Group$ retrieves the $.GroupVersion$Client
func (c *Clientset) $.Group$() $.PackageName$.$.GroupVersion$Interface {
return &fake$.PackageName$.Fake$.GroupVersion${Fake: &c.Fake}
// $.GroupGoName$ retrieves the $.GroupGoName$$.Version$Client
func (c *Clientset) $.GroupGoName$() $.PackageName$.$.GroupGoName$$.Version$Interface {
return &fake$.PackageName$.Fake$.GroupGoName$$.Version${Fake: &c.Fake}
}
`
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type genFakeForGroup struct {
realClientPackage string
group string
version string
groupGoName string
// types in this group
types []*types.Type
imports namer.ImportTracker
Expand Down Expand Up @@ -63,8 +64,8 @@ func (g *genFakeForGroup) GenerateType(c *generator.Context, t *types.Type, w io
sw := generator.NewSnippetWriter(w, c, "$", "$")

m := map[string]interface{}{
"group": g.group,
"GroupVersion": namer.IC(g.group) + namer.IC(g.version),
"GroupGoName": g.groupGoName,
"Version": namer.IC(g.version),
"Fake": c.Universe.Type(types.Name{Package: "k8s.io/client-go/testing", Name: "Fake"}),
"RESTClientInterface": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Interface"}),
"RESTClient": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "RESTClient"}),
Expand All @@ -78,7 +79,8 @@ func (g *genFakeForGroup) GenerateType(c *generator.Context, t *types.Type, w io
}
wrapper := map[string]interface{}{
"type": t,
"GroupVersion": namer.IC(g.group) + namer.IC(g.version),
"GroupGoName": g.groupGoName,
"Version": namer.IC(g.version),
"realClientPackage": strings.ToLower(filepath.Base(g.realClientPackage)),
}
if tags.NonNamespaced {
Expand All @@ -92,27 +94,27 @@ func (g *genFakeForGroup) GenerateType(c *generator.Context, t *types.Type, w io
}

var groupClientTemplate = `
type Fake$.GroupVersion$ struct {
type Fake$.GroupGoName$$.Version$ struct {
*$.Fake|raw$
}
`

var getterImplNamespaced = `
func (c *Fake$.GroupVersion$) $.type|publicPlural$(namespace string) $.realClientPackage$.$.type|public$Interface {
func (c *Fake$.GroupGoName$$.Version$) $.type|publicPlural$(namespace string) $.realClientPackage$.$.type|public$Interface {
return &Fake$.type|publicPlural${c, namespace}
}
`

var getterImplNonNamespaced = `
func (c *Fake$.GroupVersion$) $.type|publicPlural$() $.realClientPackage$.$.type|public$Interface {
func (c *Fake$.GroupGoName$$.Version$) $.type|publicPlural$() $.realClientPackage$.$.type|public$Interface {
return &Fake$.type|publicPlural${c}
}
`

var getRESTClient = `
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *Fake$.GroupVersion$) RESTClient() $.RESTClientInterface|raw$ {
func (c *Fake$.GroupGoName$$.Version$) RESTClient() $.RESTClientInterface|raw$ {
var ret *$.RESTClient|raw$
return ret
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type genFakeForType struct {
outputPackage string
group string
version string
groupGoName string
inputPackage string
typeToMatch *types.Type
imports namer.ImportTracker
Expand Down Expand Up @@ -116,7 +117,8 @@ func (g *genFakeForType) GenerateType(c *generator.Context, t *types.Type, w io.
"Package": namer.IC(pkg),
"namespaced": !tags.NonNamespaced,
"Group": namer.IC(g.group),
"GroupVersion": namer.IC(g.group) + namer.IC(g.version),
"GroupGoName": g.groupGoName,
"Version": namer.IC(g.version),
"group": canonicalGroup,
"groupName": groupName,
"version": g.version,
Expand Down Expand Up @@ -286,7 +288,7 @@ func adjustTemplate(name, verbType, template string) string {
var structNamespaced = `
// Fake$.type|publicPlural$ implements $.type|public$Interface
type Fake$.type|publicPlural$ struct {
Fake *Fake$.GroupVersion$
Fake *Fake$.GroupGoName$$.Version$
ns string
}
`
Expand All @@ -295,7 +297,7 @@ type Fake$.type|publicPlural$ struct {
var structNonNamespaced = `
// Fake$.type|publicPlural$ implements $.type|public$Interface
type Fake$.type|publicPlural$ struct {
Fake *Fake$.GroupVersion$
Fake *Fake$.GroupGoName$$.Version$
}
`

Expand Down
Loading

0 comments on commit a62e631

Please sign in to comment.