diff --git a/cmd/libs/go2idl/client-gen/generators/client-generator.go b/cmd/libs/go2idl/client-gen/generators/client-generator.go index a94e591dfe0..edaea3da166 100644 --- a/cmd/libs/go2idl/client-gen/generators/client-generator.go +++ b/cmd/libs/go2idl/client-gen/generators/client-generator.go @@ -193,6 +193,9 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat var packageList []generator.Package packageList = append(packageList, packageForClientset(customArgs, arguments.OutputPackagePath, boilerplate)) + if customArgs.FakeClient { + packageList = append(packageList, fake.PackageForClientset(arguments.OutputPackagePath, customArgs.GroupVersions, boilerplate)) + } // If --clientset-only=true, we don't regenerate the individual typed clients. if customArgs.ClientsetOnly { diff --git a/cmd/libs/go2idl/client-gen/generators/fake/fake-client-generator.go b/cmd/libs/go2idl/client-gen/generators/fake/fake-client-generator.go index 1a95eb86bbc..b71081877fa 100644 --- a/cmd/libs/go2idl/client-gen/generators/fake/fake-client-generator.go +++ b/cmd/libs/go2idl/client-gen/generators/fake/fake-client-generator.go @@ -22,6 +22,7 @@ import ( "k8s.io/kubernetes/cmd/libs/go2idl/generator" "k8s.io/kubernetes/cmd/libs/go2idl/types" + "k8s.io/kubernetes/pkg/api/unversioned" ) func PackageForGroup(group string, version string, typeList []*types.Type, packageBasePath string, srcTreePath string, boilerplate []byte) generator.Package { @@ -73,3 +74,32 @@ func PackageForGroup(group string, version string, typeList []*types.Type, packa }, } } + +func PackageForClientset(typedClientBasePath string, groupVersions []unversioned.GroupVersion, boilerplate []byte) generator.Package { + return &generator.DefaultPackage{ + // TODO: we'll generate fake clientset for different release in the future. + // Package name and path are hard coded for now. + PackageName: "fake", + PackagePath: "k8s.io/kubernetes/pkg/client/testing/fake", + HeaderText: boilerplate, + PackageDocumentation: []byte( + `// This package has the automatically generated fake clientset. +`), + // GeneratorFunc returns a list of generators. Each generator generates a + // single file. + GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { + generators = []generator.Generator{ + &genClientset{ + DefaultGen: generator.DefaultGen{ + OptionalName: "clientset_generated", + }, + groupVersions: groupVersions, + typedClientPath: typedClientBasePath, + outputPackage: "fake", + imports: generator.NewImportTracker(), + }, + } + return generators + }, + } +} diff --git a/cmd/libs/go2idl/client-gen/generators/fake/generator-fake-for-clientset.go b/cmd/libs/go2idl/client-gen/generators/fake/generator-fake-for-clientset.go new file mode 100644 index 00000000000..94e453a042d --- /dev/null +++ b/cmd/libs/go2idl/client-gen/generators/fake/generator-fake-for-clientset.go @@ -0,0 +1,97 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fake + +import ( + "fmt" + "io" + "path/filepath" + + "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/generators/normalization" + "k8s.io/kubernetes/cmd/libs/go2idl/generator" + "k8s.io/kubernetes/cmd/libs/go2idl/namer" + "k8s.io/kubernetes/cmd/libs/go2idl/types" + "k8s.io/kubernetes/pkg/api/unversioned" +) + +// genClientset generates a package for a clientset. +type genClientset struct { + generator.DefaultGen + groupVersions []unversioned.GroupVersion + typedClientPath string + outputPackage string + imports *generator.ImportTracker + clientsetGenerated bool +} + +var _ generator.Generator = &genClientset{} + +func (g *genClientset) Namers(c *generator.Context) namer.NameSystems { + return namer.NameSystems{ + "raw": namer.NewRawNamer(g.outputPackage, g.imports), + } +} + +// We only want to call GenerateType() once. +func (g *genClientset) Filter(c *generator.Context, t *types.Type) bool { + ret := !g.clientsetGenerated + g.clientsetGenerated = true + return ret +} + +func (g *genClientset) Imports(c *generator.Context) (imports []string) { + imports = append(imports, g.imports.ImportLines()...) + for _, gv := range g.groupVersions { + group := normalization.Group(gv.Group) + version := normalization.Version(gv.Version) + typedClientPath := filepath.Join(g.typedClientPath, group, version) + imports = append(imports, fmt.Sprintf("%s_%s \"%s\"", group, version, typedClientPath)) + fakeTypedClientPath := filepath.Join(typedClientPath, "fake") + imports = append(imports, fmt.Sprintf("%s_%s_fake \"%s\"", group, version, fakeTypedClientPath)) + } + return +} + +func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { + // TODO: We actually don't need any type information to generate the clientset, + // perhaps we can adapt the go2ild framework to this kind of usage. + sw := generator.NewSnippetWriter(w, c, "$", "$") + + type arg struct { + Group string + PackageName string + } + allGroups := []arg{} + for _, gv := range g.groupVersions { + group := normalization.Group(gv.Group) + version := normalization.Version(gv.Version) + allGroups = append(allGroups, arg{namer.IC(group), group + "_" + version}) + } + + for _, g := range allGroups { + sw.Do(clientsetInterfaceImplTemplate, g) + } + + return sw.Error() +} + +var clientsetInterfaceImplTemplate = ` +// $.Group$ retrieves the $.Group$Client +func (c *Clientset) $.Group$() $.PackageName$.$.Group$Interface { + return &$.PackageName$_fake.Fake$.Group${&c.Fake} +} +` diff --git a/cmd/libs/go2idl/client-gen/generators/generator-for-clientset.go b/cmd/libs/go2idl/client-gen/generators/generator-for-clientset.go index 8641570f199..6be068d3bf8 100644 --- a/cmd/libs/go2idl/client-gen/generators/generator-for-clientset.go +++ b/cmd/libs/go2idl/client-gen/generators/generator-for-clientset.go @@ -21,6 +21,7 @@ import ( "io" "path/filepath" + "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/generators/normalization" "k8s.io/kubernetes/cmd/libs/go2idl/generator" "k8s.io/kubernetes/cmd/libs/go2idl/namer" "k8s.io/kubernetes/cmd/libs/go2idl/types" @@ -30,10 +31,11 @@ import ( // genClientset generates a package for a clientset. type genClientset struct { generator.DefaultGen - groupVersions []unversioned.GroupVersion - typedClientPath string - outputPackage string - imports *generator.ImportTracker + groupVersions []unversioned.GroupVersion + typedClientPath string + outputPackage string + imports *generator.ImportTracker + clientsetGenerated bool } var _ generator.Generator = &genClientset{} @@ -44,35 +46,19 @@ func (g *genClientset) Namers(c *generator.Context) namer.NameSystems { } } -var generate_clientset = true - // We only want to call GenerateType() once. func (g *genClientset) Filter(c *generator.Context, t *types.Type) bool { - ret := generate_clientset - generate_clientset = false + ret := !g.clientsetGenerated + g.clientsetGenerated = true return ret } -func normalizeGroup(group string) string { - if group == "api" { - return "legacy" - } - return group -} - -func normalizeVersion(version string) string { - if version == "" { - return "unversioned" - } - return version -} - func (g *genClientset) Imports(c *generator.Context) (imports []string) { + imports = append(imports, g.imports.ImportLines()...) for _, gv := range g.groupVersions { - group := normalizeGroup(gv.Group) - version := normalizeVersion(gv.Version) + group := normalization.Group(gv.Group) + version := normalization.Version(gv.Version) typedClientPath := filepath.Join(g.typedClientPath, group, version) - imports = append(imports, g.imports.ImportLines()...) imports = append(imports, fmt.Sprintf("%s_%s \"%s\"", group, version, typedClientPath)) } return @@ -91,8 +77,8 @@ func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Wr allGroups := []arg{} for _, gv := range g.groupVersions { - group := normalizeGroup(gv.Group) - version := normalizeVersion(gv.Version) + group := normalization.Group(gv.Group) + version := normalization.Version(gv.Version) allGroups = append(allGroups, arg{namer.IC(group), group + "_" + version}) } diff --git a/cmd/libs/go2idl/client-gen/generators/normalization/normalization.go b/cmd/libs/go2idl/client-gen/generators/normalization/normalization.go new file mode 100644 index 00000000000..686407208a2 --- /dev/null +++ b/cmd/libs/go2idl/client-gen/generators/normalization/normalization.go @@ -0,0 +1,31 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package normalization + +func Group(group string) string { + if group == "api" { + return "legacy" + } + return group +} + +func Version(version string) string { + if version == "" { + return "unversioned" + } + return version +} diff --git a/pkg/client/testing/fake/clientset.go b/pkg/client/testing/fake/clientset.go index b2b3a37b888..db509c25178 100644 --- a/pkg/client/testing/fake/clientset.go +++ b/pkg/client/testing/fake/clientset.go @@ -20,10 +20,6 @@ import ( "k8s.io/kubernetes/pkg/api" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_1" "k8s.io/kubernetes/pkg/client/testing/core" - extensions_unversioned "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned" - extensions_unversioned_fake "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake" - legacy_unversioned "k8s.io/kubernetes/pkg/client/typed/generated/legacy/unversioned" - legacy_unversioned_fake "k8s.io/kubernetes/pkg/client/typed/generated/legacy/unversioned/fake" "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/watch" @@ -55,14 +51,6 @@ type Clientset struct { var _ clientset.Interface = &Clientset{} -func (c *Clientset) Legacy() legacy_unversioned.LegacyInterface { - return &legacy_unversioned_fake.FakeLegacy{&c.Fake} -} - -func (c *Clientset) Extensions() extensions_unversioned.ExtensionsInterface { - return &extensions_unversioned_fake.FakeExtensions{&c.Fake} -} - func (c *Clientset) Discovery() unversioned.DiscoveryInterface { return &FakeDiscovery{&c.Fake} } diff --git a/pkg/client/testing/fake/clientset_generated.go b/pkg/client/testing/fake/clientset_generated.go new file mode 100644 index 00000000000..e3e73bdd9d8 --- /dev/null +++ b/pkg/client/testing/fake/clientset_generated.go @@ -0,0 +1,34 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fake + +import ( + extensions_unversioned "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned" + extensions_unversioned_fake "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned/fake" + legacy_unversioned "k8s.io/kubernetes/pkg/client/typed/generated/legacy/unversioned" + legacy_unversioned_fake "k8s.io/kubernetes/pkg/client/typed/generated/legacy/unversioned/fake" +) + +// Legacy retrieves the LegacyClient +func (c *Clientset) Legacy() legacy_unversioned.LegacyInterface { + return &legacy_unversioned_fake.FakeLegacy{&c.Fake} +} + +// Extensions retrieves the ExtensionsClient +func (c *Clientset) Extensions() extensions_unversioned.ExtensionsInterface { + return &extensions_unversioned_fake.FakeExtensions{&c.Fake} +}