diff --git a/hack/.golint_failures b/hack/.golint_failures index 6cd1db4fbb1..33a057e99fd 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -727,7 +727,6 @@ staging/src/k8s.io/code-generator/cmd/client-gen/generators/scheme staging/src/k8s.io/code-generator/cmd/client-gen/types staging/src/k8s.io/code-generator/cmd/conversion-gen/generators staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf -staging/src/k8s.io/code-generator/cmd/informer-gen/generators staging/src/k8s.io/code-generator/cmd/lister-gen/generators staging/src/k8s.io/kube-aggregator/pkg/apis/apiregistration staging/src/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1 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 5eac82806eb..f17608fadde 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 @@ -17,11 +17,23 @@ limitations under the License. package args import ( + "fmt" + "path" + "github.com/spf13/pflag" + "k8s.io/gengo/args" "k8s.io/code-generator/cmd/client-gen/types" + codegenutil "k8s.io/code-generator/pkg/util" ) +var DefaultInputDirs = []string{ + "k8s.io/apimachinery/pkg/fields", + "k8s.io/apimachinery/pkg/labels", + "k8s.io/apimachinery/pkg/watch", + "k8s.io/apimachinery/pkg/apimachinery/registered", +} + // ClientGenArgs is a wrapper for arguments to client-gen. type CustomArgs struct { // A sorted list of group versions to generate. For each of them the package path is found @@ -47,16 +59,53 @@ type CustomArgs struct { FakeClient bool } -func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { +func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { + genericArgs := args.Default().WithoutDefaultFlagParsing() + customArgs := &CustomArgs{ + ClientsetName: "internalclientset", + ClientsetAPIPath: "/apis", + ClientsetOnly: false, + FakeClient: true, + } + genericArgs.CustomArgs = customArgs + genericArgs.InputDirs = DefaultInputDirs + + if pkg := codegenutil.CurrentPackage(); len(pkg) != 0 { + customArgs.ClientsetOutputPath = path.Join(pkg, "pkg/client/clientset/") + } + + return genericArgs, customArgs +} + +func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet, inputBase string) { 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.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") + pflag.Var(NewInputBasePathValue(gvsBuilder, inputBase), "input-base", "base path to look for the api group.") + pflag.StringVarP(&ca.ClientsetName, "clientset-name", "n", ca.ClientsetName, "the name of the generated clientset package.") + pflag.StringVarP(&ca.ClientsetAPIPath, "clientset-api-path", "", ca.ClientsetAPIPath, "the value of default API HTTP path, starting with / and without trailing /.") + pflag.StringVar(&ca.ClientsetOutputPath, "clientset-path", ca.ClientsetOutputPath, "the generated clientset will be output to /.") + pflag.BoolVar(&ca.ClientsetOnly, "clientset-only", ca.ClientsetOnly, "when set, client-gen only generates the clientset shell, without generating the individual typed clients") + pflag.BoolVar(&ca.FakeClient, "fake-clientset", ca.FakeClient, "when set, client-gen will generate the fake clientset that can be used in tests") +} + +func Validate(genericArgs *args.GeneratorArgs) error { + customArgs := genericArgs.CustomArgs.(*CustomArgs) + + if len(genericArgs.OutputPackagePath) == 0 { + return fmt.Errorf("output package cannot be empty") + } + if len(customArgs.ClientsetName) == 0 { + return fmt.Errorf("clientset name cannot be empty") + } + if len(customArgs.ClientsetAPIPath) == 0 { + return fmt.Errorf("clientset API path cannot be empty") + } + if len(customArgs.ClientsetOutputPath) == 0 { + return fmt.Errorf("clientset path cannot be empty") + } + + return nil } // GroupVersionPackages returns a map from GroupVersion to the package with the types.go. 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 0df1633edff..8154c2eec12 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 @@ -45,12 +45,12 @@ func TestGVPackageFlag(t *testing.T) { args: []string{"foo/bar/v1", "foo/bar/v2", "foo/bar/", "foo/v1"}, expectedGroups: []types.GroupVersions{ {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("")}, + {"v1", "foo/bar/v1"}, + {"v2", "foo/bar/v2"}, + {"", "foo/bar"}, }}, {PackageName: "foo", Group: types.Group("foo"), Versions: []types.PackageVersion{ - {"foo/v1", types.Version("v1")}, + {"v1", "foo/v1"}, }}, }, }, @@ -59,12 +59,12 @@ func TestGVPackageFlag(t *testing.T) { def: []string{"foo/bar/v1alpha1", "foo/v1"}, expectedGroups: []types.GroupVersions{ {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("")}, + {"v1", "foo/bar/v1"}, + {"v2", "foo/bar/v2"}, + {"", "foo/bar"}, }}, {PackageName: "foo", Group: types.Group("foo"), Versions: []types.PackageVersion{ - {"foo/v1", types.Version("v1")}, + {"v1", "foo/v1"}, }}, }, }, @@ -72,8 +72,8 @@ func TestGVPackageFlag(t *testing.T) { args: []string{"api/v1", "api"}, expectedGroups: []types.GroupVersions{ {PackageName: "core", Group: types.Group("api"), Versions: []types.PackageVersion{ - {"core/v1", types.Version("v1")}, - {"core", types.Version("")}, + {"v1", "core/v1"}, + {"", "core"}, }}, }, }, @@ -82,7 +82,7 @@ func TestGVPackageFlag(t *testing.T) { importBasePath: "k8s.io/api", expectedGroups: []types.GroupVersions{ {PackageName: "foo", Group: types.Group("foo"), Versions: []types.PackageVersion{ - {"k8s.io/api/foo/v1", types.Version("v1")}, + {"v1", "k8s.io/api/foo/v1"}, }}, }, }, @@ -90,8 +90,9 @@ func TestGVPackageFlag(t *testing.T) { for i, test := range tests { fs := pflag.NewFlagSet("testGVPackage", pflag.ContinueOnError) groups := []types.GroupVersions{} - importBasePath := test.importBasePath - fs.Var(NewGVPackagesValue(NewGroupVersionsBuilder(&groups, &importBasePath), test.def), "input", "usage") + builder := NewGroupVersionsBuilder(&groups) + fs.Var(NewGVPackagesValue(builder, test.def), "input", "usage") + fs.Var(NewInputBasePathValue(builder, test.importBasePath), "input-base-path", "usage") args := []string{} for _, a := range test.args { 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 392284519c1..40c3069819d 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 @@ -23,43 +23,37 @@ import ( "github.com/golang/glog" "github.com/spf13/pflag" - - clientgenargs "k8s.io/code-generator/cmd/client-gen/args" - "k8s.io/code-generator/cmd/client-gen/generators" "k8s.io/gengo/args" + + generatorargs "k8s.io/code-generator/cmd/client-gen/args" + "k8s.io/code-generator/cmd/client-gen/generators" ) func main() { - arguments := args.Default().WithoutDefaultFlagParsing() - - // Custom args. - customArgs := &clientgenargs.CustomArgs{} - customArgs.AddFlags(pflag.CommandLine) + genericArgs, customArgs := generatorargs.NewDefaults() // Override defaults. - arguments.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") - arguments.CustomArgs = customArgs - arguments.InputDirs = []string{ - "k8s.io/apimachinery/pkg/fields", - "k8s.io/apimachinery/pkg/labels", - "k8s.io/apimachinery/pkg/watch", - "k8s.io/apimachinery/pkg/apimachinery/registered", - } + // TODO: move this out of client-gen + genericArgs.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") + customArgs.ClientsetOutputPath = "k8s.io/kubernetes/pkg/client/clientset_generated/" - // Register default flags. We do this manually here because we have to override InputDirs below after additional - // input dirs are parse fromt he command-line. - arguments.AddFlags(pflag.CommandLine) + genericArgs.AddFlags(pflag.CommandLine) + customArgs.AddFlags(pflag.CommandLine, "k8s.io/kubernetes/pkg/apis") // TODO: move this input path out of client-gen pflag.CommandLine.AddGoFlagSet(flag.CommandLine) pflag.Parse() + if err := generatorargs.Validate(genericArgs); err != nil { + glog.Fatalf("Error: %v", err) + } + // 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) + genericArgs.InputDirs = append(genericArgs.InputDirs, v.Package) } } - if err := arguments.Execute( + if err := genericArgs.Execute( generators.NameSystems(), generators.DefaultNameSystem(), generators.Packages, diff --git a/staging/src/k8s.io/code-generator/cmd/conversion-gen/args/args.go b/staging/src/k8s.io/code-generator/cmd/conversion-gen/args/args.go new file mode 100644 index 00000000000..0d85222db2d --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/conversion-gen/args/args.go @@ -0,0 +1,81 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 args + +import ( + "fmt" + + "github.com/spf13/pflag" + "k8s.io/gengo/args" +) + +// DefaultBasePeerDirs are the peer-dirs nearly everybody will use, i.e. those coming from +// apimachinery. +var DefaultBasePeerDirs = []string{ + "k8s.io/apimachinery/pkg/apis/meta/v1", + "k8s.io/apimachinery/pkg/conversion", + "k8s.io/apimachinery/pkg/runtime", +} + +// CustomArgs is used by the gengo framework to pass args specific to this generator. +type CustomArgs struct { + // Base peer dirs which nearly everybody will use, i.e. outside of Kubernetes core. + BasePeerDirs []string + + // Custom peer dirs which are application specific. Always consider these as + // last-ditch possibilities for conversions. + ExtraPeerDirs []string // + + // Skipunsafe indicates whether to generate unsafe conversions to improve the efficiency + // of these operations. The unsafe operation is a direct pointer assignment via unsafe + // (within the allowed uses of unsafe) and is equivalent to a proposed Golang change to + // allow structs that are identical to be assigned to each other. + SkipUnsafe bool +} + +// NewDefaults returns default arguments for the generator. +func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { + genericArgs := args.Default().WithoutDefaultFlagParsing() + customArgs := &CustomArgs{ + BasePeerDirs: DefaultBasePeerDirs, + SkipUnsafe: false, + } + genericArgs.CustomArgs = customArgs + genericArgs.OutputFileBaseName = "conversion_generated" + return genericArgs, customArgs +} + +// AddFlags add the generator flags to the flag set. +func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { + pflag.CommandLine.StringSliceVar(&ca.BasePeerDirs, "base-peer-dirs", ca.BasePeerDirs, + "Comma-separated list of apimachinery import paths which are considered, after tag-specified peers, for conversions. Only change these if you have very good reasons.") + pflag.CommandLine.StringSliceVar(&ca.ExtraPeerDirs, "extra-peer-dirs", ca.ExtraPeerDirs, + "Application specific comma-separated list of import paths which are considered, after tag-specified peers and base-peer-dirs, for conversions.") + pflag.CommandLine.BoolVar(&ca.SkipUnsafe, "skip-unsafe", ca.SkipUnsafe, + "If true, will not generate code using unsafe pointer conversions; resulting code may be slower.") +} + +// Validate checks the given arguments. +func Validate(genericArgs *args.GeneratorArgs) error { + _ = genericArgs.CustomArgs.(*CustomArgs) + + if len(genericArgs.OutputFileBaseName) == 0 { + return fmt.Errorf("output file base name cannot be empty") + } + + return nil +} diff --git a/staging/src/k8s.io/code-generator/cmd/conversion-gen/generators/conversion.go b/staging/src/k8s.io/code-generator/cmd/conversion-gen/generators/conversion.go index b784950552e..aa82f150bf5 100644 --- a/staging/src/k8s.io/code-generator/cmd/conversion-gen/generators/conversion.go +++ b/staging/src/k8s.io/code-generator/cmd/conversion-gen/generators/conversion.go @@ -30,32 +30,10 @@ import ( "k8s.io/gengo/types" "github.com/golang/glog" + + conversionargs "k8s.io/code-generator/cmd/conversion-gen/args" ) -// DefaultBasePeerDirs are the peer-dirs nearly everybody will use, i.e. those coming from -// apimachinery. -var DefaultBasePeerDirs = []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1", - "k8s.io/apimachinery/pkg/conversion", - "k8s.io/apimachinery/pkg/runtime", -} - -// CustomArgs is used by the gengo framework to pass args specific to this generator. -type CustomArgs struct { - // Base peer dirs which nearly everybody will use, i.e. outside of Kubernetes core. - BasePeerDirs []string - - // Custom peer dirs which are application specific. Always consider these as - // last-ditch possibilities for conversions. - ExtraPeerDirs []string // - - // Skipunsafe indicates whether to generate unsafe conversions to improve the efficiency - // of these operations. The unsafe operation is a direct pointer assignment via unsafe - // (within the allowed uses of unsafe) and is equivalent to a proposed Golang change to - // allow structs that are identical to be assigned to each other. - SkipUnsafe bool -} - // These are the comment tags that carry parameters for conversion generation. const ( // e.g., "+k8s:conversion-gen=" in doc.go, where is the @@ -264,7 +242,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat continue } skipUnsafe := false - if customArgs, ok := arguments.CustomArgs.(*CustomArgs); ok { + if customArgs, ok := arguments.CustomArgs.(*conversionargs.CustomArgs); ok { peerPkgs = append(peerPkgs, customArgs.BasePeerDirs...) peerPkgs = append(peerPkgs, customArgs.ExtraPeerDirs...) skipUnsafe = customArgs.SkipUnsafe @@ -593,12 +571,6 @@ func argsFromType(inType, outType *types.Type) generator.Args { } } -func defaultingArgsFromType(inType *types.Type) generator.Args { - return generator.Args{ - "inType": inType, - } -} - const nameTmpl = "Convert_$.inType|publicIT$_To_$.outType|publicIT$" func (g *genConversion) preexists(inType, outType *types.Type) (*types.Type, bool) { diff --git a/staging/src/k8s.io/code-generator/cmd/conversion-gen/main.go b/staging/src/k8s.io/code-generator/cmd/conversion-gen/main.go index aab38ad1a6b..4cba1c6bdf2 100644 --- a/staging/src/k8s.io/code-generator/cmd/conversion-gen/main.go +++ b/staging/src/k8s.io/code-generator/cmd/conversion-gen/main.go @@ -35,37 +35,35 @@ limitations under the License. package main import ( + "flag" "path/filepath" - "k8s.io/code-generator/cmd/conversion-gen/generators" - "k8s.io/gengo/args" - "github.com/golang/glog" "github.com/spf13/pflag" + "k8s.io/gengo/args" + + generatorargs "k8s.io/code-generator/cmd/conversion-gen/args" + "k8s.io/code-generator/cmd/conversion-gen/generators" ) func main() { - arguments := args.Default() - - // Custom args. - customArgs := &generators.CustomArgs{ - BasePeerDirs: generators.DefaultBasePeerDirs, - SkipUnsafe: false, - } - pflag.CommandLine.StringSliceVar(&customArgs.BasePeerDirs, "base-peer-dirs", customArgs.BasePeerDirs, - "Comma-separated list of apimachinery import paths which are considered, after tag-specified peers, for conversions. Only change these if you have very good reasons.") - pflag.CommandLine.StringSliceVar(&customArgs.ExtraPeerDirs, "extra-peer-dirs", customArgs.ExtraPeerDirs, - "Application specific comma-separated list of import paths which are considered, after tag-specified peers and base-peer-dirs, for conversions.") - pflag.CommandLine.BoolVar(&customArgs.SkipUnsafe, "skip-unsafe", customArgs.SkipUnsafe, - "If true, will not generate code using unsafe pointer conversions; resulting code may be slower.") + genericArgs, customArgs := generatorargs.NewDefaults() // Override defaults. - arguments.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") - arguments.OutputFileBaseName = "conversion_generated" - arguments.CustomArgs = customArgs + // TODO: move this out of conversion-gen + genericArgs.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") + + genericArgs.AddFlags(pflag.CommandLine) + customArgs.AddFlags(pflag.CommandLine) + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.Parse() + + if err := generatorargs.Validate(genericArgs); err != nil { + glog.Fatalf("Error: %v", err) + } // Run it. - if err := arguments.Execute( + if err := genericArgs.Execute( generators.NameSystems(), generators.DefaultNameSystem(), generators.Packages, diff --git a/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go b/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go new file mode 100644 index 00000000000..789713012ad --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/args/args.go @@ -0,0 +1,54 @@ +/* +Copyright 2016 The Kubernetes Authors. + +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 args + +import ( + "fmt" + + "github.com/spf13/pflag" + "k8s.io/gengo/args" + "k8s.io/gengo/examples/deepcopy-gen/generators" +) + +// CustomArgs is used by the gengo framework to pass args specific to this generator. +type CustomArgs generators.CustomArgs + +// NewDefaults returns default arguments for the generator. +func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { + genericArgs := args.Default().WithoutDefaultFlagParsing() + customArgs := &CustomArgs{} + genericArgs.CustomArgs = (*generators.CustomArgs)(customArgs) // convert to upstream type to make type-casts work there + genericArgs.OutputFileBaseName = "deepcopy_generated" + return genericArgs, customArgs +} + +// AddFlags add the generator flags to the flag set. +func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { + pflag.CommandLine.StringSliceVar(&ca.BoundingDirs, "bounding-dirs", ca.BoundingDirs, + "Comma-separated list of import paths which bound the types for which deep-copies will be generated.") +} + +// Validate checks the given arguments. +func Validate(genericArgs *args.GeneratorArgs) error { + _ = genericArgs.CustomArgs.(*generators.CustomArgs) + + if len(genericArgs.OutputFileBaseName) == 0 { + return fmt.Errorf("output file base name cannot be empty") + } + + return nil +} diff --git a/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/main.go b/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/main.go index 75cd29b2e73..bb506cf7f9e 100644 --- a/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/main.go +++ b/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/main.go @@ -43,30 +43,35 @@ limitations under the License. package main import ( + "flag" "path/filepath" - "k8s.io/gengo/args" - "k8s.io/gengo/examples/deepcopy-gen/generators" - "github.com/golang/glog" "github.com/spf13/pflag" + "k8s.io/gengo/args" + "k8s.io/gengo/examples/deepcopy-gen/generators" + + generatorargs "k8s.io/code-generator/cmd/deepcopy-gen/args" ) func main() { - arguments := args.Default() - - // Custom args. - customArgs := &generators.CustomArgs{} - pflag.CommandLine.StringSliceVar(&customArgs.BoundingDirs, "bounding-dirs", customArgs.BoundingDirs, - "Comma-separated list of import paths which bound the types for which deep-copies will be generated.") + genericArgs, customArgs := generatorargs.NewDefaults() // Override defaults. - arguments.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") - arguments.OutputFileBaseName = "deepcopy_generated" - arguments.CustomArgs = customArgs + // TODO: move this out of deepcopy-gen + genericArgs.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") + + genericArgs.AddFlags(pflag.CommandLine) + customArgs.AddFlags(pflag.CommandLine) + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.Parse() + + if err := generatorargs.Validate(genericArgs); err != nil { + glog.Fatalf("Error: %v", err) + } // Run it. - if err := arguments.Execute( + if err := genericArgs.Execute( generators.NameSystems(), generators.DefaultNameSystem(), generators.Packages, diff --git a/staging/src/k8s.io/code-generator/cmd/defaulter-gen/args/args.go b/staging/src/k8s.io/code-generator/cmd/defaulter-gen/args/args.go new file mode 100644 index 00000000000..3c5a042c7ca --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/defaulter-gen/args/args.go @@ -0,0 +1,54 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 args + +import ( + "fmt" + + "github.com/spf13/pflag" + "k8s.io/gengo/args" + "k8s.io/gengo/examples/defaulter-gen/generators" +) + +// CustomArgs is used by the gengo framework to pass args specific to this generator. +type CustomArgs generators.CustomArgs + +// NewDefaults returns default arguments for the generator. +func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { + genericArgs := args.Default().WithoutDefaultFlagParsing() + customArgs := &CustomArgs{} + genericArgs.CustomArgs = (*generators.CustomArgs)(customArgs) // convert to upstream type to make type-casts work there + genericArgs.OutputFileBaseName = "zz_generated.defaults" + return genericArgs, customArgs +} + +// AddFlags add the generator flags to the flag set. +func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { + pflag.CommandLine.StringSliceVar(&ca.ExtraPeerDirs, "extra-peer-dirs", ca.ExtraPeerDirs, + "Comma-separated list of import paths which are considered, after tag-specified peers, for conversions.") +} + +// Validate checks the given arguments. +func Validate(genericArgs *args.GeneratorArgs) error { + _ = genericArgs.CustomArgs.(*generators.CustomArgs) + + if len(genericArgs.OutputFileBaseName) == 0 { + return fmt.Errorf("output file base name cannot be empty") + } + + return nil +} diff --git a/staging/src/k8s.io/code-generator/cmd/defaulter-gen/main.go b/staging/src/k8s.io/code-generator/cmd/defaulter-gen/main.go index 119ca119011..89d2b39bc6a 100644 --- a/staging/src/k8s.io/code-generator/cmd/defaulter-gen/main.go +++ b/staging/src/k8s.io/code-generator/cmd/defaulter-gen/main.go @@ -42,32 +42,35 @@ limitations under the License. package main import ( + "flag" "path/filepath" - "k8s.io/gengo/args" - "k8s.io/gengo/examples/defaulter-gen/generators" - "github.com/golang/glog" "github.com/spf13/pflag" + "k8s.io/gengo/args" + "k8s.io/gengo/examples/defaulter-gen/generators" + + generatorargs "k8s.io/code-generator/cmd/defaulter-gen/args" ) func main() { - arguments := args.Default() - - // Custom args. - customArgs := &generators.CustomArgs{ - ExtraPeerDirs: []string{}, - } - pflag.CommandLine.StringSliceVar(&customArgs.ExtraPeerDirs, "extra-peer-dirs", customArgs.ExtraPeerDirs, - "Comma-separated list of import paths which are considered, after tag-specified peers, for conversions.") + genericArgs, customArgs := generatorargs.NewDefaults() // Override defaults. - arguments.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") - arguments.OutputFileBaseName = "zz_generated.defaults" - arguments.CustomArgs = customArgs + // TODO: move this out of defaulter-gen + genericArgs.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") + + genericArgs.AddFlags(pflag.CommandLine) + customArgs.AddFlags(pflag.CommandLine) + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.Parse() + + if err := generatorargs.Validate(genericArgs); err != nil { + glog.Fatalf("Error: %v", err) + } // Run it. - if err := arguments.Execute( + if err := genericArgs.Execute( generators.NameSystems(), generators.DefaultNameSystem(), generators.Packages, diff --git a/staging/src/k8s.io/code-generator/cmd/informer-gen/args/args.go b/staging/src/k8s.io/code-generator/cmd/informer-gen/args/args.go new file mode 100644 index 00000000000..ba7f7209175 --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/args/args.go @@ -0,0 +1,77 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 args + +import ( + "fmt" + "path" + + "github.com/spf13/pflag" + codegenutil "k8s.io/code-generator/pkg/util" + "k8s.io/gengo/args" +) + +// CustomArgs is used by the gengo framework to pass args specific to this generator. +type CustomArgs struct { + VersionedClientSetPackage string + InternalClientSetPackage string + ListersPackage string + SingleDirectory bool +} + +// NewDefaults returns default arguments for the generator. +func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { + genericArgs := args.Default().WithoutDefaultFlagParsing() + customArgs := &CustomArgs{ + SingleDirectory: false, + } + genericArgs.CustomArgs = customArgs + + if pkg := codegenutil.CurrentPackage(); len(pkg) != 0 { + genericArgs.OutputPackagePath = path.Join(pkg, "pkg/client/informers") + customArgs.VersionedClientSetPackage = path.Join(pkg, "pkg/client/clientset/versioned") + customArgs.InternalClientSetPackage = path.Join(pkg, "pkg/client/clientset/internalversion") + customArgs.ListersPackage = path.Join(pkg, "pkg/client/listers") + } + + return genericArgs, customArgs +} + +// AddFlags add the generator flags to the flag set. +func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { + fs.StringVar(&ca.InternalClientSetPackage, "internal-clientset-package", ca.InternalClientSetPackage, "the full package name for the internal clientset to use") + fs.StringVar(&ca.VersionedClientSetPackage, "versioned-clientset-package", ca.VersionedClientSetPackage, "the full package name for the versioned clientset to use") + fs.StringVar(&ca.ListersPackage, "listers-package", ca.ListersPackage, "the full package name for the listers to use") + fs.BoolVar(&ca.SingleDirectory, "single-directory", ca.SingleDirectory, "if true, omit the intermediate \"internalversion\" and \"externalversions\" subdirectories") +} + +// Validate checks the given arguments. +func Validate(genericArgs *args.GeneratorArgs) error { + customArgs := genericArgs.CustomArgs.(*CustomArgs) + + if len(genericArgs.OutputPackagePath) == 0 { + return fmt.Errorf("output package cannot be empty") + } + if len(customArgs.VersionedClientSetPackage) == 0 { + return fmt.Errorf("versioned clientset package cannot be empty") + } + if len(customArgs.ListersPackage) == 0 { + return fmt.Errorf("listers package cannot be empty") + } + + return nil +} diff --git a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/customargs.go b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/customargs.go deleted file mode 100644 index 168309a920c..00000000000 --- a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/customargs.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -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 generators - -import "github.com/spf13/pflag" - -type CustomArgs struct { - VersionedClientSetPackage string - InternalClientSetPackage string - ListersPackage string - SingleDirectory bool -} - -func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { - fs.StringVar(&ca.InternalClientSetPackage, "internal-clientset-package", ca.InternalClientSetPackage, "the full package name for the internal clientset to use") - fs.StringVar(&ca.VersionedClientSetPackage, "versioned-clientset-package", ca.VersionedClientSetPackage, "the full package name for the versioned clientset to use") - fs.StringVar(&ca.ListersPackage, "listers-package", ca.ListersPackage, "the full package name for the listers to use") - fs.BoolVar(&ca.SingleDirectory, "single-directory", ca.SingleDirectory, "if true, omit the intermediate \"internalversion\" and \"externalversions\" subdirectories") -} 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 6e0d5c00225..2a6ef2eeb56 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 @@ -22,6 +22,7 @@ import ( "path/filepath" "strings" + "github.com/golang/glog" "k8s.io/gengo/args" "k8s.io/gengo/generator" "k8s.io/gengo/namer" @@ -29,8 +30,7 @@ import ( "k8s.io/code-generator/cmd/client-gen/generators/util" clientgentypes "k8s.io/code-generator/cmd/client-gen/types" - - "github.com/golang/glog" + informergenargs "k8s.io/code-generator/cmd/informer-gen/args" ) // NameSystems returns the name system used by the generators in this package. @@ -113,7 +113,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat boilerplate = append(boilerplate, []byte(generatedBy())...) - customArgs, ok := arguments.CustomArgs.(*CustomArgs) + customArgs, ok := arguments.CustomArgs.(*informergenargs.CustomArgs) if !ok { glog.Fatalf("Wrong CustomArgs type: %T", arguments.CustomArgs) } diff --git a/staging/src/k8s.io/code-generator/cmd/informer-gen/main.go b/staging/src/k8s.io/code-generator/cmd/informer-gen/main.go index 78c0b3829cb..fc6feeb30bc 100644 --- a/staging/src/k8s.io/code-generator/cmd/informer-gen/main.go +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/main.go @@ -17,34 +17,39 @@ limitations under the License. package main import ( + "flag" "path/filepath" - "k8s.io/code-generator/cmd/informer-gen/generators" - "k8s.io/gengo/args" - "github.com/golang/glog" "github.com/spf13/pflag" + "k8s.io/code-generator/cmd/informer-gen/generators" + "k8s.io/gengo/args" + + generatorargs "k8s.io/code-generator/cmd/informer-gen/args" ) func main() { - arguments := args.Default() - - // Custom arguments. - customArgs := &generators.CustomArgs{ - VersionedClientSetPackage: "k8s.io/kubernetes/pkg/client/clientset_generated/clientset", - InternalClientSetPackage: "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset", - ListersPackage: "k8s.io/kubernetes/pkg/client/listers", - SingleDirectory: false, - } - customArgs.AddFlags(pflag.CommandLine) + genericArgs, customArgs := generatorargs.NewDefaults() // Override defaults. - arguments.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") - arguments.OutputPackagePath = "k8s.io/kubernetes/pkg/client/informers/informers_generated" - arguments.CustomArgs = customArgs + // TODO: move out of informer-gen + genericArgs.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") + genericArgs.OutputPackagePath = "k8s.io/kubernetes/pkg/client/informers/informers_generated" + customArgs.VersionedClientSetPackage = "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" + customArgs.InternalClientSetPackage = "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + customArgs.ListersPackage = "k8s.io/kubernetes/pkg/client/listers" + + genericArgs.AddFlags(pflag.CommandLine) + customArgs.AddFlags(pflag.CommandLine) + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.Parse() + + if err := generatorargs.Validate(genericArgs); err != nil { + glog.Fatalf("Error: %v", err) + } // Run it. - if err := arguments.Execute( + if err := genericArgs.Execute( generators.NameSystems(), generators.DefaultNameSystem(), generators.Packages, diff --git a/staging/src/k8s.io/code-generator/cmd/lister-gen/args/args.go b/staging/src/k8s.io/code-generator/cmd/lister-gen/args/args.go new file mode 100644 index 00000000000..34914ea8c9b --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/lister-gen/args/args.go @@ -0,0 +1,56 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 args + +import ( + "fmt" + "path" + + "github.com/spf13/pflag" + codegenutil "k8s.io/code-generator/pkg/util" + "k8s.io/gengo/args" +) + +// CustomArgs is used by the gengo framework to pass args specific to this generator. +type CustomArgs struct{} + +// NewDefaults returns default arguments for the generator. +func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { + genericArgs := args.Default().WithoutDefaultFlagParsing() + customArgs := &CustomArgs{} + genericArgs.CustomArgs = customArgs + + if pkg := codegenutil.CurrentPackage(); len(pkg) != 0 { + genericArgs.OutputPackagePath = path.Join(pkg, "pkg/client/listers") + } + + return genericArgs, customArgs +} + +// AddFlags add the generator flags to the flag set. +func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) {} + +// Validate checks the given arguments. +func Validate(genericArgs *args.GeneratorArgs) error { + _ = genericArgs.CustomArgs.(*CustomArgs) + + if len(genericArgs.OutputPackagePath) == 0 { + return fmt.Errorf("output package cannot be empty") + } + + return nil +} diff --git a/staging/src/k8s.io/code-generator/cmd/lister-gen/main.go b/staging/src/k8s.io/code-generator/cmd/lister-gen/main.go index 3b305f82877..a89817f4957 100644 --- a/staging/src/k8s.io/code-generator/cmd/lister-gen/main.go +++ b/staging/src/k8s.io/code-generator/cmd/lister-gen/main.go @@ -17,23 +17,36 @@ limitations under the License. package main import ( + "flag" "path/filepath" + "github.com/golang/glog" + "github.com/spf13/pflag" "k8s.io/code-generator/cmd/lister-gen/generators" "k8s.io/gengo/args" - "github.com/golang/glog" + generatorargs "k8s.io/code-generator/cmd/lister-gen/args" ) func main() { - arguments := args.Default() + genericArgs, customArgs := generatorargs.NewDefaults() // Override defaults. - arguments.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") - arguments.OutputPackagePath = "k8s.io/kubernetes/pkg/client/listers" + // TODO: move this out of lister-gen + genericArgs.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") + genericArgs.OutputPackagePath = "k8s.io/kubernetes/pkg/client/listers" + + genericArgs.AddFlags(pflag.CommandLine) + customArgs.AddFlags(pflag.CommandLine) + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.Parse() + + if err := generatorargs.Validate(genericArgs); err != nil { + glog.Fatalf("Error: %v", err) + } // Run it. - if err := arguments.Execute( + if err := genericArgs.Execute( generators.NameSystems(), generators.DefaultNameSystem(), generators.Packages, diff --git a/staging/src/k8s.io/code-generator/cmd/openapi-gen/args/args.go b/staging/src/k8s.io/code-generator/cmd/openapi-gen/args/args.go new file mode 100644 index 00000000000..f9bb17e1a56 --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/openapi-gen/args/args.go @@ -0,0 +1,53 @@ +/* +Copyright 2016 The Kubernetes Authors. + +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 args + +import ( + "fmt" + + "github.com/spf13/pflag" + "k8s.io/gengo/args" +) + +// CustomArgs is used by the gengo framework to pass args specific to this generator. +type CustomArgs struct{} + +// NewDefaults returns default arguments for the generator. +func NewDefaults() (*args.GeneratorArgs, *CustomArgs) { + genericArgs := args.Default().WithoutDefaultFlagParsing() + customArgs := &CustomArgs{} + genericArgs.CustomArgs = customArgs + genericArgs.OutputFileBaseName = "openapi_generated" + return genericArgs, customArgs +} + +// AddFlags add the generator flags to the flag set. +func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) {} + +// Validate checks the given arguments. +func Validate(genericArgs *args.GeneratorArgs) error { + _ = genericArgs.CustomArgs.(*CustomArgs) + + if len(genericArgs.OutputFileBaseName) == 0 { + return fmt.Errorf("output file base name cannot be empty") + } + if len(genericArgs.OutputPackagePath) == 0 { + return fmt.Errorf("output package cannot be empty") + } + + return nil +} diff --git a/staging/src/k8s.io/code-generator/cmd/openapi-gen/main.go b/staging/src/k8s.io/code-generator/cmd/openapi-gen/main.go index 67355f83494..e3c6f6c6cd8 100644 --- a/staging/src/k8s.io/code-generator/cmd/openapi-gen/main.go +++ b/staging/src/k8s.io/code-generator/cmd/openapi-gen/main.go @@ -20,23 +20,35 @@ limitations under the License. package main import ( + "flag" "path/filepath" + "github.com/golang/glog" + "github.com/spf13/pflag" "k8s.io/gengo/args" "k8s.io/kube-openapi/pkg/generators" - "github.com/golang/glog" + generatorargs "k8s.io/code-generator/cmd/openapi-gen/args" ) func main() { - arguments := args.Default() + genericArgs, customArgs := generatorargs.NewDefaults() // Override defaults. - arguments.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") - arguments.OutputFileBaseName = "openapi_generated" + // TODO: move this out of openapi-gen + genericArgs.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt") + + genericArgs.AddFlags(pflag.CommandLine) + customArgs.AddFlags(pflag.CommandLine) + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.Parse() + + if err := generatorargs.Validate(genericArgs); err != nil { + glog.Fatalf("Error: %v", err) + } // Run it. - if err := arguments.Execute( + if err := genericArgs.Execute( generators.NameSystems(), generators.DefaultNameSystem(), generators.Packages, diff --git a/staging/src/k8s.io/code-generator/pkg/util/build.go b/staging/src/k8s.io/code-generator/pkg/util/build.go new file mode 100644 index 00000000000..9d3e8a8e151 --- /dev/null +++ b/staging/src/k8s.io/code-generator/pkg/util/build.go @@ -0,0 +1,52 @@ +/* +Copyright 2017 The Kubernetes Authors. + +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 util + +import ( + gobuild "go/build" + "path/filepath" + "strings" +) + +// CurrentPackage returns the go package of the current directory, or "" if it cannot +// be derived from the GOPATH. +func CurrentPackage() string { + for _, root := range gobuild.Default.SrcDirs() { + if pkg, ok := hasSubdir(root, "."); ok { + return pkg + } + } + return "" +} + +func hasSubdir(root, dir string) (rel string, ok bool) { + // ensure a tailing separator to properly compare on word-boundaries + const sep = string(filepath.Separator) + root = filepath.Clean(root) + if !strings.HasSuffix(root, sep) { + root += sep + } + + // check whether root dir starts with root + dir = filepath.Clean(dir) + if !strings.HasPrefix(dir, root) { + return "", false + } + + // cut off root + return filepath.ToSlash(dir[len(root):]), true +}