diff --git a/hack/.golint_failures b/hack/.golint_failures index 1f2f6c9061f..659d1c25490 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/hack/update-codegen.sh b/hack/update-codegen.sh index 01135e2451a..9c29807b438 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -72,7 +72,7 @@ INTERNAL_DIRS_CSV=$(IFS=',';echo "${INTERNAL_DIRS[*]// /,}";IFS=$) # This can be called with one flag, --verify-only, so it works for both the # update- and verify- scripts. ${clientgen} --input-base="k8s.io/kubernetes/pkg/apis" --input="${INTERNAL_DIRS_CSV}" "$@" -${clientgen} --output-base "${KUBE_ROOT}/vendor" --clientset-path="k8s.io/client-go" --clientset-name="kubernetes" --input-base="k8s.io/kubernetes/vendor/k8s.io/api" --input="${GV_DIRS_CSV}" "$@" +${clientgen} --output-base "${KUBE_ROOT}/vendor" --output-package="k8s.io/client-go" --clientset-name="kubernetes" --input-base="k8s.io/kubernetes/vendor/k8s.io/api" --input="${GV_DIRS_CSV}" "$@" listergen_internal_apis=( $( diff --git a/staging/BUILD b/staging/BUILD index fe653506ce4..b7f2b8fbd08 100644 --- a/staging/BUILD +++ b/staging/BUILD @@ -210,6 +210,7 @@ filegroup( "//staging/src/k8s.io/code-generator/cmd/lister-gen:all-srcs", "//staging/src/k8s.io/code-generator/cmd/openapi-gen:all-srcs", "//staging/src/k8s.io/code-generator/cmd/set-gen:all-srcs", + "//staging/src/k8s.io/code-generator/pkg/util:all-srcs", "//staging/src/k8s.io/code-generator/third_party/forked/golang/reflect:all-srcs", "//staging/src/k8s.io/kube-aggregator:all-srcs", "//staging/src/k8s.io/metrics/pkg/apis/custom_metrics:all-srcs", diff --git a/staging/src/k8s.io/apiextensions-apiserver/hack/update-codegen.sh b/staging/src/k8s.io/apiextensions-apiserver/hack/update-codegen.sh index efc52ecd886..8b1e582bb46 100755 --- a/staging/src/k8s.io/apiextensions-apiserver/hack/update-codegen.sh +++ b/staging/src/k8s.io/apiextensions-apiserver/hack/update-codegen.sh @@ -50,7 +50,7 @@ apiextensions/ apiextensions/v1beta1 ) INPUT="--input ${INPUT_APIS[@]}" -CLIENTSET_PATH="--clientset-path k8s.io/apiextensions-apiserver/pkg/client/clientset" +CLIENTSET_PATH="--output-package k8s.io/apiextensions-apiserver/pkg/client/clientset" ${CLIENTGEN} ${INPUT_BASE} ${INPUT} ${CLIENTSET_PATH} --output-base ${SCRIPT_BASE} ${CLIENTGEN} --clientset-name="clientset" ${INPUT_BASE} --input apiextensions/v1beta1 ${CLIENTSET_PATH} --output-base ${SCRIPT_BASE} diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/args/BUILD b/staging/src/k8s.io/code-generator/cmd/client-gen/args/BUILD index 03a93e447d4..fc7ed844947 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/args/BUILD +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/args/BUILD @@ -17,6 +17,8 @@ go_library( deps = [ "//vendor/github.com/spf13/pflag:go_default_library", "//vendor/k8s.io/code-generator/cmd/client-gen/types:go_default_library", + "//vendor/k8s.io/code-generator/pkg/util:go_default_library", + "//vendor/k8s.io/gengo/args:go_default_library", ], ) 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 fee31d90dc0..6d4bc1739b1 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,22 +17,28 @@ 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 // in GroupVersionToInputPath. Groups []types.GroupVersions - // GroupVersionToInputPath is a map between GroupVersion and the path to the respective - // types.go, relative to InputBasePath. We still need GroupVersions in the - // struct because we need an order. - GroupVersionToInputPath map[types.GroupVersion]string - // The base for the path of GroupVersionToInputPath. - InputBasePath string // Overrides for which types should be included in the client. IncludedTypesOverrides map[types.GroupVersion][]string @@ -40,10 +46,7 @@ type CustomArgs struct { // ClientsetName is the name of the clientset to be generated. It's // populated from command-line arguments. ClientsetName string - // ClientsetOutputPath is the path the clientset will be generated at. It's - // populated from command-line arguments. - ClientsetOutputPath string - // ClientsetAPIPath is the default API path for generated clients. + // ClientsetAPIPath is the default API HTTP path for generated clients. ClientsetAPIPath string // ClientsetOnly determines if we should generate the clients for groups and // types along with the clientset. It's populated from command-line @@ -53,13 +56,70 @@ type CustomArgs struct { FakeClient bool } -func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) { - pflag.Var(NewGVPackagesValue(&ca.GroupVersionToInputPath, &ca.Groups, nil), "input", "group/versions that client-gen will generate clients for. At most one version per group is allowed. Specified in the format \"group1/version1,group2/version2...\".") - pflag.Var(NewGVTypesValue(&ca.IncludedTypesOverrides, []string{}), "included-types-overrides", "list of group/version/type for which client should be generated. By default, client is generated for all types which have genclient in types.go. This overrides that. For each groupVersion in this list, only the types mentioned here will be included. The default check of genclient will be used for other group versions.") - pflag.StringVar(&ca.InputBasePath, "input-base", "k8s.io/kubernetes/pkg/apis", "base path to look for the api group.") - pflag.StringVarP(&ca.ClientsetName, "clientset-name", "n", "internalclientset", "the name of the generated clientset package.") - pflag.StringVarP(&ca.ClientsetAPIPath, "clientset-api-path", "", "", "the value of default API path.") - 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") +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 { + genericArgs.OutputPackagePath = 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, 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.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") + + // support old flags + fs.SetNormalizeFunc(mapFlagName("clientset-path", "output-package", fs.GetNormalizeFunc())) +} + +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") + } + + return nil +} + +// GroupVersionPackages returns a map from GroupVersion to the package with the types.go. +func (ca *CustomArgs) GroupVersionPackages() map[types.GroupVersion]string { + res := map[types.GroupVersion]string{} + for _, pkg := range ca.Groups { + for _, v := range pkg.Versions { + res[types.GroupVersion{Group: pkg.Group, Version: v.Version}] = v.Package + } + } + return res +} + +func mapFlagName(from, to string, old func(fs *pflag.FlagSet, name string) pflag.NormalizedName) func(fs *pflag.FlagSet, name string) pflag.NormalizedName { + return func(fs *pflag.FlagSet, name string) pflag.NormalizedName { + if name == from { + name = to + } + return old(fs, name) + } } diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go b/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go index 4ffdd32ed1e..8da71d6f9bf 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages.go @@ -21,24 +21,48 @@ import ( "encoding/csv" "flag" "path" - "strings" - - "path/filepath" "sort" + "strings" "k8s.io/code-generator/cmd/client-gen/types" ) -type gvPackagesValue struct { - gvToPath *map[types.GroupVersion]string - groups *[]types.GroupVersions - changed bool +type inputBasePathValue struct { + builder *groupVersionsBuilder } -func NewGVPackagesValue(gvToPath *map[types.GroupVersion]string, groups *[]types.GroupVersions, def []string) *gvPackagesValue { +var _ flag.Value = &inputBasePathValue{} + +func NewInputBasePathValue(builder *groupVersionsBuilder, def string) *inputBasePathValue { + v := &inputBasePathValue{ + builder: builder, + } + v.Set(def) + return v +} + +func (s *inputBasePathValue) Set(val string) error { + s.builder.importBasePath = val + return s.builder.update() +} + +func (s *inputBasePathValue) Type() string { + return "string" +} + +func (s *inputBasePathValue) String() string { + return s.builder.importBasePath +} + +type gvPackagesValue struct { + builder *groupVersionsBuilder + groups []string + changed bool +} + +func NewGVPackagesValue(builder *groupVersionsBuilder, def []string) *gvPackagesValue { gvp := new(gvPackagesValue) - gvp.gvToPath = gvToPath - gvp.groups = groups + gvp.builder = builder if def != nil { if err := gvp.set(def); err != nil { panic(err) @@ -49,6 +73,95 @@ func NewGVPackagesValue(gvToPath *map[types.GroupVersion]string, groups *[]types var _ flag.Value = &gvPackagesValue{} +func (s *gvPackagesValue) set(vs []string) error { + if s.changed { + s.groups = append(s.groups, vs...) + } else { + s.groups = append([]string(nil), vs...) + } + + s.builder.groups = s.groups + return s.builder.update() +} + +func (s *gvPackagesValue) Set(val string) error { + vs, err := readAsCSV(val) + if err != nil { + return err + } + if err := s.set(vs); err != nil { + return err + } + s.changed = true + return nil +} + +func (s *gvPackagesValue) Type() string { + return "stringSlice" +} + +func (s *gvPackagesValue) String() string { + str, _ := writeAsCSV(s.groups) + return "[" + str + "]" +} + +type groupVersionsBuilder struct { + value *[]types.GroupVersions + groups []string + importBasePath string +} + +func NewGroupVersionsBuilder(groups *[]types.GroupVersions) *groupVersionsBuilder { + return &groupVersionsBuilder{ + value: groups, + } +} + +func (p *groupVersionsBuilder) update() error { + var seenGroups = make(map[types.Group]*types.GroupVersions) + for _, v := range p.groups { + pth, gvString := parsePathGroupVersion(v) + gv, err := types.ToGroupVersion(gvString) + if err != nil { + return err + } + + versionPkg := types.PackageVersion{Package: path.Join(p.importBasePath, pth, gv.Group.NonEmpty(), gv.Version.String()), Version: gv.Version} + if group, ok := seenGroups[gv.Group]; ok { + seenGroups[gv.Group].Versions = append(group.Versions, versionPkg) + } else { + seenGroups[gv.Group] = &types.GroupVersions{ + PackageName: gv.Group.NonEmpty(), + Group: gv.Group, + Versions: []types.PackageVersion{versionPkg}, + } + } + } + + var groupNames []string + for groupName := range seenGroups { + groupNames = append(groupNames, groupName.String()) + } + sort.Strings(groupNames) + *p.value = []types.GroupVersions{} + for _, groupName := range groupNames { + *p.value = append(*p.value, *seenGroups[types.Group(groupName)]) + } + + return nil +} + +func parsePathGroupVersion(pgvString string) (gvPath string, gvString string) { + subs := strings.Split(pgvString, "/") + length := len(subs) + switch length { + case 0, 1, 2: + return "", pgvString + default: + return strings.Join(subs[:length-2], "/"), strings.Join(subs[length-2:], "/") + } +} + func readAsCSV(val string) ([]string, error) { if val == "" { return []string{}, nil @@ -68,93 +181,3 @@ func writeAsCSV(vals []string) (string, error) { w.Flush() return strings.TrimSuffix(b.String(), "\n"), nil } - -func (s *gvPackagesValue) set(vs []string) error { - if !s.changed { - *s.gvToPath = map[types.GroupVersion]string{} - *s.groups = []types.GroupVersions{} - } - - var seenGroups = make(map[types.Group]*types.GroupVersions) - for _, g := range *s.groups { - seenGroups[g.Group] = &g - } - - for _, v := range vs { - pth, gvString := parsePathGroupVersion(v) - gv, err := types.ToGroupVersion(gvString) - if err != nil { - return err - } - - if group, ok := seenGroups[gv.Group]; ok { - seenGroups[gv.Group].Versions = append(group.Versions, gv.Version) - } else { - seenGroups[gv.Group] = &types.GroupVersions{ - PackageName: gv.Group.NonEmpty(), - Group: gv.Group, - Versions: []types.Version{gv.Version}, - } - } - - (*s.gvToPath)[gv] = groupVersionPath(pth, gv.Group.String(), gv.Version.String()) - } - - var groupNames []string - for groupName := range seenGroups { - groupNames = append(groupNames, groupName.String()) - } - sort.Strings(groupNames) - *s.groups = []types.GroupVersions{} - for _, groupName := range groupNames { - *s.groups = append(*s.groups, *seenGroups[types.Group(groupName)]) - } - - return nil -} - -func (s *gvPackagesValue) Set(val string) error { - vs, err := readAsCSV(val) - if err != nil { - return err - } - if err := s.set(vs); err != nil { - return err - } - s.changed = true - return nil -} - -func (s *gvPackagesValue) Type() string { - return "stringSlice" -} - -func (s *gvPackagesValue) String() string { - strs := make([]string, 0, len(*s.gvToPath)) - for gv, pth := range *s.gvToPath { - strs = append(strs, path.Join(pth, gv.Group.String(), gv.Version.String())) - } - str, _ := writeAsCSV(strs) - return "[" + str + "]" -} - -func parsePathGroupVersion(pgvString string) (gvPath string, gvString string) { - subs := strings.Split(pgvString, "/") - length := len(subs) - switch length { - case 0, 1, 2: - return "", pgvString - default: - return strings.Join(subs[:length-2], "/"), strings.Join(subs[length-2:], "/") - } -} - -func groupVersionPath(gvPath string, group string, version string) (path string) { - // special case for the core group - if group == "api" { - path = filepath.Join("core", version) - } else { - path = filepath.Join(gvPath, group, version) - } - return -} diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages_test.go b/staging/src/k8s.io/code-generator/cmd/client-gen/args/gvpackages_test.go index 1a88dbf32aa..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 @@ -31,6 +31,7 @@ func TestGVPackageFlag(t *testing.T) { tests := []struct { args []string def []string + importBasePath string expected map[types.GroupVersion]string expectedGroups []types.GroupVersions parseError string @@ -42,47 +43,56 @@ func TestGVPackageFlag(t *testing.T) { }, { args: []string{"foo/bar/v1", "foo/bar/v2", "foo/bar/", "foo/v1"}, - expected: map[types.GroupVersion]string{ - {Group: "bar", Version: ""}: "foo/bar", - {Group: "bar", Version: "v1"}: "foo/bar/v1", - {Group: "bar", Version: "v2"}: "foo/bar/v2", - {Group: "foo", Version: "v1"}: "foo/v1", - }, expectedGroups: []types.GroupVersions{ - {PackageName: "bar", Group: types.Group("bar"), Versions: []types.Version{types.Version("v1"), types.Version("v2"), types.Version("")}}, - {PackageName: "foo", Group: types.Group("foo"), Versions: []types.Version{types.Version("v1")}}, + {PackageName: "bar", Group: types.Group("bar"), Versions: []types.PackageVersion{ + {"v1", "foo/bar/v1"}, + {"v2", "foo/bar/v2"}, + {"", "foo/bar"}, + }}, + {PackageName: "foo", Group: types.Group("foo"), Versions: []types.PackageVersion{ + {"v1", "foo/v1"}, + }}, }, }, { args: []string{"foo/bar/v1", "foo/bar/v2", "foo/bar/", "foo/v1"}, def: []string{"foo/bar/v1alpha1", "foo/v1"}, - expected: map[types.GroupVersion]string{ - {Group: "bar", Version: ""}: "foo/bar", - {Group: "bar", Version: "v1"}: "foo/bar/v1", - {Group: "bar", Version: "v2"}: "foo/bar/v2", - {Group: "foo", Version: "v1"}: "foo/v1", - }, expectedGroups: []types.GroupVersions{ - {PackageName: "bar", Group: types.Group("bar"), Versions: []types.Version{types.Version("v1"), types.Version("v2"), types.Version("")}}, - {PackageName: "foo", Group: types.Group("foo"), Versions: []types.Version{types.Version("v1")}}, + {PackageName: "bar", Group: types.Group("bar"), Versions: []types.PackageVersion{ + {"v1", "foo/bar/v1"}, + {"v2", "foo/bar/v2"}, + {"", "foo/bar"}, + }}, + {PackageName: "foo", Group: types.Group("foo"), Versions: []types.PackageVersion{ + {"v1", "foo/v1"}, + }}, }, }, { args: []string{"api/v1", "api"}, - expected: map[types.GroupVersion]string{ - {Group: "api", Version: "v1"}: "core/v1", - {Group: "api", Version: ""}: "core", - }, expectedGroups: []types.GroupVersions{ - {PackageName: "core", Group: types.Group("api"), Versions: []types.Version{types.Version("v1"), types.Version("")}}, + {PackageName: "core", Group: types.Group("api"), Versions: []types.PackageVersion{ + {"v1", "core/v1"}, + {"", "core"}, + }}, + }, + }, + { + args: []string{"foo/v1"}, + importBasePath: "k8s.io/api", + expectedGroups: []types.GroupVersions{ + {PackageName: "foo", Group: types.Group("foo"), Versions: []types.PackageVersion{ + {"v1", "k8s.io/api/foo/v1"}, + }}, }, }, } for i, test := range tests { fs := pflag.NewFlagSet("testGVPackage", pflag.ContinueOnError) - gvp := map[types.GroupVersion]string{} groups := []types.GroupVersions{} - fs.Var(NewGVPackagesValue(&gvp, &groups, test.def), "input", "usage") + 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 { @@ -99,9 +109,6 @@ func TestGVPackageFlag(t *testing.T) { } else if err != nil { t.Errorf("%d: expected nil error, got %v", i, err) } - if !reflect.DeepEqual(gvp, test.expected) { - t.Errorf("%d: expected %+v, got %+v", i, test.expected, gvp) - } if !reflect.DeepEqual(groups, test.expectedGroups) { t.Errorf("%d: expected groups %+v, got groups %+v", i, test.expectedGroups, groups) } diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go index 5d314848f0d..74af0b31d47 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go @@ -233,7 +233,7 @@ func packageForScheme(customArgs *clientgenargs.CustomArgs, clientsetPackage str NextGroup: for _, group := range customArgs.Groups { for _, v := range group.Versions { - if v == "" { + if v.String() == "" { internalClient = true break NextGroup } @@ -258,7 +258,7 @@ NextGroup: DefaultGen: generator.DefaultGen{ OptionalName: "register", }, - InputPackages: customArgs.GroupVersionToInputPath, + InputPackages: customArgs.GroupVersionPackages(), OutputPackage: schemePackage, OutputPath: filepath.Join(srcTreePath, schemePackage), Groups: customArgs.Groups, @@ -274,13 +274,13 @@ NextGroup: // applyGroupOverrides applies group name overrides to each package, if applicable. If there is a // comment of the form "// +groupName=somegroup" or "// +groupName=somegroup.foo.bar.io", use the -// first field (somegroup) as the name of the group when generating. +// first field (somegroup) as the name of the group in Go code, e.g. as the func name in a clientset. // // If the first field of the groupName is not unique within the clientset, use "// +groupName=unique func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.CustomArgs) { // Create a map from "old GV" to "new GV" so we know what changes we need to make. changes := make(map[clientgentypes.GroupVersion]clientgentypes.GroupVersion) - for gv, inputDir := range customArgs.GroupVersionToInputPath { + for gv, inputDir := range customArgs.GroupVersionPackages() { p := universe.Package(inputDir) if override := types.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { newGV := clientgentypes.GroupVersion{ @@ -296,7 +296,7 @@ func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.Cust for _, gvs := range customArgs.Groups { gv := clientgentypes.GroupVersion{ Group: gvs.Group, - Version: gvs.Versions[0], // we only need a version, and the first will do + Version: gvs.Versions[0].Version, // we only need a version, and the first will do } if newGV, ok := changes[gv]; ok { // There's an override, so use it. @@ -312,19 +312,6 @@ func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.Cust } } customArgs.Groups = newGroups - - // Modify customArgs.GroupVersionToInputPath based on the groupName overrides. - newGVToInputPath := make(map[clientgentypes.GroupVersion]string) - for gv, inputDir := range customArgs.GroupVersionToInputPath { - if newGV, ok := changes[gv]; ok { - // There's an override, so use it. - newGVToInputPath[newGV] = inputDir - } else { - // No override. - newGVToInputPath[gv] = inputDir - } - } - customArgs.GroupVersionToInputPath = newGVToInputPath } // Packages makes the client package definition. @@ -344,7 +331,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat gvToTypes := map[clientgentypes.GroupVersion][]*types.Type{} groupGoNames := make(map[clientgentypes.GroupVersion]string) - for gv, inputDir := range customArgs.GroupVersionToInputPath { + for gv, inputDir := range customArgs.GroupVersionPackages() { p := context.Universe.Package(path.Vendorless(inputDir)) // If there's a comment of the form "// +groupGoName=SomeUniqueShortName", use that as @@ -384,7 +371,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat } var packageList []generator.Package - clientsetPackage := filepath.Join(customArgs.ClientsetOutputPath, customArgs.ClientsetName) + clientsetPackage := filepath.Join(arguments.OutputPackagePath, customArgs.ClientsetName) packageList = append(packageList, packageForClientset(customArgs, clientsetPackage, groupGoNames, boilerplate)) packageList = append(packageList, packageForScheme(customArgs, clientsetPackage, arguments.OutputBase, groupGoNames, boilerplate)) @@ -398,11 +385,12 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat } orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} + gvPackages := customArgs.GroupVersionPackages() for _, group := range customArgs.Groups { for _, version := range group.Versions { - gv := clientgentypes.GroupVersion{Group: group.Group, Version: version} + gv := clientgentypes.GroupVersion{Group: group.Group, Version: version.Version} types := gvToTypes[gv] - inputPath := customArgs.GroupVersionToInputPath[gv] + inputPath := gvPackages[gv] packageList = append(packageList, packageForGroup(gv, orderer.OrderTypes(types), clientsetPackage, group.PackageName, groupGoNames[gv], customArgs.ClientsetAPIPath, arguments.OutputBase, inputPath, boilerplate)) if customArgs.FakeClient { packageList = append(packageList, fake.PackageForGroup(gv, orderer.OrderTypes(types), clientsetPackage, group.PackageName, groupGoNames[gv], inputPath, boilerplate)) diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go index 941cc35b0db..ec439c2f7ae 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/fake_client_generator.go @@ -84,12 +84,12 @@ func PackageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, cli } } -func PackageForClientset(customArgs *clientgenargs.CustomArgs, fakeClientsetPackage string, groupGoNames map[clientgentypes.GroupVersion]string, boilerplate []byte) generator.Package { +func PackageForClientset(customArgs *clientgenargs.CustomArgs, clientsetPackage string, groupGoNames map[clientgentypes.GroupVersion]string, 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: filepath.Join(fakeClientsetPackage, "fake"), + PackagePath: filepath.Join(clientsetPackage, "fake"), HeaderText: boilerplate, PackageDocumentation: []byte( `// This package has the automatically generated fake clientset. @@ -107,17 +107,17 @@ func PackageForClientset(customArgs *clientgenargs.CustomArgs, fakeClientsetPack }, groups: customArgs.Groups, groupGoNames: groupGoNames, - fakeClientsetPackage: fakeClientsetPackage, + fakeClientsetPackage: clientsetPackage, outputPackage: "fake", imports: generator.NewImportTracker(), - realClientsetPackage: filepath.Join(customArgs.ClientsetOutputPath, customArgs.ClientsetName), + realClientsetPackage: clientsetPackage, }, &scheme.GenScheme{ DefaultGen: generator.DefaultGen{ OptionalName: "register", }, - InputPackages: customArgs.GroupVersionToInputPath, - OutputPackage: fakeClientsetPackage, + InputPackages: customArgs.GroupVersionPackages(), + OutputPackage: clientsetPackage, Groups: customArgs.Groups, GroupGoNames: groupGoNames, ImportTracker: generator.NewImportTracker(), diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go index b6a8de3f81e..ea9ed8deb45 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/fake/generator_fake_for_clientset.go @@ -63,7 +63,7 @@ func (g *genClientset) Imports(c *generator.Context) (imports []string) { groupClientPackage := filepath.Join(g.fakeClientsetPackage, "typed", group.PackageName, version.NonEmpty()) fakeGroupClientPackage := filepath.Join(groupClientPackage, "fake") - groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{group.Group, version}]) + groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{group.Group, version.Version}]) imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", groupAlias, version.NonEmpty(), groupClientPackage))) imports = append(imports, strings.ToLower(fmt.Sprintf("fake%s%s \"%s\"", groupAlias, version.NonEmpty(), fakeGroupClientPackage))) } @@ -87,7 +87,7 @@ func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Wr // perhaps we can adapt the go2ild framework to this kind of usage. sw := generator.NewSnippetWriter(w, c, "$", "$") - allGroups := clientgentypes.ToGroupVersionPackages(g.groups, g.groupGoNames) + allGroups := clientgentypes.ToGroupVersionInfo(g.groups, g.groupGoNames) sw.Do(common, nil) sw.Do(checkImpl, nil) diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go index a7fdf85d151..de52646600c 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_clientset.go @@ -59,7 +59,7 @@ func (g *genClientset) Imports(c *generator.Context) (imports []string) { for _, group := range g.groups { for _, version := range group.Versions { typedClientPath := filepath.Join(g.clientsetPackage, "typed", group.PackageName, version.NonEmpty()) - groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{group.Group, version}]) + groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{group.Group, version.Version}]) imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", groupAlias, version.NonEmpty(), typedClientPath))) } } @@ -71,7 +71,7 @@ func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Wr // perhaps we can adapt the go2ild framework to this kind of usage. sw := generator.NewSnippetWriter(w, c, "$", "$") - allGroups := clientgentypes.ToGroupVersionPackages(g.groups, g.groupGoNames) + allGroups := clientgentypes.ToGroupVersionInfo(g.groups, g.groupGoNames) m := map[string]interface{}{ "allGroups": allGroups, "Config": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Config"}), diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_group.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_group.go index 3646794ef39..8e569a84f95 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_group.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_group.go @@ -72,13 +72,10 @@ func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer sw := generator.NewSnippetWriter(w, c, "$", "$") apiPath := func(group string) string { - if len(g.apiPath) > 0 { - return `"` + g.apiPath + `"` - } if group == "core" { return `"/api"` } - return `"/apis"` + return `"` + g.apiPath + `"` } groupName := g.group diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go index 416877c4949..f0f726cf728 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/scheme/generator_for_scheme.go @@ -61,18 +61,18 @@ func (g *GenScheme) Imports(c *generator.Context) (imports []string) { imports = append(imports, g.ImportTracker.ImportLines()...) for _, group := range g.Groups { for _, version := range group.Versions { - packagePath := g.InputPackages[clientgentypes.GroupVersion{Group: group.Group, Version: version}] - groupAlias := strings.ToLower(g.GroupGoNames[clientgentypes.GroupVersion{group.Group, version}]) + packagePath := g.InputPackages[clientgentypes.GroupVersion{Group: group.Group, Version: version.Version}] + groupAlias := strings.ToLower(g.GroupGoNames[clientgentypes.GroupVersion{group.Group, version.Version}]) if g.CreateRegistry { // import the install package for internal clientsets instead of the type package with register.go - if version != "" { + if version.Version != "" { packagePath = filepath.Dir(packagePath) } packagePath = filepath.Join(packagePath, "install") imports = append(imports, strings.ToLower(fmt.Sprintf("%s \"%s\"", groupAlias, path.Vendorless(packagePath)))) break } else { - imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", groupAlias, version.NonEmpty(), path.Vendorless(packagePath)))) + imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", groupAlias, version.Version.NonEmpty(), path.Vendorless(packagePath)))) } } } @@ -82,7 +82,7 @@ func (g *GenScheme) Imports(c *generator.Context) (imports []string) { func (g *GenScheme) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { sw := generator.NewSnippetWriter(w, c, "$", "$") - allGroupVersions := clientgentypes.ToGroupVersionPackages(g.Groups, g.GroupGoNames) + allGroupVersions := clientgentypes.ToGroupVersionInfo(g.Groups, g.GroupGoNames) allInstallGroups := clientgentypes.ToGroupInstallPackages(g.Groups, g.GroupGoNames) m := map[string]interface{}{ diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/main.go b/staging/src/k8s.io/code-generator/cmd/client-gen/main.go index 72404808ec2..5869d83a1d5 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/main.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/main.go @@ -19,49 +19,41 @@ package main import ( "flag" - "path" "path/filepath" "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") + genericArgs.OutputPackagePath = "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() - // Prefix with InputBaseDir and add client dirs as input dirs. - for gv, pth := range customArgs.GroupVersionToInputPath { - customArgs.GroupVersionToInputPath[gv] = path.Join(customArgs.InputBasePath, pth) - } - for _, pkg := range customArgs.GroupVersionToInputPath { - arguments.InputDirs = append(arguments.InputDirs, pkg) + // add group version package as input dirs for gengo + for _, pkg := range customArgs.Groups { + for _, v := range pkg.Versions { + genericArgs.InputDirs = append(genericArgs.InputDirs, v.Package) + } } - if err := arguments.Execute( + if err := generatorargs.Validate(genericArgs); err != nil { + glog.Fatalf("Error: %v", err) + } + + if err := genericArgs.Execute( generators.NameSystems(), generators.DefaultNameSystem(), generators.Packages, diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/types/helpers.go b/staging/src/k8s.io/code-generator/cmd/client-gen/types/helpers.go index bc4d9dea306..33e6ac451bf 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/types/helpers.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/types/helpers.go @@ -75,27 +75,27 @@ func (a sortableSliceOfVersions) Less(i, j int) bool { // Determine the default version among versions. If a user calls a group client // without specifying the version (e.g., c.Core(), instead of c.CoreV1()), the // default version will be returned. -func defaultVersion(versions []Version) Version { +func defaultVersion(versions []PackageVersion) Version { var versionStrings []string for _, version := range versions { - versionStrings = append(versionStrings, string(version)) + versionStrings = append(versionStrings, version.Version.String()) } sort.Sort(sortableSliceOfVersions(versionStrings)) return Version(versionStrings[len(versionStrings)-1]) } -// ToGroupVersionPackages is a helper function used by generators for groups. -func ToGroupVersionPackages(groups []GroupVersions, groupGoNames map[GroupVersion]string) []GroupVersionPackage { - var groupVersionPackages []GroupVersionPackage +// ToGroupVersionInfo is a helper function used by generators for groups. +func ToGroupVersionInfo(groups []GroupVersions, groupGoNames map[GroupVersion]string) []GroupVersionInfo { + var groupVersionPackages []GroupVersionInfo for _, group := range groups { defaultVersion := defaultVersion(group.Versions) for _, version := range group.Versions { - groupGoName := groupGoNames[GroupVersion{Group: group.Group, Version: version}] - groupVersionPackages = append(groupVersionPackages, GroupVersionPackage{ + groupGoName := groupGoNames[GroupVersion{Group: group.Group, Version: version.Version}] + groupVersionPackages = append(groupVersionPackages, GroupVersionInfo{ Group: Group(namer.IC(group.Group.NonEmpty())), - Version: Version(namer.IC(version.String())), - PackageAlias: strings.ToLower(groupGoName + version.NonEmpty()), - IsDefaultVersion: version == defaultVersion && version != "", + Version: Version(namer.IC(version.Version.String())), + PackageAlias: strings.ToLower(groupGoName + version.Version.NonEmpty()), + IsDefaultVersion: version.Version == defaultVersion && version.Version != "", GroupGoName: groupGoName, LowerCaseGroupGoName: namer.IL(groupGoName), }) diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/types/types.go b/staging/src/k8s.io/code-generator/cmd/client-gen/types/types.go index a2a87b1e1d6..17fd6e92a70 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/types/types.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/types/types.go @@ -42,20 +42,26 @@ func (g Group) NonEmpty() string { return string(g) } +type PackageVersion struct { + Version + // The fully qualified package, e.g. k8s.io/kubernetes/pkg/apis/apps, where the types.go is found. + Package string +} + type GroupVersion struct { Group Group Version Version } type GroupVersions struct { - // The package name of the group, e.g. extensions or networking + // The name of the package for this group, e.g. apps. PackageName string Group Group - Versions []Version + Versions []PackageVersion } -// GroupVersionPackage contains group name, version name, and the package name client-gen will generate for this group version. -type GroupVersionPackage struct { +// GroupVersionInfo contains all the info around a group version. +type GroupVersionInfo struct { Group Group Version Version // If a user calls a group client without specifying the version (e.g., diff --git a/staging/src/k8s.io/code-generator/cmd/conversion-gen/BUILD b/staging/src/k8s.io/code-generator/cmd/conversion-gen/BUILD index eea6e91524e..a244fae00f8 100644 --- a/staging/src/k8s.io/code-generator/cmd/conversion-gen/BUILD +++ b/staging/src/k8s.io/code-generator/cmd/conversion-gen/BUILD @@ -19,6 +19,7 @@ go_library( deps = [ "//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/code-generator/cmd/conversion-gen/args:go_default_library", "//vendor/k8s.io/code-generator/cmd/conversion-gen/generators:go_default_library", "//vendor/k8s.io/gengo/args:go_default_library", ], @@ -35,6 +36,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//staging/src/k8s.io/code-generator/cmd/conversion-gen/args:all-srcs", "//staging/src/k8s.io/code-generator/cmd/conversion-gen/generators:all-srcs", ], tags = ["automanaged"], diff --git a/staging/src/k8s.io/code-generator/cmd/conversion-gen/args/BUILD b/staging/src/k8s.io/code-generator/cmd/conversion-gen/args/BUILD new file mode 100644 index 00000000000..e06b0b1bce1 --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/conversion-gen/args/BUILD @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["args.go"], + importpath = "k8s.io/code-generator/cmd/conversion-gen/args", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/gengo/args:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) 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..3b7b0123de9 --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/conversion-gen/args/args.go @@ -0,0 +1,83 @@ +/* +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. Peer dirs + // are declared to make the generator pick up manually written conversion funcs from external + // packages. + BasePeerDirs []string + + // Custom peer dirs which are application specific. Peer dirs are declared to make the + // generator pick up manually written conversion funcs from external packages. + 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/BUILD b/staging/src/k8s.io/code-generator/cmd/conversion-gen/generators/BUILD index 49290d578c3..fd9feff4027 100644 --- a/staging/src/k8s.io/code-generator/cmd/conversion-gen/generators/BUILD +++ b/staging/src/k8s.io/code-generator/cmd/conversion-gen/generators/BUILD @@ -11,6 +11,7 @@ go_library( importpath = "k8s.io/code-generator/cmd/conversion-gen/generators", deps = [ "//vendor/github.com/golang/glog:go_default_library", + "//vendor/k8s.io/code-generator/cmd/conversion-gen/args:go_default_library", "//vendor/k8s.io/gengo/args:go_default_library", "//vendor/k8s.io/gengo/generator:go_default_library", "//vendor/k8s.io/gengo/namer:go_default_library", 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 ed7ab27eb20..257fa0a5cb7 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/BUILD b/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/BUILD index d02e19af509..e399aab102c 100644 --- a/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/BUILD +++ b/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/BUILD @@ -19,6 +19,7 @@ go_library( deps = [ "//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/code-generator/cmd/deepcopy-gen/args:go_default_library", "//vendor/k8s.io/gengo/args:go_default_library", "//vendor/k8s.io/gengo/examples/deepcopy-gen/generators:go_default_library", ], @@ -33,6 +34,9 @@ filegroup( filegroup( name = "all-srcs", - srcs = [":package-srcs"], + srcs = [ + ":package-srcs", + "//staging/src/k8s.io/code-generator/cmd/deepcopy-gen/args:all-srcs", + ], tags = ["automanaged"], ) diff --git a/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/args/BUILD b/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/args/BUILD new file mode 100644 index 00000000000..cf86fb77658 --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/args/BUILD @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["args.go"], + importpath = "k8s.io/code-generator/cmd/deepcopy-gen/args", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/gengo/args:go_default_library", + "//vendor/k8s.io/gengo/examples/deepcopy-gen/generators:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) 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/BUILD b/staging/src/k8s.io/code-generator/cmd/defaulter-gen/BUILD index 947327e961d..8306dd8992a 100644 --- a/staging/src/k8s.io/code-generator/cmd/defaulter-gen/BUILD +++ b/staging/src/k8s.io/code-generator/cmd/defaulter-gen/BUILD @@ -19,6 +19,7 @@ go_library( deps = [ "//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/code-generator/cmd/defaulter-gen/args:go_default_library", "//vendor/k8s.io/gengo/args:go_default_library", "//vendor/k8s.io/gengo/examples/defaulter-gen/generators:go_default_library", ], @@ -33,6 +34,9 @@ filegroup( filegroup( name = "all-srcs", - srcs = [":package-srcs"], + srcs = [ + ":package-srcs", + "//staging/src/k8s.io/code-generator/cmd/defaulter-gen/args:all-srcs", + ], tags = ["automanaged"], ) diff --git a/staging/src/k8s.io/code-generator/cmd/defaulter-gen/args/BUILD b/staging/src/k8s.io/code-generator/cmd/defaulter-gen/args/BUILD new file mode 100644 index 00000000000..6f9bb87c54b --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/defaulter-gen/args/BUILD @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["args.go"], + importpath = "k8s.io/code-generator/cmd/defaulter-gen/args", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/gengo/args:go_default_library", + "//vendor/k8s.io/gengo/examples/defaulter-gen/generators:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) 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/BUILD b/staging/src/k8s.io/code-generator/cmd/informer-gen/BUILD index 81eeb5c6110..cd80dab10fe 100644 --- a/staging/src/k8s.io/code-generator/cmd/informer-gen/BUILD +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/BUILD @@ -19,6 +19,7 @@ go_library( deps = [ "//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/code-generator/cmd/informer-gen/args:go_default_library", "//vendor/k8s.io/code-generator/cmd/informer-gen/generators:go_default_library", "//vendor/k8s.io/gengo/args:go_default_library", ], @@ -35,6 +36,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//staging/src/k8s.io/code-generator/cmd/informer-gen/args:all-srcs", "//staging/src/k8s.io/code-generator/cmd/informer-gen/generators:all-srcs", ], tags = ["automanaged"], diff --git a/staging/src/k8s.io/code-generator/cmd/informer-gen/args/BUILD b/staging/src/k8s.io/code-generator/cmd/informer-gen/args/BUILD new file mode 100644 index 00000000000..e2233810152 --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/args/BUILD @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["args.go"], + importpath = "k8s.io/code-generator/cmd/informer-gen/args", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/code-generator/pkg/util:go_default_library", + "//vendor/k8s.io/gengo/args:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) 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/BUILD b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/BUILD index 5b1de7e77a7..9c220b55aa9 100644 --- a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/BUILD +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/BUILD @@ -8,7 +8,6 @@ load( go_library( name = "go_default_library", srcs = [ - "customargs.go", "factory.go", "factoryinterface.go", "generic.go", @@ -22,9 +21,9 @@ go_library( importpath = "k8s.io/code-generator/cmd/informer-gen/generators", deps = [ "//vendor/github.com/golang/glog:go_default_library", - "//vendor/github.com/spf13/pflag:go_default_library", "//vendor/k8s.io/code-generator/cmd/client-gen/generators/util:go_default_library", "//vendor/k8s.io/code-generator/cmd/client-gen/types:go_default_library", + "//vendor/k8s.io/code-generator/cmd/informer-gen/args:go_default_library", "//vendor/k8s.io/gengo/args:go_default_library", "//vendor/k8s.io/gengo/generator:go_default_library", "//vendor/k8s.io/gengo/namer:go_default_library", 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/generic.go b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/generic.go index 891cac31382..54632de0530 100644 --- a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/generic.go +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/generic.go @@ -105,10 +105,10 @@ func (g *genericGenerator) GenerateType(c *generator.Context, t *types.Type, w i Versions: []*version{}, } for _, v := range groupVersions.Versions { - gv := clientgentypes.GroupVersion{Group: groupVersions.Group, Version: v} + gv := clientgentypes.GroupVersion{Group: groupVersions.Group, Version: v.Version} version := &version{ - Name: v.NonEmpty(), - GoName: namer.IC(v.NonEmpty()), + Name: v.Version.NonEmpty(), + GoName: namer.IC(v.Version.NonEmpty()), Resources: orderer.OrderTypes(g.typesForGroupVersion[gv]), } schemeGVs[version] = c.Universe.Variable(types.Name{Package: g.typesForGroupVersion[gv][0].Name.Package, Name: "SchemeGroupVersion"}) diff --git a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go index 253b79f377b..0bba93c4b2e 100644 --- a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/groupinterface.go @@ -69,11 +69,11 @@ func (g *groupInterfaceGenerator) GenerateType(c *generator.Context, t *types.Ty versions := make([]versionData, 0, len(g.groupVersions.Versions)) for _, version := range g.groupVersions.Versions { - gv := clientgentypes.GroupVersion{Group: g.groupVersions.Group, Version: version} + gv := clientgentypes.GroupVersion{Group: g.groupVersions.Group, Version: version.Version} versionPackage := filepath.Join(g.outputPackage, strings.ToLower(gv.Version.NonEmpty())) iface := c.Universe.Type(types.Name{Package: versionPackage, Name: "Interface"}) versions = append(versions, versionData{ - Name: namer.IC(version.NonEmpty()), + Name: namer.IC(version.Version.NonEmpty()), Interface: iface, New: c.Universe.Function(types.Name{Package: versionPackage, Name: "New"}), }) diff --git a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/packages.go b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/packages.go index faa012188df..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 @@ -18,9 +18,11 @@ package generators import ( "fmt" + "path" "path/filepath" "strings" + "github.com/golang/glog" "k8s.io/gengo/args" "k8s.io/gengo/generator" "k8s.io/gengo/namer" @@ -28,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. @@ -112,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) } @@ -158,7 +159,8 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat gv.Version = clientgentypes.Version(parts[len(parts)-1]) targetGroupVersions = externalGroupVersions } - groupPkgName := strings.ToLower(gv.Group.NonEmpty()) + groupPackageName := gv.Group.NonEmpty() + gvPackage := path.Clean(p.Path) // If there's a comment of the form "// +groupName=somegroup" or // "// +groupName=somegroup.foo.bar.io", use the first field (somegroup) as the name of the @@ -169,9 +171,9 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat // If there's a comment of the form "// +groupGoName=SomeUniqueShortName", use that as // the Go group identifier in CamelCase. It defaults - groupGoNames[groupPkgName] = namer.IC(strings.Split(gv.Group.NonEmpty(), ".")[0]) + groupGoNames[groupPackageName] = namer.IC(strings.Split(gv.Group.NonEmpty(), ".")[0]) if override := types.ExtractCommentTags("+", p.Comments)["groupGoName"]; override != nil { - groupGoNames[groupPkgName] = namer.IC(override[0]) + groupGoNames[groupPackageName] = namer.IC(override[0]) } var typesToGenerate []*types.Type @@ -192,23 +194,23 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat continue } - groupVersionsEntry, ok := targetGroupVersions[groupPkgName] + groupVersionsEntry, ok := targetGroupVersions[groupPackageName] if !ok { groupVersionsEntry = clientgentypes.GroupVersions{ - PackageName: groupPkgName, + PackageName: groupPackageName, Group: gv.Group, } } - groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, gv.Version) - targetGroupVersions[groupPkgName] = groupVersionsEntry + groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, clientgentypes.PackageVersion{Version: gv.Version, Package: gvPackage}) + targetGroupVersions[groupPackageName] = groupVersionsEntry orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} typesToGenerate = orderer.OrderTypes(typesToGenerate) if internal { - packageList = append(packageList, versionPackage(internalVersionPackagePath, groupPkgName, gv, groupGoNames[groupPkgName], boilerplate, typesToGenerate, customArgs.InternalClientSetPackage, customArgs.ListersPackage)) + packageList = append(packageList, versionPackage(internalVersionPackagePath, groupPackageName, gv, groupGoNames[groupPackageName], boilerplate, typesToGenerate, customArgs.InternalClientSetPackage, customArgs.ListersPackage)) } else { - packageList = append(packageList, versionPackage(externalVersionPackagePath, groupPkgName, gv, groupGoNames[groupPkgName], boilerplate, typesToGenerate, customArgs.VersionedClientSetPackage, customArgs.ListersPackage)) + packageList = append(packageList, versionPackage(externalVersionPackagePath, groupPackageName, gv, groupGoNames[groupPackageName], boilerplate, typesToGenerate, customArgs.VersionedClientSetPackage, customArgs.ListersPackage)) } } 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/BUILD b/staging/src/k8s.io/code-generator/cmd/lister-gen/BUILD index 186c410117b..5d44c37176b 100644 --- a/staging/src/k8s.io/code-generator/cmd/lister-gen/BUILD +++ b/staging/src/k8s.io/code-generator/cmd/lister-gen/BUILD @@ -18,6 +18,8 @@ go_library( importpath = "k8s.io/code-generator/cmd/lister-gen", deps = [ "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/code-generator/cmd/lister-gen/args:go_default_library", "//vendor/k8s.io/code-generator/cmd/lister-gen/generators:go_default_library", "//vendor/k8s.io/gengo/args:go_default_library", ], @@ -34,6 +36,7 @@ filegroup( name = "all-srcs", srcs = [ ":package-srcs", + "//staging/src/k8s.io/code-generator/cmd/lister-gen/args:all-srcs", "//staging/src/k8s.io/code-generator/cmd/lister-gen/generators:all-srcs", ], tags = ["automanaged"], diff --git a/staging/src/k8s.io/code-generator/cmd/lister-gen/args/BUILD b/staging/src/k8s.io/code-generator/cmd/lister-gen/args/BUILD new file mode 100644 index 00000000000..53c1eefdea6 --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/lister-gen/args/BUILD @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["args.go"], + importpath = "k8s.io/code-generator/cmd/lister-gen/args", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/code-generator/pkg/util:go_default_library", + "//vendor/k8s.io/gengo/args:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) 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/BUILD b/staging/src/k8s.io/code-generator/cmd/openapi-gen/BUILD index bf4a9faef11..533b7cb5d01 100644 --- a/staging/src/k8s.io/code-generator/cmd/openapi-gen/BUILD +++ b/staging/src/k8s.io/code-generator/cmd/openapi-gen/BUILD @@ -18,6 +18,8 @@ go_library( importpath = "k8s.io/code-generator/cmd/openapi-gen", deps = [ "//vendor/github.com/golang/glog:go_default_library", + "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/code-generator/cmd/openapi-gen/args:go_default_library", "//vendor/k8s.io/gengo/args:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/generators:go_default_library", ], @@ -32,6 +34,9 @@ filegroup( filegroup( name = "all-srcs", - srcs = [":package-srcs"], + srcs = [ + ":package-srcs", + "//staging/src/k8s.io/code-generator/cmd/openapi-gen/args:all-srcs", + ], tags = ["automanaged"], ) diff --git a/staging/src/k8s.io/code-generator/cmd/openapi-gen/args/BUILD b/staging/src/k8s.io/code-generator/cmd/openapi-gen/args/BUILD new file mode 100644 index 00000000000..e1eb70ea719 --- /dev/null +++ b/staging/src/k8s.io/code-generator/cmd/openapi-gen/args/BUILD @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["args.go"], + importpath = "k8s.io/code-generator/cmd/openapi-gen/args", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/k8s.io/gengo/args:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) 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/generate-groups.sh b/staging/src/k8s.io/code-generator/generate-groups.sh index 145b12400b4..b92296d96d7 100755 --- a/staging/src/k8s.io/code-generator/generate-groups.sh +++ b/staging/src/k8s.io/code-generator/generate-groups.sh @@ -67,7 +67,7 @@ fi if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/clientset" - ${GOPATH}/bin/client-gen --clientset-name versioned --input-base "" --input $(codegen::join , "${FQ_APIS[@]}") --clientset-path ${OUTPUT_PKG}/clientset "$@" + ${GOPATH}/bin/client-gen --clientset-name versioned --input-base "" --input $(codegen::join , "${FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/clientset "$@" fi if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then diff --git a/staging/src/k8s.io/code-generator/generate-internal-groups.sh b/staging/src/k8s.io/code-generator/generate-internal-groups.sh index b995dd4d56a..0de606d39af 100755 --- a/staging/src/k8s.io/code-generator/generate-internal-groups.sh +++ b/staging/src/k8s.io/code-generator/generate-internal-groups.sh @@ -87,9 +87,9 @@ fi if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/clientset" if [ -n "${INT_APIS_PKG}" ]; then - ${GOPATH}/bin/client-gen --clientset-name internalversion --input-base "" --input $(codegen::join , $(printf '%s/ ' "${INT_FQ_APIS[@]}")) --clientset-path ${OUTPUT_PKG}/clientset "$@" + ${GOPATH}/bin/client-gen --clientset-name internalversion --input-base "" --input $(codegen::join , $(printf '%s/ ' "${INT_FQ_APIS[@]}")) --output-package ${OUTPUT_PKG}/clientset "$@" fi - ${GOPATH}/bin/client-gen --clientset-name versioned --input-base "" --input $(codegen::join , "${EXT_FQ_APIS[@]}") --clientset-path ${OUTPUT_PKG}/clientset "$@" + ${GOPATH}/bin/client-gen --clientset-name versioned --input-base "" --input $(codegen::join , "${EXT_FQ_APIS[@]}") --output-package ${OUTPUT_PKG}/clientset "$@" fi if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then diff --git a/staging/src/k8s.io/code-generator/pkg/util/BUILD b/staging/src/k8s.io/code-generator/pkg/util/BUILD new file mode 100644 index 00000000000..4b6ea978cb2 --- /dev/null +++ b/staging/src/k8s.io/code-generator/pkg/util/BUILD @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["build.go"], + importpath = "k8s.io/code-generator/pkg/util", + visibility = ["//visibility:public"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) 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 +} diff --git a/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh b/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh index 53e9889caeb..527be571b4e 100755 --- a/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh +++ b/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh @@ -51,7 +51,7 @@ apiregistration/ apiregistration/v1beta1 ) INPUT="--input ${INPUT_APIS[@]}" -CLIENTSET_PATH="--clientset-path k8s.io/kube-aggregator/pkg/client/clientset_generated" +CLIENTSET_PATH="--output-package k8s.io/kube-aggregator/pkg/client/clientset_generated" ${CLIENTGEN} ${INPUT_BASE} ${INPUT} ${CLIENTSET_PATH} --output-base ${SCRIPT_BASE} ${CLIENTGEN} --clientset-name="clientset" ${INPUT_BASE} --input apiregistration/v1beta1 ${CLIENTSET_PATH} --output-base ${SCRIPT_BASE} diff --git a/staging/src/k8s.io/metrics/hack/update-codegen.sh b/staging/src/k8s.io/metrics/hack/update-codegen.sh index 52ce78f437a..429a7152c44 100755 --- a/staging/src/k8s.io/metrics/hack/update-codegen.sh +++ b/staging/src/k8s.io/metrics/hack/update-codegen.sh @@ -34,7 +34,7 @@ go build -o "${CLIENTGEN}" ${CODEGEN_PKG}/cmd/client-gen PREFIX=k8s.io/metrics/pkg/apis INPUT_BASE="--input-base ${PREFIX}" -CLIENTSET_PATH="--clientset-path k8s.io/metrics/pkg/client/clientset_generated" +CLIENTSET_PATH="--output-package k8s.io/metrics/pkg/client/clientset_generated" ${CLIENTGEN} --clientset-name="clientset" ${INPUT_BASE} --input metrics/v1alpha1 --input metrics/v1beta1 ${CLIENTSET_PATH} --output-base ${SCRIPT_BASE}