code-gen: uniform reusable main.go logic

Split main.go into plumbing and calls to NewDefaults, AddFlags and Validate.
This commit is contained in:
Dr. Stefan Schimanski 2017-11-25 11:45:19 +01:00
parent 536522bb1e
commit 916812ea1d
20 changed files with 629 additions and 184 deletions

View File

@ -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

View File

@ -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 <clientset-path>/<clientset-name>.")
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 <clientset-path>/<clientset-name>.")
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.

View File

@ -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 {

View File

@ -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,

View File

@ -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
}

View File

@ -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=<peer-pkg>" in doc.go, where <peer-pkg> 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) {

View File

@ -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,

View File

@ -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
}

View File

@ -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,

View File

@ -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
}

View File

@ -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,

View File

@ -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
}

View File

@ -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")
}

View File

@ -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)
}

View File

@ -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,

View File

@ -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
}

View File

@ -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,

View File

@ -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
}

View File

@ -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,

View File

@ -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
}