Skip to content

Commit dcde050

Browse files
committed
adds a new generator that creates register.go files
this pull brings a new generator that creates register.go file, initially only for the external types. The app takes only one argument --input-dirs and outputs zz_generated.register.go file in the same directory. The name of the generated file can be controlled by passing output-file-base flag.
1 parent d2696d5 commit dcde050

File tree

8 files changed

+445
-0
lines changed

8 files changed

+445
-0
lines changed

staging/src/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ filegroup(
188188
"//staging/src/k8s.io/code-generator/cmd/informer-gen:all-srcs",
189189
"//staging/src/k8s.io/code-generator/cmd/lister-gen:all-srcs",
190190
"//staging/src/k8s.io/code-generator/cmd/openapi-gen:all-srcs",
191+
"//staging/src/k8s.io/code-generator/cmd/register-gen:all-srcs",
191192
"//staging/src/k8s.io/code-generator/cmd/set-gen:all-srcs",
192193
"//staging/src/k8s.io/code-generator/hack:all-srcs",
193194
"//staging/src/k8s.io/code-generator/pkg/util:all-srcs",
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = ["main.go"],
6+
importmap = "k8s.io/kubernetes/vendor/k8s.io/code-generator/cmd/register-gen",
7+
importpath = "k8s.io/code-generator/cmd/register-gen",
8+
visibility = ["//visibility:private"],
9+
deps = [
10+
"//staging/src/k8s.io/code-generator/cmd/register-gen/args:go_default_library",
11+
"//staging/src/k8s.io/code-generator/cmd/register-gen/generators:go_default_library",
12+
"//staging/src/k8s.io/code-generator/pkg/util:go_default_library",
13+
"//vendor/github.com/golang/glog:go_default_library",
14+
"//vendor/github.com/spf13/pflag:go_default_library",
15+
"//vendor/k8s.io/gengo/args:go_default_library",
16+
],
17+
)
18+
19+
go_binary(
20+
name = "register-gen",
21+
embed = [":go_default_library"],
22+
visibility = ["//visibility:public"],
23+
)
24+
25+
filegroup(
26+
name = "package-srcs",
27+
srcs = glob(["**"]),
28+
tags = ["automanaged"],
29+
visibility = ["//visibility:private"],
30+
)
31+
32+
filegroup(
33+
name = "all-srcs",
34+
srcs = [
35+
":package-srcs",
36+
"//staging/src/k8s.io/code-generator/cmd/register-gen/args:all-srcs",
37+
"//staging/src/k8s.io/code-generator/cmd/register-gen/generators:all-srcs",
38+
],
39+
tags = ["automanaged"],
40+
visibility = ["//visibility:public"],
41+
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = ["args.go"],
6+
importmap = "k8s.io/kubernetes/vendor/k8s.io/code-generator/cmd/register-gen/args",
7+
importpath = "k8s.io/code-generator/cmd/register-gen/args",
8+
visibility = ["//visibility:public"],
9+
deps = ["//vendor/k8s.io/gengo/args:go_default_library"],
10+
)
11+
12+
filegroup(
13+
name = "package-srcs",
14+
srcs = glob(["**"]),
15+
tags = ["automanaged"],
16+
visibility = ["//visibility:private"],
17+
)
18+
19+
filegroup(
20+
name = "all-srcs",
21+
srcs = [":package-srcs"],
22+
tags = ["automanaged"],
23+
visibility = ["//visibility:public"],
24+
)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package args
18+
19+
import (
20+
"fmt"
21+
22+
"k8s.io/gengo/args"
23+
)
24+
25+
// NewDefaults returns default arguments for the generator.
26+
func NewDefaults() *args.GeneratorArgs {
27+
genericArgs := args.Default().WithoutDefaultFlagParsing()
28+
genericArgs.OutputFileBaseName = "zz_generated.register"
29+
return genericArgs
30+
}
31+
32+
// Validate checks the given arguments.
33+
func Validate(genericArgs *args.GeneratorArgs) error {
34+
if len(genericArgs.OutputFileBaseName) == 0 {
35+
return fmt.Errorf("output file base name cannot be empty")
36+
}
37+
38+
return nil
39+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = [
6+
"packages.go",
7+
"register_external.go",
8+
],
9+
importmap = "k8s.io/kubernetes/vendor/k8s.io/code-generator/cmd/register-gen/generators",
10+
importpath = "k8s.io/code-generator/cmd/register-gen/generators",
11+
visibility = ["//visibility:public"],
12+
deps = [
13+
"//staging/src/k8s.io/code-generator/cmd/client-gen/types:go_default_library",
14+
"//vendor/github.com/golang/glog:go_default_library",
15+
"//vendor/k8s.io/gengo/args:go_default_library",
16+
"//vendor/k8s.io/gengo/generator:go_default_library",
17+
"//vendor/k8s.io/gengo/namer:go_default_library",
18+
"//vendor/k8s.io/gengo/types:go_default_library",
19+
],
20+
)
21+
22+
filegroup(
23+
name = "package-srcs",
24+
srcs = glob(["**"]),
25+
tags = ["automanaged"],
26+
visibility = ["//visibility:private"],
27+
)
28+
29+
filegroup(
30+
name = "all-srcs",
31+
srcs = [":package-srcs"],
32+
tags = ["automanaged"],
33+
visibility = ["//visibility:public"],
34+
)
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package generators
18+
19+
import (
20+
"fmt"
21+
"os"
22+
"path"
23+
"strings"
24+
25+
"github.com/golang/glog"
26+
27+
clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
28+
"k8s.io/gengo/args"
29+
"k8s.io/gengo/generator"
30+
"k8s.io/gengo/namer"
31+
"k8s.io/gengo/types"
32+
)
33+
34+
// NameSystems returns the name system used by the generators in this package.
35+
func NameSystems() namer.NameSystems {
36+
return namer.NameSystems{}
37+
}
38+
39+
// DefaultNameSystem returns the default name system for ordering the types to be
40+
// processed by the generators in this package.
41+
func DefaultNameSystem() string {
42+
return "public"
43+
}
44+
45+
// Packages makes packages to generate.
46+
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
47+
boilerplate, err := arguments.LoadGoBoilerplate()
48+
if err != nil {
49+
glog.Fatalf("Failed loading boilerplate: %v", err)
50+
}
51+
52+
packages := generator.Packages{}
53+
for _, inputDir := range arguments.InputDirs {
54+
pkg := context.Universe.Package(inputDir)
55+
internal, err := isInternal(pkg)
56+
if err != nil {
57+
glog.V(5).Infof("skipping the generation of %s file, due to err %v", arguments.OutputFileBaseName, err)
58+
continue
59+
}
60+
if internal {
61+
glog.V(5).Infof("skipping the generation of %s file because %s package contains internal types, note that internal types don't have \"json\" tags", arguments.OutputFileBaseName, pkg.Name)
62+
continue
63+
}
64+
registerFileName := "register.go"
65+
searchPath := path.Join(args.DefaultSourceTree(), inputDir, registerFileName)
66+
if _, err := os.Stat(path.Join(searchPath)); err == nil {
67+
glog.V(5).Infof("skipping the generation of %s file because %s already exists in the path %s", arguments.OutputFileBaseName, registerFileName, searchPath)
68+
continue
69+
} else if err != nil && !os.IsNotExist(err) {
70+
glog.Fatalf("an error %v has occurred while checking if %s exists", err, registerFileName)
71+
}
72+
73+
gv := clientgentypes.GroupVersion{}
74+
{
75+
pathParts := strings.Split(pkg.Path, "/")
76+
if len(pathParts) < 2 {
77+
glog.Errorf("the path of the package must contain the group name and the version, path = %s", pkg.Path)
78+
continue
79+
}
80+
gv.Group = clientgentypes.Group(pathParts[len(pathParts)-2])
81+
gv.Version = clientgentypes.Version(pathParts[len(pathParts)-1])
82+
83+
// if there is a comment of the form "// +groupName=somegroup" or "// +groupName=somegroup.foo.bar.io",
84+
// extract the fully qualified API group name from it and overwrite the group inferred from the package path
85+
if override := types.ExtractCommentTags("+", pkg.DocComments)["groupName"]; override != nil {
86+
groupName := override[0]
87+
glog.V(5).Infof("overriding the group name with = %s", groupName)
88+
gv.Group = clientgentypes.Group(groupName)
89+
}
90+
}
91+
92+
typesToRegister := []*types.Type{}
93+
for _, t := range pkg.Types {
94+
glog.V(5).Infof("considering type = %s", t.Name.String())
95+
for _, typeMember := range t.Members {
96+
if typeMember.Name == "TypeMeta" && typeMember.Embedded == true {
97+
typesToRegister = append(typesToRegister, t)
98+
}
99+
}
100+
}
101+
102+
packages = append(packages,
103+
&generator.DefaultPackage{
104+
PackageName: pkg.Name,
105+
PackagePath: pkg.Path,
106+
HeaderText: boilerplate,
107+
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
108+
return []generator.Generator{
109+
&registerExternalGenerator{
110+
DefaultGen: generator.DefaultGen{
111+
OptionalName: arguments.OutputFileBaseName,
112+
},
113+
gv: gv,
114+
typesToGenerate: typesToRegister,
115+
outputPackage: pkg.Path,
116+
imports: generator.NewImportTracker(),
117+
},
118+
}
119+
},
120+
})
121+
}
122+
123+
return packages
124+
}
125+
126+
// isInternal determines whether the given package
127+
// contains the internal types or not
128+
func isInternal(p *types.Package) (bool, error) {
129+
for _, t := range p.Types {
130+
for _, member := range t.Members {
131+
if member.Name == "TypeMeta" {
132+
return !strings.Contains(member.Tags, "json"), nil
133+
}
134+
}
135+
}
136+
return false, fmt.Errorf("unable to find TypeMeta for any types in package %s", p.Path)
137+
}

0 commit comments

Comments
 (0)