code-gen: allow overlapping prefixes in GroupNames

This commit is contained in:
Dr. Stefan Schimanski 2017-11-01 18:33:37 +01:00
parent 210626577b
commit a62e6310cb
18 changed files with 206 additions and 149 deletions

View File

@ -91,8 +91,9 @@ func (s *gvPackagesValue) set(vs []string) error {
seenGroups[gv.Group].Versions = append(group.Versions, gv.Version) seenGroups[gv.Group].Versions = append(group.Versions, gv.Version)
} else { } else {
seenGroups[gv.Group] = &types.GroupVersions{ seenGroups[gv.Group] = &types.GroupVersions{
Group: gv.Group, PackageName: gv.Group.NonEmpty(),
Versions: []types.Version{gv.Version}, Group: gv.Group,
Versions: []types.Version{gv.Version},
} }
} }

View File

@ -49,8 +49,8 @@ func TestGVPackageFlag(t *testing.T) {
{Group: "foo", Version: "v1"}: "foo/v1", {Group: "foo", Version: "v1"}: "foo/v1",
}, },
expectedGroups: []types.GroupVersions{ expectedGroups: []types.GroupVersions{
{Group: types.Group("bar"), Versions: []types.Version{types.Version("v1"), types.Version("v2"), types.Version("")}}, {PackageName: "bar", 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: "foo", Group: types.Group("foo"), Versions: []types.Version{types.Version("v1")}},
}, },
}, },
{ {
@ -63,8 +63,8 @@ func TestGVPackageFlag(t *testing.T) {
{Group: "foo", Version: "v1"}: "foo/v1", {Group: "foo", Version: "v1"}: "foo/v1",
}, },
expectedGroups: []types.GroupVersions{ expectedGroups: []types.GroupVersions{
{Group: types.Group("bar"), Versions: []types.Version{types.Version("v1"), types.Version("v2"), types.Version("")}}, {PackageName: "bar", 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: "foo", Group: types.Group("foo"), Versions: []types.Version{types.Version("v1")}},
}, },
}, },
{ {
@ -74,7 +74,7 @@ func TestGVPackageFlag(t *testing.T) {
{Group: "api", Version: ""}: "../api", {Group: "api", Version: ""}: "../api",
}, },
expectedGroups: []types.GroupVersions{ 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("")}},
}, },
}, },
} }

View File

