From 536522bb1e60562a4a3be92261f018106240f44f Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Sat, 25 Nov 2017 11:38:10 +0100 Subject: [PATCH] client-gen: separate input-base logic from CustomArgs --- .../cmd/client-gen/args/args.go | 22 +- .../cmd/client-gen/args/gvpackages.go | 223 ++++++++++-------- .../cmd/client-gen/args/gvpackages_test.go | 58 +++-- .../client-gen/generators/client_generator.go | 30 +-- .../generators/fake/fake_client_generator.go | 2 +- .../fake/generator_fake_for_clientset.go | 4 +- .../generators/generator_for_clientset.go | 4 +- .../generators/scheme/generator_for_scheme.go | 10 +- .../code-generator/cmd/client-gen/main.go | 12 +- .../cmd/client-gen/types/helpers.go | 20 +- .../cmd/client-gen/types/types.go | 14 +- .../cmd/informer-gen/generators/generic.go | 6 +- .../informer-gen/generators/groupinterface.go | 4 +- .../cmd/informer-gen/generators/packages.go | 20 +- 14 files changed, 229 insertions(+), 200 deletions(-) diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/args/args.go b/staging/src/k8s.io/code-generator/cmd/client-gen/args/args.go index f2274c7772f..5eac82806eb 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/args/args.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/args/args.go @@ -27,12 +27,6 @@ type CustomArgs struct { // A sorted list of group versions to generate. For each of them the package path is found // in GroupVersionToInputPath. Groups []types.GroupVersions - // GroupVersionToInputPath is a map between GroupVersion and the path to the respective - // types.go, relative to InputBasePath. We still need GroupVersions in the - // struct because we need an order. - GroupVersionToInputPath map[types.GroupVersion]string - // The base for the path of GroupVersionToInputPath. - InputBasePath string // Overrides for which types should be included in the client. IncludedTypesOverrides map[types.GroupVersion][]string @@ -54,12 +48,24 @@ type CustomArgs struct { } func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { - pflag.Var(NewGVPackagesValue(&ca.GroupVersionToInputPath, &ca.Groups, nil), "input", "group/versions that client-gen will generate clients for. At most one version per group is allowed. Specified in the format \"group1/version1,group2/version2...\".") + gvsBuilder := NewGroupVersionsBuilder(&ca.Groups) + pflag.Var(NewGVPackagesValue(gvsBuilder, nil), "input", "group/versions that client-gen will generate clients for. At most one version per group is allowed. Specified in the format \"group1/version1,group2/version2...\".") pflag.Var(NewGVTypesValue(&ca.IncludedTypesOverrides, []string{}), "included-types-overrides", "list of group/version/type for which client should be generated. By default, client is generated for all types which have genclient in types.go. This overrides that. For each groupVersion in this list, only the types mentioned here will be included. The default check of genclient will be used for other group versions.") - pflag.StringVar(&ca.InputBasePath, "input-base", "k8s.io/kubernetes/pkg/apis", "base path to look for the api group.") + pflag.Var(NewInputBasePathValue(gvsBuilder, "k8s.io/kubernetes/pkg/apis"), "input-base", "base path to look for the api group.") pflag.StringVarP(&ca.ClientsetName, "clientset-name", "n", "internalclientset", "the name of the generated clientset package.") pflag.StringVarP(&ca.ClientsetAPIPath, "clientset-api-path", "", "/apis", "the value of default API HTTP path, starting with / and without trailing /.") pflag.StringVar(&ca.ClientsetOutputPath, "clientset-path", "k8s.io/kubernetes/pkg/client/clientset_generated/", "the generated clientset will be output to /.") pflag.BoolVar(&ca.ClientsetOnly, "clientset-only", false, "when set, client-gen only generates the clientset shell, without generating the individual typed clients") pflag.BoolVar(&ca.FakeClient, "fake-clientset", true, "when set, client-gen will generate the fake clientset that can be used in tests") } + +// GroupVersionPackages returns a map from GroupVersion to the package with the types.go. +func (ca *CustomArgs) GroupVersionPackages() map[types.GroupVersion]string { + res := map[types.GroupVersion]string{} + for _, pkg := range ca.Groups { + for _, v := range pkg.Versions { + res[types.GroupVersion{Group: pkg.Group, Version: v.Version}] = v.Package + } + } + return res +} diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go b/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go index 4ffdd32ed1e..8da71d6f9bf 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go @@ -21,24 +21,48 @@ import ( "encoding/csv" "flag" "path" - "strings" - - "path/filepath" "sort" + "strings" "k8s.io/code-generator/cmd/client-gen/types" ) -type gvPackagesValue struct { - gvToPath *map[types.GroupVersion]string - groups *[]types.GroupVersions - changed bool +type inputBasePathValue struct { + builder *groupVersionsBuilder } -func NewGVPackagesValue(gvToPath *map[types.GroupVersion]string, groups *[]types.GroupVersions, def []string) *gvPackagesValue { +var _ flag.Value = &inputBasePathValue{} + +func NewInputBasePathValue(builder *groupVersionsBuilder, def string) *inputBasePathValue { + v := &inputBasePathValue{ + builder: builder, + } + v.Set(def) + return v +} + +func (s *inputBasePathValue) Set(val string) error { + s.builder.importBasePath = val + return s.builder.update() +} + +func (s *inputBasePathValue) Type() string { + return "string" +} + +func (s *inputBasePathValue) String() string { + return s.builder.importBasePath +} + +type gvPackagesValue struct { + builder *groupVersionsBuilder + groups []string + changed bool +} + +func NewGVPackagesValue(builder *groupVersionsBuilder, def []string) *gvPackagesValue { gvp := new(gvPackagesValue) - gvp.gvToPath = gvToPath - gvp.groups = groups + gvp.builder = builder if def != nil { if err := gvp.set(def); err != nil { panic(err) @@ -49,6 +73,95 @@ func NewGVPackagesValue(gvToPath *map[types.GroupVersion]string, groups *[]types var _ flag.Value = &gvPackagesValue{} +func (s *gvPackagesValue) set(vs []string) error { + if s.changed { + s.groups = append(s.groups, vs...) + } else { + s.groups = append([]string(nil), vs...) + } + + s.builder.groups = s.groups + return s.builder.update() +} + +func (s *gvPackagesValue) Set(val string) error { + vs, err := readAsCSV(val) + if err != nil { + return err + } + if err := s.set(vs); err != nil { + return err + } + s.changed = true + return nil +} + +func (s *gvPackagesValue) Type() string { + return "stringSlice" +} + +func (s *gvPackagesValue) String() string { + str, _ := writeAsCSV(s.groups) + return "[" + str + "]" +} + +type groupVersionsBuilder struct { + value *[]types.GroupVersions + groups []string + importBasePath string +} + +func NewGroupVersionsBuilder(groups *[]types.GroupVersions) *groupVersionsBuilder { + return &groupVersionsBuilder{ + value: groups, + } +} + +func (p *groupVersionsBuilder) update() error { + var seenGroups = make(map[types.Group]*types.GroupVersions) + for _, v := range p.groups { + pth, gvString := parsePathGroupVersion(v) + gv, err := types.ToGroupVersion(gvString) + if err != nil { + return err + } + + versionPkg := types.PackageVersion{Package: path.Join(p.importBasePath, pth, gv.Group.NonEmpty(), gv.Version.String()), Version: gv.Version} + if group, ok := seenGroups[gv.Group]; ok { + seenGroups[gv.Group].Versions = append(group.Versions, versionPkg) + } else { + seenGroups[gv.Group] = &types.GroupVersions{ + PackageName: gv.Group.NonEmpty(), + Group: gv.Group, + Versions: []types.PackageVersion{versionPkg}, + } + } + } + + var groupNames []string + for groupName := range seenGroups { + groupNames = append(groupNames, groupName.String()) + } + sort.Strings(groupNames) + *p.value = []types.GroupVersions{} + for _, groupName := range groupNames { + *p.value = append(*p.value, *seenGroups[types.Group(groupName)]) + } + + return nil +} + +func parsePathGroupVersion(pgvString string) (gvPath string, gvString string) { + subs := strings.Split(pgvString, "/") + length := len(subs) + switch length { + case 0, 1, 2: + return "", pgvString + default: + return strings.Join(subs[:length-2], "/"), strings.Join(subs[length-2:], "/") + } +} + func readAsCSV(val string) ([]string, error) { if val == "" { return []string{}, nil @@ -68,93 +181,3 @@ func writeAsCSV(vals []string) (string, error) { w.Flush() return strings.TrimSuffix(b.String(), "\n"), nil } - -func (s *gvPackagesValue) set(vs []string) error { - if !s.changed { - *s.gvToPath = map[types.GroupVersion]string{} - *s.groups = []types.GroupVersions{} - } - - var seenGroups = make(map[types.Group]*types.GroupVersions) - for _, g := range *s.groups { - seenGroups[g.Group] = &g - } - - for _, v := range vs { - pth, gvString := parsePathGroupVersion(v) - gv, err := types.ToGroupVersion(gvString) - if err != nil { - return err - } - - if group, ok := seenGroups[gv.Group]; ok { - seenGroups[gv.Group].Versions = append(group.Versions, gv.Version) - } else { - seenGroups[gv.Group] = &types.GroupVersions{ - PackageName: gv.Group.NonEmpty(), - Group: gv.Group, - Versions: []types.Version{gv.Version}, - } - } - - (*s.gvToPath)[gv] = groupVersionPath(pth, gv.Group.String(), gv.Version.String()) - } - - var groupNames []string - for groupName := range seenGroups { - groupNames = append(groupNames, groupName.String()) - } - sort.Strings(groupNames) - *s.groups = []types.GroupVersions{} - for _, groupName := range groupNames { - *s.groups = append(*s.groups, *seenGroups[types.Group(groupName)]) - } - - return nil -} - -func (s *gvPackagesValue) Set(val string) error { - vs, err := readAsCSV(val) - if err != nil { - return err - } - if err := s.set(vs); err != nil { - return err - } - s.changed = true - return nil -} - -func (s *gvPackagesValue) Type() string { - return "stringSlice" -} - -func (s *gvPackagesValue) String() string { - strs := make([]string, 0, len(*s.gvToPath)) - for gv, pth := range *s.gvToPath { - strs = append(strs, path.Join(pth, gv.Group.String(), gv.Version.String())) - } - str, _ := writeAsCSV(strs) - return "[" + str + "]" -} - -func parsePathGroupVersion(pgvString string) (gvPath string, gvString string) { - subs := strings.Split(pgvString, "/") - length := len(subs) - switch length { - case 0, 1, 2: - return "", pgvString - default: - return strings.Join(subs[:length-2], "/"), strings.Join(subs[length-2:], "/") - } -} - -func groupVersionPath(gvPath string, group string, version string) (path string) { - // special case for the core group - if group == "api" { - path = filepath.Join("core", version) - } else { - path = filepath.Join(gvPath, group, version) - } - return -} diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages_test.go b/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages_test.go index 1a88dbf32aa..0df1633edff 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages_test.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages_test.go @@ -31,6 +31,7 @@ func TestGVPackageFlag(t *testing.T) { tests := []struct { args []string def []string + importBasePath string expected map[types.GroupVersion]string expectedGroups []types.GroupVersions parseError string @@ -42,47 +43,55 @@ func TestGVPackageFlag(t *testing.T) { }, { args: []string{"foo/bar/v1", "foo/bar/v2", "foo/bar/", "foo/v1"}, - expected: map[types.GroupVersion]string{ - {Group: "bar", Version: ""}: "foo/bar", - {Group: "bar", Version: "v1"}: "foo/bar/v1", - {Group: "bar", Version: "v2"}: "foo/bar/v2", - {Group: "foo", Version: "v1"}: "foo/v1", - }, expectedGroups: []types.GroupVersions{ - {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")}}, + {PackageName: "bar", Group: types.Group("bar"), Versions: []types.PackageVersion{ + {"foo/bar/v1", types.Version("v1")}, + {"foo/bar/v2", types.Version("v2")}, + {"foo/bar", types.Version("")}, + }}, + {PackageName: "foo", Group: types.Group("foo"), Versions: []types.PackageVersion{ + {"foo/v1", types.Version("v1")}, + }}, }, }, { args: []string{"foo/bar/v1", "foo/bar/v2", "foo/bar/", "foo/v1"}, def: []string{"foo/bar/v1alpha1", "foo/v1"}, - expected: map[types.GroupVersion]string{ - {Group: "bar", Version: ""}: "foo/bar", - {Group: "bar", Version: "v1"}: "foo/bar/v1", - {Group: "bar", Version: "v2"}: "foo/bar/v2", - {Group: "foo", Version: "v1"}: "foo/v1", - }, expectedGroups: []types.GroupVersions{ - {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")}}, + {PackageName: "bar", Group: types.Group("bar"), Versions: []types.PackageVersion{ + {"foo/bar/v1", types.Version("v1")}, + {"foo/bar/v2", types.Version("v2")}, + {"foo/bar", types.Version("")}, + }}, + {PackageName: "foo", Group: types.Group("foo"), Versions: []types.PackageVersion{ + {"foo/v1", types.Version("v1")}, + }}, }, }, { args: []string{"api/v1", "api"}, - expected: map[types.GroupVersion]string{ - {Group: "api", Version: "v1"}: "core/v1", - {Group: "api", Version: ""}: "core", - }, expectedGroups: []types.GroupVersions{ - {PackageName: "core", Group: types.Group("api"), Versions: []types.Version{types.Version("v1"), types.Version("")}}, + {PackageName: "core", Group: types.Group("api"), Versions: []types.PackageVersion{ + {"core/v1", types.Version("v1")}, + {"core", types.Version("")}, + }}, + }, + }, + { + args: []string{"foo/v1"}, + importBasePath: "k8s.io/api", + expectedGroups: []types.GroupVersions{ + {PackageName: "foo", Group: types.Group("foo"), Versions: []types.PackageVersion{ + {"k8s.io/api/foo/v1", types.Version("v1")}, + }}, }, }, } for i, test := range tests { fs := pflag.NewFlagSet("testGVPackage", pflag.ContinueOnError) - gvp := map[types.GroupVersion]string{} groups := []types.GroupVersions{} - fs.Var(NewGVPackagesValue(&gvp, &groups, test.def), "input", "usage") + importBasePath := test.importBasePath + fs.Var(NewGVPackagesValue(NewGroupVersionsBuilder(&groups, &importBasePath), test.def), "input", "usage") args := []string{} for _, a := range test.args { @@ -99,9 +108,6 @@ func TestGVPackageFlag(t *testing.T) { } else if err != nil { t.Errorf("%d: expected nil error, got %v", i, err) } - if !reflect.DeepEqual(gvp, test.expected) { - t.Errorf("%d: expected %+v, got %+v", i, test.expected, gvp) - } if !reflect.DeepEqual(groups, test.expectedGroups) { t.Errorf("%d: expected groups %+v, got groups %+v", i, test.expectedGroups, groups) } diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go index 5d314848f0d..3042267e9dc 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go @@ -233,7 +233,7 @@ func packageForScheme(customArgs *clientgenargs.CustomArgs, clientsetPackage str NextGroup: for _, group := range customArgs.Groups { for _, v := range group.Versions { - if v == "" { + if v.String() == "" { internalClient = true break NextGroup } @@ -258,7 +258,7 @@ NextGroup: DefaultGen: generator.DefaultGen{ OptionalName: "register", }, - InputPackages: customArgs.GroupVersionToInputPath, + InputPackages: customArgs.GroupVersionPackages(), OutputPackage: schemePackage, OutputPath: filepath.Join(srcTreePath, schemePackage), Groups: customArgs.Groups, @@ -274,13 +274,13 @@ 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. +// first field (somegroup) as the name of the group in Go code, e.g. as the func name in a clientset. // // 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 { + for gv, inputDir := range customArgs.GroupVersionPackages() { p := universe.Package(inputDir) if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { newGV := clientgentypes.GroupVersion{ @@ -296,7 +296,7 @@ func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.Cust for _, gvs := range customArgs.Groups { gv := clientgentypes.GroupVersion{ Group: gvs.Group, - Version: gvs.Versions[0], // we only need a version, and the first will do + Version: gvs.Versions[0].Version, // we only need a version, and the first will do } if newGV, ok := changes[gv]; ok { // There's an override, so use it. @@ -312,19 +312,6 @@ func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.Cust } } customArgs.Groups = newGroups - - // Modify customArgs.GroupVersionToInputPath based on the groupName overrides. - newGVToInputPath := make(map[clientgentypes.GroupVersion]string) - for gv, inputDir := range customArgs.GroupVersionToInputPath { - if newGV, ok := changes[gv]; ok { - // There's an override, so use it. - newGVToInputPath[newGV] = inputDir - } else { - // No override. - newGVToInputPath[gv] = inputDir - } - } - customArgs.GroupVersionToInputPath = newGVToInputPath } // Packages makes the client package definition. @@ -344,7 +331,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat gvToTypes := map[clientgentypes.GroupVersion][]*types.Type{} groupGoNames := make(map[clientgentypes.GroupVersion]string) - for gv, inputDir := range customArgs.GroupVersionToInputPath { + for gv, inputDir := range customArgs.GroupVersionPackages() { p := context.Universe.Package(path.Vendorless(inputDir)) // If there's a comment of the form "// +groupGoName=SomeUniqueShortName", use that as @@ -398,11 +385,12 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat } orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} + gvPackages := customArgs.GroupVersionPackages() for _, group := range customArgs.Groups { for _, version := range group.Versions { - gv := clientgentypes.GroupVersion{Group: group.Group, Version: version} + gv := clientgentypes.GroupVersion{Group: group.Group, Version: version.Version} types := gvToTypes[gv] - inputPath := customArgs.GroupVersionToInputPath[gv] + inputPath := gvPackages[gv] 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, group.PackageName, groupGoNames[gv], inputPath, boilerplate)) diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go index 941cc35b0db..277a3ce1045 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go @@ -116,7 +116,7 @@ func PackageForClientset(customArgs *clientgenargs.CustomArgs, fakeClientsetPack DefaultGen: generator.DefaultGen{ OptionalName: "register", }, - InputPackages: customArgs.GroupVersionToInputPath, + InputPackages: customArgs.GroupVersionPackages(), OutputPackage: fakeClientsetPackage, Groups: customArgs.Groups, GroupGoNames: groupGoNames, diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go index b6a8de3f81e..ea9ed8deb45 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go @@ -63,7 +63,7 @@ func (g *genClientset) Imports(c *generator.Context) (imports []string) { groupClientPackage := filepath.Join(g.fakeClientsetPackage, "typed", group.PackageName, version.NonEmpty()) fakeGroupClientPackage := filepath.Join(groupClientPackage, "fake") - groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{group.Group, version}]) + groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{group.Group, version.Version}]) imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", groupAlias, version.NonEmpty(), groupClientPackage))) imports = append(imports, strings.ToLower(fmt.Sprintf("fake%s%s \"%s\"", groupAlias, version.NonEmpty(), fakeGroupClientPackage))) } @@ -87,7 +87,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. sw := generator.NewSnippetWriter(w, c, "$", "$") - allGroups := clientgentypes.ToGroupVersionPackages(g.groups, g.groupGoNames) + allGroups := clientgentypes.ToGroupVersionInfo(g.groups, g.groupGoNames) sw.Do(common, nil) sw.Do(checkImpl, nil) diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go index a7fdf85d151..de52646600c 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go @@ -59,7 +59,7 @@ func (g *genClientset) Imports(c *generator.Context) (imports []string) { for _, group := range g.groups { for _, version := range group.Versions { typedClientPath := filepath.Join(g.clientsetPackage, "typed", group.PackageName, version.NonEmpty()) - groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{group.Group, version}]) + groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{group.Group, version.Version}]) imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", groupAlias, version.NonEmpty(), typedClientPath))) } } @@ -71,7 +71,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. sw := generator.NewSnippetWriter(w, c, "$", "$") - allGroups := clientgentypes.ToGroupVersionPackages(g.groups, g.groupGoNames) + allGroups := clientgentypes.ToGroupVersionInfo(g.groups, g.groupGoNames) m := map[string]interface{}{ "allGroups": allGroups, "Config": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Config"}), diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go index 416877c4949..f0f726cf728 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go @@ -61,18 +61,18 @@ func (g *GenScheme) Imports(c *generator.Context) (imports []string) { imports = append(imports, g.ImportTracker.ImportLines()...) for _, group := range g.Groups { for _, version := range group.Versions { - packagePath := g.InputPackages[clientgentypes.GroupVersion{Group: group.Group, Version: version}] - groupAlias := strings.ToLower(g.GroupGoNames[clientgentypes.GroupVersion{group.Group, version}]) + packagePath := g.InputPackages[clientgentypes.GroupVersion{Group: group.Group, Version: version.Version}] + groupAlias := strings.ToLower(g.GroupGoNames[clientgentypes.GroupVersion{group.Group, version.Version}]) if g.CreateRegistry { // import the install package for internal clientsets instead of the type package with register.go - if version != "" { + if version.Version != "" { packagePath = filepath.Dir(packagePath) } packagePath = filepath.Join(packagePath, "install") imports = append(imports, strings.ToLower(fmt.Sprintf("%s \"%s\"", groupAlias, path.Vendorless(packagePath)))) break } else { - imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", groupAlias, version.NonEmpty(), path.Vendorless(packagePath)))) + imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", groupAlias, version.Version.NonEmpty(), path.Vendorless(packagePath)))) } } } @@ -82,7 +82,7 @@ func (g *GenScheme) Imports(c *generator.Context) (imports []string) { func (g *GenScheme) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { sw := generator.NewSnippetWriter(w, c, "$", "$") - allGroupVersions := clientgentypes.ToGroupVersionPackages(g.Groups, g.GroupGoNames) + allGroupVersions := clientgentypes.ToGroupVersionInfo(g.Groups, g.GroupGoNames) allInstallGroups := clientgentypes.ToGroupInstallPackages(g.Groups, g.GroupGoNames) m := map[string]interface{}{ diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/main.go b/staging/src/k8s.io/code-generator/cmd/client-gen/main.go index 72404808ec2..392284519c1 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/main.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/main.go @@ -19,7 +19,6 @@ package main import ( "flag" - "path" "path/filepath" "github.com/golang/glog" @@ -53,12 +52,11 @@ func main() { pflag.CommandLine.AddGoFlagSet(flag.CommandLine) pflag.Parse() - // Prefix with InputBaseDir and add client dirs as input dirs. - for gv, pth := range customArgs.GroupVersionToInputPath { - customArgs.GroupVersionToInputPath[gv] = path.Join(customArgs.InputBasePath, pth) - } - for _, pkg := range customArgs.GroupVersionToInputPath { - arguments.InputDirs = append(arguments.InputDirs, pkg) + // add group version package as input dirs for gengo + for _, pkg := range customArgs.Groups { + for _, v := range pkg.Versions { + arguments.InputDirs = append(arguments.InputDirs, v.Package) + } } if err := arguments.Execute( diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/types/helpers.go b/staging/src/k8s.io/code-generator/cmd/client-gen/types/helpers.go index bc4d9dea306..33e6ac451bf 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/types/helpers.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/types/helpers.go @@ -75,27 +75,27 @@ func (a sortableSliceOfVersions) Less(i, j int) bool { // Determine the default version among versions. 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. -func defaultVersion(versions []Version) Version { +func defaultVersion(versions []PackageVersion) Version { var versionStrings []string for _, version := range versions { - versionStrings = append(versionStrings, string(version)) + versionStrings = append(versionStrings, version.Version.String()) } sort.Sort(sortableSliceOfVersions(versionStrings)) return Version(versionStrings[len(versionStrings)-1]) } -// ToGroupVersionPackages is a helper function used by generators for groups. -func ToGroupVersionPackages(groups []GroupVersions, groupGoNames map[GroupVersion]string) []GroupVersionPackage { - var groupVersionPackages []GroupVersionPackage +// ToGroupVersionInfo is a helper function used by generators for groups. +func ToGroupVersionInfo(groups []GroupVersions, groupGoNames map[GroupVersion]string) []GroupVersionInfo { + var groupVersionPackages []GroupVersionInfo for _, group := range groups { defaultVersion := defaultVersion(group.Versions) for _, version := range group.Versions { - groupGoName := groupGoNames[GroupVersion{Group: group.Group, Version: version}] - groupVersionPackages = append(groupVersionPackages, GroupVersionPackage{ + groupGoName := groupGoNames[GroupVersion{Group: group.Group, Version: version.Version}] + groupVersionPackages = append(groupVersionPackages, GroupVersionInfo{ Group: Group(namer.IC(group.Group.NonEmpty())), - Version: Version(namer.IC(version.String())), - PackageAlias: strings.ToLower(groupGoName + version.NonEmpty()), - IsDefaultVersion: version == defaultVersion && version != "", + Version: Version(namer.IC(version.Version.String())), + PackageAlias: strings.ToLower(groupGoName + version.Version.NonEmpty()), + IsDefaultVersion: version.Version == defaultVersion && version.Version != "", GroupGoName: groupGoName, LowerCaseGroupGoName: namer.IL(groupGoName), }) diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/types/types.go b/staging/src/k8s.io/code-generator/cmd/client-gen/types/types.go index a2a87b1e1d6..17fd6e92a70 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/types/types.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/types/types.go @@ -42,20 +42,26 @@ func (g Group) NonEmpty() string { return string(g) } +type PackageVersion struct { + Version + // The fully qualified package, e.g. k8s.io/kubernetes/pkg/apis/apps, where the types.go is found. + Package string +} + type GroupVersion struct { Group Group Version Version } type GroupVersions struct { - // The package name of the group, e.g. extensions or networking + // The name of the package for this group, e.g. apps. PackageName string Group Group - Versions []Version + Versions []PackageVersion } -// GroupVersionPackage contains group name, version name, and the package name client-gen will generate for this group version. -type GroupVersionPackage struct { +// GroupVersionInfo contains all the info around a group version. +type GroupVersionInfo struct { Group Group Version Version // If a user calls a group client without specifying the version (e.g., diff --git a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/generic.go b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/generic.go index 891cac31382..54632de0530 100644 --- a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/generic.go +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/generic.go @@ -105,10 +105,10 @@ func (g *genericGenerator) GenerateType(c *generator.Context, t *types.Type, w i Versions: []*version{}, } for _, v := range groupVersions.Versions { - gv := clientgentypes.GroupVersion{Group: groupVersions.Group, Version: v} + gv := clientgentypes.GroupVersion{Group: groupVersions.Group, Version: v.Version} version := &version{ - Name: v.NonEmpty(), - GoName: namer.IC(v.NonEmpty()), + Name: v.Version.NonEmpty(), + GoName: namer.IC(v.Version.NonEmpty()), Resources: orderer.OrderTypes(g.typesForGroupVersion[gv]), } schemeGVs[version] = c.Universe.Variable(types.Name{Package: g.typesForGroupVersion[gv][0].Name.Package, Name: "SchemeGroupVersion"}) diff --git a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go index 253b79f377b..0bba93c4b2e 100644 --- a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go @@ -69,11 +69,11 @@ func (g *groupInterfaceGenerator) GenerateType(c *generator.Context, t *types.Ty versions := make([]versionData, 0, len(g.groupVersions.Versions)) for _, version := range g.groupVersions.Versions { - gv := clientgentypes.GroupVersion{Group: g.groupVersions.Group, Version: version} + gv := clientgentypes.GroupVersion{Group: g.groupVersions.Group, Version: version.Version} versionPackage := filepath.Join(g.outputPackage, strings.ToLower(gv.Version.NonEmpty())) iface := c.Universe.Type(types.Name{Package: versionPackage, Name: "Interface"}) versions = append(versions, versionData{ - Name: namer.IC(version.NonEmpty()), + Name: namer.IC(version.Version.NonEmpty()), Interface: iface, New: c.Universe.Function(types.Name{Package: versionPackage, Name: "New"}), }) diff --git a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/packages.go b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/packages.go index faa012188df..6e0d5c00225 100644 --- a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/packages.go +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/packages.go @@ -18,6 +18,7 @@ package generators import ( "fmt" + "path" "path/filepath" "strings" @@ -158,7 +159,8 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat gv.Version = clientgentypes.Version(parts[len(parts)-1]) targetGroupVersions = externalGroupVersions } - groupPkgName := strings.ToLower(gv.Group.NonEmpty()) + groupPackageName := gv.Group.NonEmpty() + gvPackage := path.Clean(p.Path) // 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 @@ -169,9 +171,9 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat // 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]) + groupGoNames[groupPackageName] = namer.IC(strings.Split(gv.Group.NonEmpty(), ".")[0]) if override := types.ExtractCommentTags("+", p.Comments)["groupGoName"]; override != nil { - groupGoNames[groupPkgName] = namer.IC(override[0]) + groupGoNames[groupPackageName] = namer.IC(override[0]) } var typesToGenerate []*types.Type @@ -192,23 +194,23 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat continue } - groupVersionsEntry, ok := targetGroupVersions[groupPkgName] + groupVersionsEntry, ok := targetGroupVersions[groupPackageName] if !ok { groupVersionsEntry = clientgentypes.GroupVersions{ - PackageName: groupPkgName, + PackageName: groupPackageName, Group: gv.Group, } } - groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, gv.Version) - targetGroupVersions[groupPkgName] = groupVersionsEntry + groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, clientgentypes.PackageVersion{Version: gv.Version, Package: gvPackage}) + targetGroupVersions[groupPackageName] = groupVersionsEntry orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} typesToGenerate = orderer.OrderTypes(typesToGenerate) if internal { - packageList = append(packageList, versionPackage(internalVersionPackagePath, groupPkgName, gv, groupGoNames[groupPkgName], boilerplate, typesToGenerate, customArgs.InternalClientSetPackage, customArgs.ListersPackage)) + packageList = append(packageList, versionPackage(internalVersionPackagePath, groupPackageName, gv, groupGoNames[groupPackageName], boilerplate, typesToGenerate, customArgs.InternalClientSetPackage, customArgs.ListersPackage)) } else { - packageList = append(packageList, versionPackage(externalVersionPackagePath, groupPkgName, gv, groupGoNames[groupPkgName], boilerplate, typesToGenerate, customArgs.VersionedClientSetPackage, customArgs.ListersPackage)) + packageList = append(packageList, versionPackage(externalVersionPackagePath, groupPackageName, gv, groupGoNames[groupPackageName], boilerplate, typesToGenerate, customArgs.VersionedClientSetPackage, customArgs.ListersPackage)) } }