@ -103,8 +103,8 @@ func DefaultNameSystem() string {
return "public" return "public"
} }
func packageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetPackage string, apiPath string, srcTreePath string, inputPackage string, boilerplate []byte) generator.Package { 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", gv.Group.NonEmpty(), gv.Version.NonEmpty())) groupVersionClientPackage := strings.ToLower(filepath.Join(clientsetPackage, "typed", groupPackageName, gv.Version.NonEmpty()))
return &generator.DefaultPackage{ return &generator.DefaultPackage{
PackageName: strings.ToLower(gv.Version.NonEmpty()), PackageName: strings.ToLower(gv.Version.NonEmpty()),
PackagePath: groupVersionClientPackage, PackagePath: groupVersionClientPackage,
@ -130,6 +130,7 @@ func packageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, cli
clientsetPackage: clientsetPackage, clientsetPackage: clientsetPackage,
group: gv.Group.NonEmpty(), group: gv.Group.NonEmpty(),
version: gv.Version.String(), version: gv.Version.String(),
groupGoName: groupGoName,
typeToMatch: t, typeToMatch: t,
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
}) })
@ -137,13 +138,14 @@ func packageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, cli
generators = append(generators, &genGroup{ generators = append(generators, &genGroup{
DefaultGen: generator.DefaultGen{ DefaultGen: generator.DefaultGen{
OptionalName: gv.Group.NonEmpty() + "_client", OptionalName: groupPackageName + "_client",
}, },
outputPackage: groupVersionClientPackage, outputPackage: groupVersionClientPackage,
inputPackage: inputPackage, inputPackage: inputPackage,
clientsetPackage: clientsetPackage, clientsetPackage: clientsetPackage,
group: gv.Group.NonEmpty(), group: gv.Group.NonEmpty(),
version: gv.Version.String(), version: gv.Version.String(),
groupGoName: groupGoName,
apiPath: apiPath, apiPath: apiPath,
types: typeList, types: typeList,
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
@ -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{ return &generator.DefaultPackage{
PackageName: customArgs.ClientsetName, PackageName: customArgs.ClientsetName,
PackagePath: clientsetPackage, PackagePath: clientsetPackage,
@ -186,6 +188,7 @@ func packageForClientset(customArgs *clientgenargs.CustomArgs, clientsetPackage
OptionalName: "clientset", OptionalName: "clientset",
}, },
groups: customArgs.Groups, groups: customArgs.Groups,
groupGoNames: groupGoNames,
clientsetPackage: clientsetPackage, clientsetPackage: clientsetPackage,
outputPackage: customArgs.ClientsetName, outputPackage: customArgs.ClientsetName,
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
@ -245,6 +248,8 @@ NextGroup:
// applyGroupOverrides applies group name overrides to each package, if applicable. If there is a // 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 // 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. // 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) { 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. // 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) changes := make(map[clientgentypes.GroupVersion]clientgentypes.GroupVersion)
@ -252,7 +257,7 @@ func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.Cust
p := universe.Package(inputDir) p := universe.Package(inputDir)
if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil {
newGV := clientgentypes.GroupVersion{ newGV := clientgentypes.GroupVersion{
Group: clientgentypes.Group(strings.SplitN(override[0], ".", 2)[0]), Group: clientgentypes.Group(override[0]),
Version: gv.Version, Version: gv.Version,
} }
changes[gv] = newGV changes[gv] = newGV
@ -269,8 +274,9 @@ func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.Cust
if newGV, ok := changes[gv]; ok { if newGV, ok := changes[gv]; ok {
// There's an override, so use it. // There's an override, so use it.
newGVS := clientgentypes.GroupVersions{ newGVS := clientgentypes.GroupVersions{
Group: newGV.Group, PackageName: gv.Group.NonEmpty(),
Versions: gvs.Versions, Group: newGV.Group,
Versions: gvs.Versions,
} }
newGroups = append(newGroups, newGVS) newGroups = append(newGroups, newGVS)
} else { } else {
@ -310,9 +316,18 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
applyGroupOverrides(context.Universe, customArgs) applyGroupOverrides(context.Universe, customArgs)
gvToTypes := map[clientgentypes.GroupVersion][]*types.Type{} gvToTypes := map[clientgentypes.GroupVersion][]*types.Type{}
groupGoNames := make(map[clientgentypes.GroupVersion]string)
for gv, inputDir := range customArgs.GroupVersionToInputPath { for gv, inputDir := range customArgs.GroupVersionToInputPath {
// Package are indexed with the vendor prefix stripped
p := context.Universe.Package(path.Vendorless(inputDir)) 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 { for n, t := range p.Types {
// filter out types which are not included in user specified overrides. // filter out types which are not included in user specified overrides.
typesOverride, ok := includedTypesOverrides[gv] typesOverride, ok := includedTypesOverrides[gv]
@ -344,10 +359,10 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
var packageList []generator.Package var packageList []generator.Package
clientsetPackage := filepath.Join(customArgs.ClientsetOutputPath, customArgs.ClientsetName) 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)) packageList = append(packageList, packageForScheme(customArgs, clientsetPackage, arguments.OutputBase, boilerplate))
if customArgs.FakeClient { 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. // If --clientset-only=true, we don't regenerate the individual typed clients.
@ -361,9 +376,9 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
gv := clientgentypes.GroupVersion{Group: group.Group, Version: version} gv := clientgentypes.GroupVersion{Group: group.Group, Version: version}
types := gvToTypes[gv] types := gvToTypes[gv]
inputPath := customArgs.GroupVersionToInputPath[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 { 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))
} }
} }
} }

View File

@ -29,10 +29,10 @@ import (
clientgentypes "k8s.io/code-generator/cmd/client-gen/types" 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 { 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", gv.Group.NonEmpty(), gv.Version.NonEmpty(), "fake")) 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 // 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{ return &generator.DefaultPackage{
PackageName: "fake", PackageName: "fake",
PackagePath: outputPackage, PackagePath: outputPackage,
@ -58,6 +58,7 @@ func PackageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, cli
inputPackage: inputPackage, inputPackage: inputPackage,
group: gv.Group.NonEmpty(), group: gv.Group.NonEmpty(),
version: gv.Version.String(), version: gv.Version.String(),
groupGoName: groupGoName,
typeToMatch: t, typeToMatch: t,
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
}) })
@ -65,12 +66,13 @@ func PackageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, cli
generators = append(generators, &genFakeForGroup{ generators = append(generators, &genFakeForGroup{
DefaultGen: generator.DefaultGen{ DefaultGen: generator.DefaultGen{
OptionalName: "fake_" + gv.Group.NonEmpty() + "_client", OptionalName: "fake_" + groupPackageName + "_client",
}, },
outputPackage: outputPackage, outputPackage: outputPackage,
realClientPackage: realClientPackage, realClientPackage: realClientPackage,
group: gv.Group.NonEmpty(), group: gv.Group.NonEmpty(),
version: gv.Version.String(), version: gv.Version.String(),
groupGoName: groupGoName,
types: typeList, types: typeList,
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
}) })
@ -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{ return &generator.DefaultPackage{
// TODO: we'll generate fake clientset for different release in the future. // TODO: we'll generate fake clientset for different release in the future.
// Package name and path are hard coded for now. // Package name and path are hard coded for now.
@ -104,6 +106,7 @@ func PackageForClientset(customArgs *clientgenargs.CustomArgs, fakeClientsetPack
OptionalName: "clientset_generated", OptionalName: "clientset_generated",
}, },
groups: customArgs.Groups, groups: customArgs.Groups,
groupGoNames: groupGoNames,
fakeClientsetPackage: fakeClientsetPackage, fakeClientsetPackage: fakeClientsetPackage,
outputPackage: "fake", outputPackage: "fake",
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),

View File

@ -32,6 +32,7 @@ import (
type genClientset struct { type genClientset struct {
generator.DefaultGen generator.DefaultGen
groups []clientgentypes.GroupVersions groups []clientgentypes.GroupVersions
groupGoNames map[clientgentypes.GroupVersion]string
fakeClientsetPackage string fakeClientsetPackage string
outputPackage string outputPackage string
imports namer.ImportTracker imports namer.ImportTracker
@ -59,11 +60,11 @@ func (g *genClientset) Imports(c *generator.Context) (imports []string) {
imports = append(imports, g.imports.ImportLines()...) imports = append(imports, g.imports.ImportLines()...)
for _, group := range g.groups { for _, group := range g.groups {
for _, version := range group.Versions { 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") 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("%s%s \"%s\"", group.PackageName, 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("fake%s%s \"%s\"", group.PackageName, version.NonEmpty(), fakeGroupClientPackage)))
} }
} }
// the package that has the clientset Interface // the package that has the clientset Interface
@ -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. // perhaps we can adapt the go2ild framework to this kind of usage.
sw := generator.NewSnippetWriter(w, c, "$", "$") sw := generator.NewSnippetWriter(w, c, "$", "$")
allGroups := clientgentypes.ToGroupVersionPackages(g.groups) allGroups := clientgentypes.ToGroupVersionPackages(g.groups, g.groupGoNames)
sw.Do(common, nil) sw.Do(common, nil)
sw.Do(checkImpl, nil) sw.Do(checkImpl, nil)
for _, g := range allGroups { for _, group := range allGroups {
sw.Do(clientsetInterfaceImplTemplate, g) 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 // don't generated the default method if generating internalversion clientset
if g.IsDefaultVersion && g.Version != "" { if group.IsDefaultVersion && group.Version != "" {
sw.Do(clientsetInterfaceDefaultVersionImpl, g) sw.Do(clientsetInterfaceDefaultVersionImpl, m)
} }
} }
@ -140,15 +149,15 @@ var _ clientset.Interface = &Clientset{}
` `
var clientsetInterfaceImplTemplate = ` var clientsetInterfaceImplTemplate = `
// $.GroupVersion$ retrieves the $.GroupVersion$Client // $.GroupGoName$$.Version$ retrieves the $.GroupGoName$$.Version$Client
func (c *Clientset) $.GroupVersion$() $.PackageName$.$.GroupVersion$Interface { func (c *Clientset) $.GroupGoName$$.Version$() $.PackageName$.$.GroupGoName$$.Version$Interface {
return &fake$.PackageName$.Fake$.GroupVersion${Fake: &c.Fake} return &fake$.PackageName$.Fake$.GroupGoName$$.Version${Fake: &c.Fake}
} }
` `
var clientsetInterfaceDefaultVersionImpl = ` var clientsetInterfaceDefaultVersionImpl = `
// $.Group$ retrieves the $.GroupVersion$Client // $.GroupGoName$ retrieves the $.GroupGoName$$.Version$Client
func (c *Clientset) $.Group$() $.PackageName$.$.GroupVersion$Interface { func (c *Clientset) $.GroupGoName$() $.PackageName$.$.GroupGoName$$.Version$Interface {
return &fake$.PackageName$.Fake$.GroupVersion${Fake: &c.Fake} return &fake$.PackageName$.Fake$.GroupGoName$$.Version${Fake: &c.Fake}
} }
` `

View File

@ -36,6 +36,7 @@ type genFakeForGroup struct {
realClientPackage string realClientPackage string
group string group string
version string version string
groupGoName string
// types in this group // types in this group
types []*types.Type types []*types.Type
imports namer.ImportTracker imports namer.ImportTracker
@ -63,8 +64,8 @@ func (g *genFakeForGroup) GenerateType(c *generator.Context, t *types.Type, w io
sw := generator.NewSnippetWriter(w, c, "$", "$") sw := generator.NewSnippetWriter(w, c, "$", "$")
m := map[string]interface{}{ m := map[string]interface{}{
"group": g.group, "GroupGoName": g.groupGoName,
"GroupVersion": namer.IC(g.group) + namer.IC(g.version), "Version": namer.IC(g.version),
"Fake": c.Universe.Type(types.Name{Package: "k8s.io/client-go/testing", Name: "Fake"}), "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"}), "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"}), "RESTClient": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "RESTClient"}),
@ -78,7 +79,8 @@ func (g *genFakeForGroup) GenerateType(c *generator.Context, t *types.Type, w io
} }
wrapper := map[string]interface{}{ wrapper := map[string]interface{}{
"type": t, "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)), "realClientPackage": strings.ToLower(filepath.Base(g.realClientPackage)),
} }
if tags.NonNamespaced { if tags.NonNamespaced {
@ -92,19 +94,19 @@ func (g *genFakeForGroup) GenerateType(c *generator.Context, t *types.Type, w io
} }
var groupClientTemplate = ` var groupClientTemplate = `
type Fake$.GroupVersion$ struct { type Fake$.GroupGoName$$.Version$ struct {
*$.Fake|raw$ *$.Fake|raw$
} }
` `
var getterImplNamespaced = ` 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} return &Fake$.type|publicPlural${c, namespace}
} }
` `
var getterImplNonNamespaced = ` 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} return &Fake$.type|publicPlural${c}
} }
` `
@ -112,7 +114,7 @@ func (c *Fake$.GroupVersion$) $.type|publicPlural$() $.realClientPackage$.$.type
var getRESTClient = ` var getRESTClient = `
// RESTClient returns a RESTClient that is used to communicate // RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation. // 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$ var ret *$.RESTClient|raw$
return ret return ret
} }

View File

@ -35,6 +35,7 @@ type genFakeForType struct {
outputPackage string outputPackage string
group string group string
version string version string
groupGoName string
inputPackage string inputPackage string
typeToMatch *types.Type typeToMatch *types.Type
imports namer.ImportTracker imports namer.ImportTracker
@ -116,7 +117,8 @@ func (g *genFakeForType) GenerateType(c *generator.Context, t *types.Type, w io.
"Package": namer.IC(pkg), "Package": namer.IC(pkg),
"namespaced": !tags.NonNamespaced, "namespaced": !tags.NonNamespaced,
"Group": namer.IC(g.group), "Group": namer.IC(g.group),
"GroupVersion": namer.IC(g.group) + namer.IC(g.version), "GroupGoName": g.groupGoName,
"Version": namer.IC(g.version),
"group": canonicalGroup, "group": canonicalGroup,
"groupName": groupName, "groupName": groupName,
"version": g.version, "version": g.version,
@ -286,7 +288,7 @@ func adjustTemplate(name, verbType, template string) string {
var structNamespaced = ` var structNamespaced = `
// Fake$.type|publicPlural$ implements $.type|public$Interface // Fake$.type|publicPlural$ implements $.type|public$Interface
type Fake$.type|publicPlural$ struct { type Fake$.type|publicPlural$ struct {
Fake *Fake$.GroupVersion$ Fake *Fake$.GroupGoName$$.Version$
ns string ns string
} }
` `
@ -295,7 +297,7 @@ type Fake$.type|publicPlural$ struct {
var structNonNamespaced = ` var structNonNamespaced = `
// Fake$.type|publicPlural$ implements $.type|public$Interface // Fake$.type|publicPlural$ implements $.type|public$Interface
type Fake$.type|publicPlural$ struct { type Fake$.type|publicPlural$ struct {
Fake *Fake$.GroupVersion$ Fake *Fake$.GroupGoName$$.Version$
} }
` `

View File

@ -32,6 +32,7 @@ import (
type genClientset struct { type genClientset struct {
generator.DefaultGen generator.DefaultGen
groups []clientgentypes.GroupVersions groups []clientgentypes.GroupVersions
groupGoNames map[clientgentypes.GroupVersion]string
clientsetPackage string clientsetPackage string
outputPackage string outputPackage string
imports namer.ImportTracker imports namer.ImportTracker
@ -57,8 +58,8 @@ func (g *genClientset) Imports(c *generator.Context) (imports []string) {
imports = append(imports, g.imports.ImportLines()...) imports = append(imports, g.imports.ImportLines()...)
for _, group := range g.groups { for _, group := range g.groups {
for _, version := range group.Versions { for _, version := range group.Versions {
typedClientPath := filepath.Join(g.clientsetPackage, "typed", group.Group.NonEmpty(), version.NonEmpty()) typedClientPath := filepath.Join(g.clientsetPackage, "typed", group.PackageName, version.NonEmpty())
imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", group.Group.NonEmpty(), version.NonEmpty(), typedClientPath))) imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", group.PackageName, version.NonEmpty(), typedClientPath)))
} }
} }
return return
@ -69,7 +70,7 @@ 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. // perhaps we can adapt the go2ild framework to this kind of usage.
sw := generator.NewSnippetWriter(w, c, "$", "$") sw := generator.NewSnippetWriter(w, c, "$", "$")
allGroups := clientgentypes.ToGroupVersionPackages(g.groups) allGroups := clientgentypes.ToGroupVersionPackages(g.groups, g.groupGoNames)
m := map[string]interface{}{ m := map[string]interface{}{
"allGroups": allGroups, "allGroups": allGroups,
"Config": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Config"}), "Config": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Config"}),
@ -103,9 +104,9 @@ func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Wr
var clientsetInterface = ` var clientsetInterface = `
type Interface interface { type Interface interface {
Discovery() $.DiscoveryInterface|raw$ Discovery() $.DiscoveryInterface|raw$
$range .allGroups$$.GroupVersion$() $.PackageName$.$.GroupVersion$Interface $range .allGroups$$.GroupGoName$$.Version$() $.PackageName$.$.GroupGoName$$.Version$Interface
$if .IsDefaultVersion$// Deprecated: please explicitly pick a version if possible. $if .IsDefaultVersion$// Deprecated: please explicitly pick a version if possible.
$.Group$() $.PackageName$.$.GroupVersion$Interface $.GroupGoName$() $.PackageName$.$.GroupGoName$$.Version$Interface
$end$$end$ $end$$end$
} }
` `
@ -115,23 +116,23 @@ var clientsetTemplate = `
// version included in a Clientset. // version included in a Clientset.
type Clientset struct { type Clientset struct {
*$.DiscoveryClient|raw$ *$.DiscoveryClient|raw$
$range .allGroups$$.LowerCaseGroupVersion$ *$.PackageName$.$.GroupVersion$Client $range .allGroups$$.LowerCaseGroupGoName$$.Version$ *$.PackageName$.$.GroupGoName$$.Version$Client
$end$ $end$
} }
` `
var clientsetInterfaceImplTemplate = ` var clientsetInterfaceImplTemplate = `
// $.GroupVersion$ retrieves the $.GroupVersion$Client // $.GroupGoName$$.Version$ retrieves the $.GroupGoName$$.Version$Client
func (c *Clientset) $.GroupVersion$() $.PackageName$.$.GroupVersion$Interface { func (c *Clientset) $.GroupGoName$$.Version$() $.PackageName$.$.GroupGoName$$.Version$Interface {
return c.$.LowerCaseGroupVersion$ return c.$.LowerCaseGroupGoName$$.Version$
} }
` `
var clientsetInterfaceDefaultVersionImpl = ` var clientsetInterfaceDefaultVersionImpl = `
// Deprecated: $.Group$ retrieves the default version of $.Group$Client. // Deprecated: $.GroupGoName$ retrieves the default version of $.GroupGoName$Client.
// Please explicitly pick a version. // Please explicitly pick a version.
func (c *Clientset) $.Group$() $.PackageName$.$.GroupVersion$Interface { func (c *Clientset) $.GroupGoName$() $.PackageName$.$.GroupGoName$$.Version$Interface {
return c.$.LowerCaseGroupVersion$ return c.$.LowerCaseGroupGoName$$.Version$
} }
` `
@ -154,7 +155,7 @@ func NewForConfig(c *$.Config|raw$) (*Clientset, error) {
} }
var cs Clientset var cs Clientset
var err error var err error
$range .allGroups$ cs.$.LowerCaseGroupVersion$, err =$.PackageName$.NewForConfig(&configShallowCopy) $range .allGroups$ cs.$.LowerCaseGroupGoName$$.Version$, err =$.PackageName$.NewForConfig(&configShallowCopy)
if err!=nil { if err!=nil {
return nil, err return nil, err
} }
@ -173,7 +174,7 @@ var newClientsetForConfigOrDieTemplate = `
// panics if there is an error in the config. // panics if there is an error in the config.
func NewForConfigOrDie(c *$.Config|raw$) *Clientset { func NewForConfigOrDie(c *$.Config|raw$) *Clientset {
var cs Clientset var cs Clientset
$range .allGroups$ cs.$.LowerCaseGroupVersion$ =$.PackageName$.NewForConfigOrDie(c) $range .allGroups$ cs.$.LowerCaseGroupGoName$$.Version$ =$.PackageName$.NewForConfigOrDie(c)
$end$ $end$
cs.DiscoveryClient = $.NewDiscoveryClientForConfigOrDie|raw$(c) cs.DiscoveryClient = $.NewDiscoveryClientForConfigOrDie|raw$(c)
return &cs return &cs
@ -184,7 +185,7 @@ var newClientsetForRESTClientTemplate = `
// New creates a new Clientset for the given RESTClient. // New creates a new Clientset for the given RESTClient.
func New(c $.RESTClientInterface|raw$) *Clientset { func New(c $.RESTClientInterface|raw$) *Clientset {
var cs Clientset var cs Clientset
$range .allGroups$ cs.$.LowerCaseGroupVersion$ =$.PackageName$.New(c) $range .allGroups$ cs.$.LowerCaseGroupGoName$$.Version$ =$.PackageName$.New(c)
$end$ $end$
cs.DiscoveryClient = $.NewDiscoveryClient|raw$(c) cs.DiscoveryClient = $.NewDiscoveryClient|raw$(c)
return &cs return &cs

View File

@ -34,6 +34,7 @@ type genGroup struct {
outputPackage string outputPackage string
group string group string
version string version string
groupGoName string
apiPath string apiPath string
// types in this group // types in this group
types []*types.Type types []*types.Type
@ -87,8 +88,9 @@ func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer
m := map[string]interface{}{ m := map[string]interface{}{
"group": g.group, "group": g.group,
"version": g.version, "version": g.version,
"GroupVersion": namer.IC(g.group) + namer.IC(g.version),
"groupName": groupName, "groupName": groupName,
"GroupGoName": g.groupGoName,
"Version": namer.IC(g.version),
"types": g.types, "types": g.types,
"apiPath": apiPath(g.group), "apiPath": apiPath(g.group),
"schemaGroupVersion": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime/schema", Name: "GroupVersion"}), "schemaGroupVersion": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime/schema", Name: "GroupVersion"}),
@ -108,8 +110,9 @@ func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer
return err return err
} }
wrapper := map[string]interface{}{ wrapper := map[string]interface{}{
"type": t, "type": t,
"GroupVersion": namer.IC(g.group) + namer.IC(g.version), "GroupGoName": g.groupGoName,
"Version": namer.IC(g.version),
} }
if tags.NonNamespaced { if tags.NonNamespaced {
sw.Do(getterImplNonNamespaced, wrapper) sw.Do(getterImplNonNamespaced, wrapper)
@ -131,7 +134,7 @@ func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer
} }
var groupInterfaceTemplate = ` var groupInterfaceTemplate = `
type $.GroupVersion$Interface interface { type $.GroupGoName$$.Version$Interface interface {
RESTClient() $.restRESTClientInterface|raw$ RESTClient() $.restRESTClientInterface|raw$
$range .types$ $.|publicPlural$Getter $range .types$ $.|publicPlural$Getter
$end$ $end$
@ -139,27 +142,27 @@ type $.GroupVersion$Interface interface {
` `
var groupClientTemplate = ` var groupClientTemplate = `
// $.GroupVersion$Client is used to interact with features provided by the $.groupName$ group. // $.GroupGoName$$.Version$Client is used to interact with features provided by the $.groupName$ group.
type $.GroupVersion$Client struct { type $.GroupGoName$$.Version$Client struct {
restClient $.restRESTClientInterface|raw$ restClient $.restRESTClientInterface|raw$
} }
` `
var getterImplNamespaced = ` var getterImplNamespaced = `
func (c *$.GroupVersion$Client) $.type|publicPlural$(namespace string) $.type|public$Interface { func (c *$.GroupGoName$$.Version$Client) $.type|publicPlural$(namespace string) $.type|public$Interface {
return new$.type|publicPlural$(c, namespace) return new$.type|publicPlural$(c, namespace)
} }
` `
var getterImplNonNamespaced = ` var getterImplNonNamespaced = `
func (c *$.GroupVersion$Client) $.type|publicPlural$() $.type|public$Interface { func (c *$.GroupGoName$$.Version$Client) $.type|publicPlural$() $.type|public$Interface {
return new$.type|publicPlural$(c) return new$.type|publicPlural$(c)
} }
` `
var newClientForConfigTemplate = ` var newClientForConfigTemplate = `
// NewForConfig creates a new $.GroupVersion$Client for the given config. // NewForConfig creates a new $.GroupGoName$$.Version$Client for the given config.
func NewForConfig(c *$.restConfig|raw$) (*$.GroupVersion$Client, error) { func NewForConfig(c *$.restConfig|raw$) (*$.GroupGoName$$.Version$Client, error) {
config := *c config := *c
if err := setConfigDefaults(&config); err != nil { if err := setConfigDefaults(&config); err != nil {
return nil, err return nil, err
@ -168,14 +171,14 @@ func NewForConfig(c *$.restConfig|raw$) (*$.GroupVersion$Client, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &$.GroupVersion$Client{client}, nil return &$.GroupGoName$$.Version$Client{client}, nil
} }
` `
var newClientForConfigOrDieTemplate = ` var newClientForConfigOrDieTemplate = `
// NewForConfigOrDie creates a new $.GroupVersion$Client for the given config and // NewForConfigOrDie creates a new $.GroupGoName$$.Version$Client for the given config and
// panics if there is an error in the config. // panics if there is an error in the config.
func NewForConfigOrDie(c *$.restConfig|raw$) *$.GroupVersion$Client { func NewForConfigOrDie(c *$.restConfig|raw$) *$.GroupGoName$$.Version$Client {
client, err := NewForConfig(c) client, err := NewForConfig(c)
if err != nil { if err != nil {
panic(err) panic(err)
@ -187,7 +190,7 @@ func NewForConfigOrDie(c *$.restConfig|raw$) *$.GroupVersion$Client {
var getRESTClient = ` var getRESTClient = `
// RESTClient returns a RESTClient that is used to communicate // RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation. // with API server by this client implementation.
func (c *$.GroupVersion$Client) RESTClient() $.restRESTClientInterface|raw$ { func (c *$.GroupGoName$$.Version$Client) RESTClient() $.restRESTClientInterface|raw$ {
if c == nil { if c == nil {
return nil return nil
} }
@ -196,9 +199,9 @@ func (c *$.GroupVersion$Client) RESTClient() $.restRESTClientInterface|raw$ {
` `
var newClientForRESTClientTemplate = ` var newClientForRESTClientTemplate = `
// New creates a new $.GroupVersion$Client for the given RESTClient. // New creates a new $.GroupGoName$$.Version$Client for the given RESTClient.
func New(c $.restRESTClientInterface|raw$) *$.GroupVersion$Client { func New(c $.restRESTClientInterface|raw$) *$.GroupGoName$$.Version$Client {
return &$.GroupVersion$Client{c} return &$.GroupGoName$$.Version$Client{c}
} }
` `

View File

@ -35,6 +35,7 @@ type genClientForType struct {
clientsetPackage string clientsetPackage string
group string group string
version string version string
groupGoName string
typeToMatch *types.Type typeToMatch *types.Type
imports namer.ImportTracker imports namer.ImportTracker
} }
@ -132,7 +133,8 @@ func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w i
"Group": namer.IC(g.group), "Group": namer.IC(g.group),
"subresource": false, "subresource": false,
"subresourcePath": "", "subresourcePath": "",
"GroupVersion": namer.IC(g.group) + namer.IC(g.version), "GroupGoName": g.groupGoName,
"Version": namer.IC(g.version),
"DeleteOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "DeleteOptions"}), "DeleteOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "DeleteOptions"}),
"ListOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ListOptions"}), "ListOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ListOptions"}),
"GetOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "GetOptions"}), "GetOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "GetOptions"}),
@ -366,7 +368,7 @@ type $.type|privatePlural$ struct {
var newStructNamespaced = ` var newStructNamespaced = `
// new$.type|publicPlural$ returns a $.type|publicPlural$ // new$.type|publicPlural$ returns a $.type|publicPlural$
func new$.type|publicPlural$(c *$.GroupVersion$Client, namespace string) *$.type|privatePlural$ { func new$.type|publicPlural$(c *$.GroupGoName$$.Version$Client, namespace string) *$.type|privatePlural$ {
return &$.type|privatePlural${ return &$.type|privatePlural${
client: c.RESTClient(), client: c.RESTClient(),
ns: namespace, ns: namespace,
@ -376,7 +378,7 @@ func new$.type|publicPlural$(c *$.GroupVersion$Client, namespace string) *$.type
var newStructNonNamespaced = ` var newStructNonNamespaced = `
// new$.type|publicPlural$ returns a $.type|publicPlural$ // new$.type|publicPlural$ returns a $.type|publicPlural$
func new$.type|publicPlural$(c *$.GroupVersion$Client) *$.type|privatePlural$ { func new$.type|publicPlural$(c *$.GroupGoName$$.Version$Client) *$.type|privatePlural$ {
return &$.type|privatePlural${ return &$.type|privatePlural${
client: c.RESTClient(), client: c.RESTClient(),
} }

View File

@ -67,10 +67,10 @@ func (g *GenScheme) Imports(c *generator.Context) (imports []string) {
packagePath = filepath.Dir(packagePath) packagePath = filepath.Dir(packagePath)
} }
packagePath = filepath.Join(packagePath, "install") packagePath = filepath.Join(packagePath, "install")
imports = append(imports, strings.ToLower(fmt.Sprintf("%s \"%s\"", group.Group.NonEmpty(), path.Vendorless(packagePath)))) imports = append(imports, strings.ToLower(fmt.Sprintf("%s \"%s\"", group.PackageName, path.Vendorless(packagePath))))
break break
} else { } else {
imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", group.Group.NonEmpty(), version.NonEmpty(), path.Vendorless(packagePath)))) imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", group.PackageName, version.NonEmpty(), path.Vendorless(packagePath))))
} }
} }
} }
@ -80,7 +80,7 @@ func (g *GenScheme) Imports(c *generator.Context) (imports []string) {
func (g *GenScheme) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { func (g *GenScheme) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
sw := generator.NewSnippetWriter(w, c, "$", "$") sw := generator.NewSnippetWriter(w, c, "$", "$")
allGroupVersions := clientgentypes.ToGroupVersionPackages(g.Groups) allGroupVersions := clientgentypes.ToGroupVersionPackages(g.Groups, nil)
allInstallGroups := clientgentypes.ToGroupInstallPackages(g.Groups) allInstallGroups := clientgentypes.ToGroupInstallPackages(g.Groups)
m := map[string]interface{}{ m := map[string]interface{}{

View File

@ -85,18 +85,19 @@ func defaultVersion(versions []Version) Version {
} }
// ToGroupVersionPackages is a helper function used by generators for groups. // ToGroupVersionPackages is a helper function used by generators for groups.
func ToGroupVersionPackages(groups []GroupVersions) []GroupVersionPackage { func ToGroupVersionPackages(groups []GroupVersions, groupGoNames map[GroupVersion]string) []GroupVersionPackage {
var groupVersionPackages []GroupVersionPackage var groupVersionPackages []GroupVersionPackage
for _, group := range groups { for _, group := range groups {
defaultVersion := defaultVersion(group.Versions) defaultVersion := defaultVersion(group.Versions)
for _, version := range group.Versions { for _, version := range group.Versions {
groupGoName := groupGoNames[GroupVersion{Group: group.Group, Version: version}]
groupVersionPackages = append(groupVersionPackages, GroupVersionPackage{ groupVersionPackages = append(groupVersionPackages, GroupVersionPackage{
Group: Group(namer.IC(group.Group.NonEmpty())), Group: Group(namer.IC(group.Group.NonEmpty())),
Version: Version(namer.IC(version.String())), Version: Version(namer.IC(version.String())),
GroupVersion: namer.IC(group.Group.NonEmpty()) + namer.IC(version.String()), PackageName: strings.ToLower(group.PackageName + version.NonEmpty()),
LowerCaseGroupVersion: namer.IL(group.Group.NonEmpty()) + namer.IC(version.String()), IsDefaultVersion: version == defaultVersion && version != "",
PackageName: strings.ToLower(group.Group.NonEmpty() + version.NonEmpty()), GroupGoName: groupGoName,
IsDefaultVersion: version == defaultVersion && version != "", LowerCaseGroupGoName: namer.IL(groupGoName),
}) })
} }
} }
@ -108,7 +109,7 @@ func ToGroupInstallPackages(groups []GroupVersions) []GroupInstallPackage {
for _, group := range groups { for _, group := range groups {
groupInstallPackages = append(groupInstallPackages, GroupInstallPackage{ groupInstallPackages = append(groupInstallPackages, GroupInstallPackage{
Group: Group(namer.IC(group.Group.NonEmpty())), Group: Group(namer.IC(group.Group.NonEmpty())),
InstallPackageName: strings.ToLower(group.Group.NonEmpty()), InstallPackageName: group.PackageName,
}) })
} }
return groupInstallPackages return groupInstallPackages

View File

@ -48,8 +48,10 @@ type GroupVersion struct {
} }
type GroupVersions struct { type GroupVersions struct {
Group Group // The package name of the group, e.g. extensions or networking
Versions []Version PackageName string
Group Group
Versions []Version
} }
// GroupVersionPackage contains group name, version name, and the package name client-gen will generate for this group version. // GroupVersionPackage contains group name, version name, and the package name client-gen will generate for this group version.
@ -58,10 +60,10 @@ type GroupVersionPackage struct {
Version Version Version Version
// If a user calls a group client without specifying the version (e.g., // If a user calls a group client without specifying the version (e.g.,
// c.Core(), instead of c.CoreV1()), the default version will be returned. // c.Core(), instead of c.CoreV1()), the default version will be returned.
IsDefaultVersion bool IsDefaultVersion bool
GroupVersion string PackageName string
LowerCaseGroupVersion string GroupGoName string
PackageName string LowerCaseGroupGoName string
} }
type GroupInstallPackage struct { type GroupInstallPackage struct {

View File

@ -18,6 +18,7 @@ package generators
import ( import (
"io" "io"
"path"
clientgentypes "k8s.io/code-generator/cmd/client-gen/types" clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
"k8s.io/gengo/generator" "k8s.io/gengo/generator"
@ -34,6 +35,7 @@ type factoryGenerator struct {
outputPackage string outputPackage string
imports namer.ImportTracker imports namer.ImportTracker
groupVersions map[string]clientgentypes.GroupVersions groupVersions map[string]clientgentypes.GroupVersions
gvGoNames map[string]string
clientSetPackage string clientSetPackage string
internalInterfacesPackage string internalInterfacesPackage string
filtered bool filtered bool
@ -67,15 +69,16 @@ func (g *factoryGenerator) GenerateType(c *generator.Context, t *types.Type, w i
gvInterfaces := make(map[string]*types.Type) gvInterfaces := make(map[string]*types.Type)
gvNewFuncs := make(map[string]*types.Type) gvNewFuncs := make(map[string]*types.Type)
for groupName := range g.groupVersions { for groupPkgName := range g.groupVersions {
gvInterfaces[groupName] = c.Universe.Type(types.Name{Package: packageForGroup(vendorless(g.outputPackage), g.groupVersions[groupName].Group), Name: "Interface"}) gvInterfaces[groupPkgName] = c.Universe.Type(types.Name{Package: path.Join(g.outputPackage, groupPkgName), Name: "Interface"})
gvNewFuncs[groupName] = c.Universe.Function(types.Name{Package: packageForGroup(vendorless(g.outputPackage), g.groupVersions[groupName].Group), Name: "New"}) gvNewFuncs[groupPkgName] = c.Universe.Function(types.Name{Package: path.Join(g.outputPackage, groupPkgName), Name: "New"})
} }
m := map[string]interface{}{ m := map[string]interface{}{
"cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer),
"groupVersions": g.groupVersions, "groupVersions": g.groupVersions,
"gvInterfaces": gvInterfaces, "gvInterfaces": gvInterfaces,
"gvNewFuncs": gvNewFuncs, "gvNewFuncs": gvNewFuncs,
"gvGoNames": g.gvGoNames,
"interfacesNewInformerFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "NewInformerFunc"}), "interfacesNewInformerFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "NewInformerFunc"}),
"informerFactoryInterface": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), "informerFactoryInterface": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}),
"clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), "clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}),
@ -177,14 +180,16 @@ type SharedInformerFactory interface {
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
{{$gvInterfaces := .gvInterfaces}} {{$gvInterfaces := .gvInterfaces}}
{{range $groupName, $group := .groupVersions}}{{$groupName}}() {{index $gvInterfaces $groupName|raw}} {{$gvGoNames := .gvGoNames}}
{{range $groupName, $group := .groupVersions}}{{index $gvGoNames $groupName}}() {{index $gvInterfaces $groupName|raw}}
{{end}} {{end}}
} }
{{$gvNewFuncs := .gvNewFuncs}} {{$gvNewFuncs := .gvNewFuncs}}
{{range $groupName, $group := .groupVersions}} {{$gvGoNames := .gvGoNames}}
func (f *sharedInformerFactory) {{$groupName}}() {{index $gvInterfaces $groupName|raw}} { {{range $groupPkgName, $group := .groupVersions}}
return {{index $gvNewFuncs $groupName|raw}}(f) func (f *sharedInformerFactory) {{index $gvGoNames $groupPkgName}}() {{index $gvInterfaces $groupPkgName|raw}} {
return {{index $gvNewFuncs $groupPkgName|raw}}(f)
} }
{{end}} {{end}}
` `

View File

@ -33,6 +33,7 @@ type genericGenerator struct {
outputPackage string outputPackage string
imports namer.ImportTracker imports namer.ImportTracker
groupVersions map[string]clientgentypes.GroupVersions groupVersions map[string]clientgentypes.GroupVersions
groupGoNames map[string]string
typesForGroupVersion map[clientgentypes.GroupVersion][]*types.Type typesForGroupVersion map[clientgentypes.GroupVersion][]*types.Type
filtered bool filtered bool
} }
@ -65,8 +66,9 @@ func (g *genericGenerator) Imports(c *generator.Context) (imports []string) {
} }
type group struct { type group struct {
Name string GroupGoName string
Versions []*version Name string
Versions []*version
} }
type groupSort []group type groupSort []group
@ -77,6 +79,7 @@ func (g groupSort) Swap(i, j int) { g[i], g[j] = g[j], g[i] }
type version struct { type version struct {
Name string Name string
GoName string
Resources []*types.Type Resources []*types.Type
} }
@ -95,15 +98,17 @@ func (g *genericGenerator) GenerateType(c *generator.Context, t *types.Type, w i
schemeGVs := make(map[*version]*types.Type) schemeGVs := make(map[*version]*types.Type)
orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)}
for _, groupVersions := range g.groupVersions { for groupPackageName, groupVersions := range g.groupVersions {
group := group{ group := group{
Name: namer.IC(groupVersions.Group.NonEmpty()), GroupGoName: g.groupGoNames[groupPackageName],
Versions: []*version{}, Name: groupVersions.Group.NonEmpty(),
Versions: []*version{},
} }
for _, v := range groupVersions.Versions { for _, v := range groupVersions.Versions {
gv := clientgentypes.GroupVersion{Group: groupVersions.Group, Version: v} gv := clientgentypes.GroupVersion{Group: groupVersions.Group, Version: v}
version := &version{ version := &version{
Name: namer.IC(v.NonEmpty()), Name: v.NonEmpty(),
GoName: namer.IC(v.NonEmpty()),
Resources: orderer.OrderTypes(g.typesForGroupVersion[gv]), Resources: orderer.OrderTypes(g.typesForGroupVersion[gv]),
} }
schemeGVs[version] = c.Universe.Variable(types.Name{Package: g.typesForGroupVersion[gv][0].Name.Package, Name: "SchemeGroupVersion"}) schemeGVs[version] = c.Universe.Variable(types.Name{Package: g.typesForGroupVersion[gv][0].Name.Package, Name: "SchemeGroupVersion"})
@ -159,12 +164,12 @@ var forResource = `
// TODO extend this to unknown resources with a client pool // TODO extend this to unknown resources with a client pool
func (f *sharedInformerFactory) ForResource(resource {{.schemaGroupVersionResource|raw}}) (GenericInformer, error) { func (f *sharedInformerFactory) ForResource(resource {{.schemaGroupVersionResource|raw}}) (GenericInformer, error) {
switch resource { switch resource {
{{range $group := .groups -}} {{range $group := .groups -}}{{$GroupGoName := .GroupGoName -}}
{{range $version := .Versions -}} {{range $version := .Versions -}}
// Group={{$group.Name}}, Version={{.Name}} // Group={{$group.Name}}, Version={{.Name}}
{{range .Resources -}} {{range .Resources -}}
case {{index $.schemeGVs $version|raw}}.WithResource("{{.|allLowercasePlural}}"): case {{index $.schemeGVs $version|raw}}.WithResource("{{.|allLowercasePlural}}"):
return &genericInformer{resource: resource.GroupResource(), informer: f.{{$group.Name}}().{{$version.Name}}().{{.|publicPlural}}().Informer()}, nil return &genericInformer{resource: resource.GroupResource(), informer: f.{{$GroupGoName}}().{{$version.GoName}}().{{.|publicPlural}}().Informer()}, nil
{{end}} {{end}}
{{end}} {{end}}
{{end -}} {{end -}}

View File

@ -36,7 +36,9 @@ import (
type informerGenerator struct { type informerGenerator struct {
generator.DefaultGen generator.DefaultGen
outputPackage string outputPackage string
groupPkgName string
groupVersion clientgentypes.GroupVersion groupVersion clientgentypes.GroupVersion
groupGoName string
typeToGenerate *types.Type typeToGenerate *types.Type
imports namer.ImportTracker imports namer.ImportTracker
clientSetPackage string clientSetPackage string
@ -66,8 +68,7 @@ func (g *informerGenerator) GenerateType(c *generator.Context, t *types.Type, w
glog.V(5).Infof("processing type %v", t) glog.V(5).Infof("processing type %v", t)
//listerPackage := "k8s.io/kubernetes/pkg/client/listers/" + g.groupVersion.Group.NonEmpty() + "/" + strings.ToLower(g.groupVersion.Version.NonEmpty()) listerPackage := fmt.Sprintf("%s/%s/%s", g.listersPackage, g.groupPkgName, strings.ToLower(g.groupVersion.Version.NonEmpty()))
listerPackage := fmt.Sprintf("%s/%s/%s", g.listersPackage, g.groupVersion.Group.NonEmpty(), strings.ToLower(g.groupVersion.Version.NonEmpty()))
clientSetInterface := c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}) clientSetInterface := c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"})
informerFor := "InformerFor" informerFor := "InformerFor"
@ -85,7 +86,7 @@ func (g *informerGenerator) GenerateType(c *generator.Context, t *types.Type, w
"cacheNewSharedIndexInformer": c.Universe.Function(cacheNewSharedIndexInformer), "cacheNewSharedIndexInformer": c.Universe.Function(cacheNewSharedIndexInformer),
"cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer),
"clientSetInterface": clientSetInterface, "clientSetInterface": clientSetInterface,
"group": namer.IC(g.groupVersion.Group.NonEmpty()), "group": namer.IC(g.groupGoName),
"informerFor": informerFor, "informerFor": informerFor,
"interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}),
"listOptions": c.Universe.Type(listOptions), "listOptions": c.Universe.Type(listOptions),

View File

@ -92,10 +92,6 @@ func isInternal(m types.Member) bool {
return !strings.Contains(m.Tags, "json") return !strings.Contains(m.Tags, "json")
} }
func packageForGroup(base string, group clientgentypes.Group) string {
return filepath.Join(base, group.NonEmpty())
}
func packageForInternalInterfaces(base string) string { func packageForInternalInterfaces(base string) string {
return filepath.Join(base, "internalinterfaces") return filepath.Join(base, "internalinterfaces")
} }
@ -133,6 +129,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
externalGroupVersions := make(map[string]clientgentypes.GroupVersions) externalGroupVersions := make(map[string]clientgentypes.GroupVersions)
internalGroupVersions := make(map[string]clientgentypes.GroupVersions) internalGroupVersions := make(map[string]clientgentypes.GroupVersions)
groupGoNames := make(map[string]string)
for _, inputDir := range arguments.InputDirs { for _, inputDir := range arguments.InputDirs {
p := context.Universe.Package(vendorless(inputDir)) p := context.Universe.Package(vendorless(inputDir))
@ -161,12 +158,20 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
gv.Version = clientgentypes.Version(parts[len(parts)-1]) gv.Version = clientgentypes.Version(parts[len(parts)-1])
targetGroupVersions = externalGroupVersions targetGroupVersions = externalGroupVersions
} }
groupPkgName := strings.ToLower(gv.Group.NonEmpty())
// If there's a comment of the form "// +groupName=somegroup" or // If there's a comment of the form "// +groupName=somegroup" or
// "// +groupName=somegroup.foo.bar.io", use the first field (somegroup) as the name of the // "// +groupName=somegroup.foo.bar.io", use the first field (somegroup) as the name of the
// group when generating. // group when generating.
if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil {
gv.Group = clientgentypes.Group(strings.SplitN(override[0], ".", 2)[0]) gv.Group = clientgentypes.Group(override[0])
}
// If there's a comment of the form "// +groupGoName=SomeUniqueShortName", use that as
// the Go group identifier in CamelCase. It defaults
groupGoNames[groupPkgName] = namer.IC(strings.Split(gv.Group.NonEmpty(), ".")[0])
if override := types.ExtractCommentTags("+", p.Comments)["groupGoName"]; override != nil {
groupGoNames[groupPkgName] = namer.IC(override[0])
} }
var typesToGenerate []*types.Type var typesToGenerate []*types.Type
@ -187,50 +192,45 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
continue continue
} }
icGroupName := namer.IC(gv.Group.NonEmpty()) groupVersionsEntry, ok := targetGroupVersions[groupPkgName]
groupVersionsEntry, ok := targetGroupVersions[icGroupName]
if !ok { if !ok {
groupVersionsEntry = clientgentypes.GroupVersions{ groupVersionsEntry = clientgentypes.GroupVersions{
Group: gv.Group, Group: gv.Group,
} }
} }
groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, gv.Version) groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, gv.Version)
targetGroupVersions[icGroupName] = groupVersionsEntry targetGroupVersions[groupPkgName] = groupVersionsEntry
orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)}
typesToGenerate = orderer.OrderTypes(typesToGenerate) typesToGenerate = orderer.OrderTypes(typesToGenerate)
if internal { if internal {
packageList = append(packageList, versionPackage(internalVersionPackagePath, gv, boilerplate, typesToGenerate, customArgs.InternalClientSetPackage, customArgs.ListersPackage)) packageList = append(packageList, versionPackage(internalVersionPackagePath, groupPkgName, gv, groupGoNames[groupPkgName], boilerplate, typesToGenerate, customArgs.InternalClientSetPackage, customArgs.ListersPackage))
} else { } else {
packageList = append(packageList, versionPackage(externalVersionPackagePath, gv, boilerplate, typesToGenerate, customArgs.VersionedClientSetPackage, customArgs.ListersPackage)) packageList = append(packageList, versionPackage(externalVersionPackagePath, groupPkgName, gv, groupGoNames[groupPkgName], boilerplate, typesToGenerate, customArgs.VersionedClientSetPackage, customArgs.ListersPackage))
} }
} }
if len(externalGroupVersions) != 0 { if len(externalGroupVersions) != 0 {
packageList = append(packageList, factoryInterfacePackage(externalVersionPackagePath, boilerplate, customArgs.VersionedClientSetPackage, typesForGroupVersion)) packageList = append(packageList, factoryInterfacePackage(externalVersionPackagePath, boilerplate, customArgs.VersionedClientSetPackage))
packageList = append(packageList, factoryPackage(externalVersionPackagePath, boilerplate, externalGroupVersions, customArgs.VersionedClientSetPackage, typesForGroupVersion)) packageList = append(packageList, factoryPackage(externalVersionPackagePath, boilerplate, groupGoNames, externalGroupVersions, customArgs.VersionedClientSetPackage, typesForGroupVersion))
for _, groupVersionsEntry := range externalGroupVersions { for groupPkgName, groupVersionsEntry := range externalGroupVersions {
packageList = append(packageList, groupPackage(externalVersionPackagePath, groupVersionsEntry, boilerplate)) packageList = append(packageList, groupPackage(externalVersionPackagePath, groupPkgName, groupVersionsEntry, boilerplate))
} }
} }
if len(internalGroupVersions) != 0 { if len(internalGroupVersions) != 0 {
packageList = append(packageList, factoryInterfacePackage(internalVersionPackagePath, boilerplate, customArgs.InternalClientSetPackage, typesForGroupVersion)) packageList = append(packageList, factoryInterfacePackage(internalVersionPackagePath, boilerplate, customArgs.InternalClientSetPackage))
packageList = append(packageList, factoryPackage(internalVersionPackagePath, boilerplate, internalGroupVersions, customArgs.InternalClientSetPackage, typesForGroupVersion)) packageList = append(packageList, factoryPackage(internalVersionPackagePath, boilerplate, groupGoNames, internalGroupVersions, customArgs.InternalClientSetPackage, typesForGroupVersion))
for _, groupVersionsEntry := range internalGroupVersions { for groupPkgName, groupVersionsEntry := range internalGroupVersions {
packageList = append(packageList, groupPackage(internalVersionPackagePath, groupVersionsEntry, boilerplate)) packageList = append(packageList, groupPackage(internalVersionPackagePath, groupPkgName, groupVersionsEntry, boilerplate))
} }
} }
return packageList return packageList
} }
func isInternalVersion(gv clientgentypes.GroupVersion) bool { func factoryPackage(basePackage string, boilerplate []byte, groupGoNames map[string]string, groupVersions map[string]clientgentypes.GroupVersions, clientSetPackage string, typesForGroupVersion map[clientgentypes.GroupVersion][]*types.Type) generator.Package {
return len(gv.Version) == 0
}
func factoryPackage(basePackage string, boilerplate []byte, groupVersions map[string]clientgentypes.GroupVersions, clientSetPackage string, typesForGroupVersion map[clientgentypes.GroupVersion][]*types.Type) generator.Package {
return &generator.DefaultPackage{ return &generator.DefaultPackage{
PackageName: filepath.Base(basePackage), PackageName: filepath.Base(basePackage),
PackagePath: basePackage, PackagePath: basePackage,
@ -245,6 +245,7 @@ func factoryPackage(basePackage string, boilerplate []byte, groupVersions map[st
groupVersions: groupVersions, groupVersions: groupVersions,
clientSetPackage: clientSetPackage, clientSetPackage: clientSetPackage,
internalInterfacesPackage: packageForInternalInterfaces(basePackage), internalInterfacesPackage: packageForInternalInterfaces(basePackage),
gvGoNames: groupGoNames,
}) })
generators = append(generators, &genericGenerator{ generators = append(generators, &genericGenerator{
@ -255,6 +256,7 @@ func factoryPackage(basePackage string, boilerplate []byte, groupVersions map[st
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
groupVersions: groupVersions, groupVersions: groupVersions,
typesForGroupVersion: typesForGroupVersion, typesForGroupVersion: typesForGroupVersion,
groupGoNames: groupGoNames,
}) })
return generators return generators
@ -262,7 +264,7 @@ func factoryPackage(basePackage string, boilerplate []byte, groupVersions map[st
} }
} }
func factoryInterfacePackage(basePackage string, boilerplate []byte, clientSetPackage string, typesForGroupVersion map[clientgentypes.GroupVersion][]*types.Type) generator.Package { func factoryInterfacePackage(basePackage string, boilerplate []byte, clientSetPackage string) generator.Package {
packagePath := packageForInternalInterfaces(basePackage) packagePath := packageForInternalInterfaces(basePackage)
return &generator.DefaultPackage{ return &generator.DefaultPackage{
@ -284,11 +286,11 @@ func factoryInterfacePackage(basePackage string, boilerplate []byte, clientSetPa
} }
} }
func groupPackage(basePackage string, groupVersions clientgentypes.GroupVersions, boilerplate []byte) generator.Package { func groupPackage(basePackage string, groupPkgName string, groupVersions clientgentypes.GroupVersions, boilerplate []byte) generator.Package {
packagePath := filepath.Join(basePackage, strings.ToLower(groupVersions.Group.NonEmpty())) packagePath := filepath.Join(basePackage, groupPkgName)
return &generator.DefaultPackage{ return &generator.DefaultPackage{
PackageName: strings.ToLower(groupVersions.Group.NonEmpty()), PackageName: groupPkgName,
PackagePath: packagePath, PackagePath: packagePath,
HeaderText: boilerplate, HeaderText: boilerplate,
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
@ -310,8 +312,8 @@ func groupPackage(basePackage string, groupVersions clientgentypes.GroupVersions
} }
} }
func versionPackage(basePackage string, gv clientgentypes.GroupVersion, boilerplate []byte, typesToGenerate []*types.Type, clientSetPackage, listersPackage string) generator.Package { func versionPackage(basePackage string, groupPkgName string, gv clientgentypes.GroupVersion, groupGoName string, boilerplate []byte, typesToGenerate []*types.Type, clientSetPackage, listersPackage string) generator.Package {
packagePath := filepath.Join(basePackage, strings.ToLower(gv.Group.NonEmpty()), strings.ToLower(gv.Version.NonEmpty())) packagePath := filepath.Join(basePackage, groupPkgName, strings.ToLower(gv.Version.NonEmpty()))
return &generator.DefaultPackage{ return &generator.DefaultPackage{
PackageName: strings.ToLower(gv.Version.NonEmpty()), PackageName: strings.ToLower(gv.Version.NonEmpty()),
@ -334,7 +336,9 @@ func versionPackage(basePackage string, gv clientgentypes.GroupVersion, boilerpl
OptionalName: strings.ToLower(t.Name.Name), OptionalName: strings.ToLower(t.Name.Name),
}, },
outputPackage: packagePath, outputPackage: packagePath,
groupPkgName: groupPkgName,
groupVersion: gv, groupVersion: gv,
groupGoName: groupGoName,
typeToGenerate: t, typeToGenerate: t,
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
clientSetPackage: clientSetPackage, clientSetPackage: clientSetPackage,

View File

@ -107,6 +107,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
internalGVPkg = strings.Join(parts[0:len(parts)-1], "/") internalGVPkg = strings.Join(parts[0:len(parts)-1], "/")
} }
groupPackageName := strings.ToLower(gv.Group.NonEmpty())
// If there's a comment of the form "// +groupName=somegroup" or // If there's a comment of the form "// +groupName=somegroup" or
// "// +groupName=somegroup.foo.bar.io", use the first field (somegroup) as the name of the // "// +groupName=somegroup.foo.bar.io", use the first field (somegroup) as the name of the
@ -129,7 +130,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)}
typesToGenerate = orderer.OrderTypes(typesToGenerate) typesToGenerate = orderer.OrderTypes(typesToGenerate)
packagePath := filepath.Join(arguments.OutputPackagePath, strings.ToLower(gv.Group.NonEmpty()), strings.ToLower(gv.Version.NonEmpty())) packagePath := filepath.Join(arguments.OutputPackagePath, groupPackageName, strings.ToLower(gv.Version.NonEmpty()))
packageList = append(packageList, &generator.DefaultPackage{ packageList = append(packageList, &generator.DefaultPackage{
PackageName: strings.ToLower(gv.Version.NonEmpty()), PackageName: strings.ToLower(gv.Version.NonEmpty()),
PackagePath: packagePath, PackagePath: packagePath,