mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 22:17:14 +00:00
Merge pull request #66251 from p0lyn0mial/generate_register_file
Automatic merge from submit-queue (batch tested with PRs 59030, 64666, 66251, 66485, 66813). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. register.go generator for external types **What this PR does / why we need it**: 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. See: https://github.com/kubernetes/kubernetes/issues/65612 **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes # **Special notes for your reviewer**: Passing https://github.com/openshift-evangelists/crd-code-generation/blob/master/pkg/apis/example.com/v1/types.go to register-gen produces the following output: ``` /* Copyright 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. */ // Code generated by ___debug_register_gen. DO NOT EDIT. package v1 import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" ) // GroupName specifies the group name used to register the objects. const GroupName = "example.com" // GroupVersion specifies the group and the version used to register the objects. var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1"} // SchemeGroupVersion is group version used to register these objects // Deprecated: use GroupName instead. var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"} // Resource takes an unqualified resource and returns a Group qualified GroupResource func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } var ( // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. SchemeBuilder runtime.SchemeBuilder localSchemeBuilder = &SchemeBuilder // Depreciated: use Install instead AddToScheme = localSchemeBuilder.AddToScheme Install = localSchemeBuilder.AddToScheme ) func init() { // We only register manually written functions here. The registration of the // generated functions takes place in the generated files. The separation // makes the code compile even when the generated files are missing. localSchemeBuilder.Register(addKnownTypes) } // Adds the list of known types to Scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &Database{}, &DatabaseList{}, ) // AddToGroupVersion allows the serialization of client types like ListOptions. v1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } ``` **Release note**: ``` NONE ```
This commit is contained in:
commit
c06e76ce7f
@ -191,6 +191,7 @@ filegroup(
|
||||
"//staging/src/k8s.io/code-generator/cmd/informer-gen:all-srcs",
|
||||
"//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/register-gen:all-srcs",
|
||||
"//staging/src/k8s.io/code-generator/cmd/set-gen:all-srcs",
|
||||
"//staging/src/k8s.io/code-generator/hack:all-srcs",
|
||||
"//staging/src/k8s.io/code-generator/pkg/util:all-srcs",
|
||||
|
41
staging/src/k8s.io/code-generator/cmd/register-gen/BUILD
Normal file
41
staging/src/k8s.io/code-generator/cmd/register-gen/BUILD
Normal file
@ -0,0 +1,41 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["main.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/code-generator/cmd/register-gen",
|
||||
importpath = "k8s.io/code-generator/cmd/register-gen",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/code-generator/cmd/register-gen/args:go_default_library",
|
||||
"//staging/src/k8s.io/code-generator/cmd/register-gen/generators:go_default_library",
|
||||
"//staging/src/k8s.io/code-generator/pkg/util:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/gengo/args:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "register-gen",
|
||||
embed = [":go_default_library"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/code-generator/cmd/register-gen/args:all-srcs",
|
||||
"//staging/src/k8s.io/code-generator/cmd/register-gen/generators:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
@ -0,0 +1,24 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["args.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/code-generator/cmd/register-gen/args",
|
||||
importpath = "k8s.io/code-generator/cmd/register-gen/args",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//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"],
|
||||
)
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2018 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"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
)
|
||||
|
||||
// NewDefaults returns default arguments for the generator.
|
||||
func NewDefaults() *args.GeneratorArgs {
|
||||
genericArgs := args.Default().WithoutDefaultFlagParsing()
|
||||
genericArgs.OutputFileBaseName = "zz_generated.register"
|
||||
return genericArgs
|
||||
}
|
||||
|
||||
// Validate checks the given arguments.
|
||||
func Validate(genericArgs *args.GeneratorArgs) error {
|
||||
if len(genericArgs.OutputFileBaseName) == 0 {
|
||||
return fmt.Errorf("output file base name cannot be empty")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"packages.go",
|
||||
"register_external.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/code-generator/cmd/register-gen/generators",
|
||||
importpath = "k8s.io/code-generator/cmd/register-gen/generators",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/code-generator/cmd/client-gen/types:go_default_library",
|
||||
"//vendor/github.com/golang/glog: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",
|
||||
"//vendor/k8s.io/gengo/types: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"],
|
||||
)
|
@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright 2018 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 (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
|
||||
"k8s.io/gengo/args"
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
// NameSystems returns the name system used by the generators in this package.
|
||||
func NameSystems() namer.NameSystems {
|
||||
return namer.NameSystems{}
|
||||
}
|
||||
|
||||
// DefaultNameSystem returns the default name system for ordering the types to be
|
||||
// processed by the generators in this package.
|
||||
func DefaultNameSystem() string {
|
||||
return "public"
|
||||
}
|
||||
|
||||
// Packages makes packages to generate.
|
||||
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
|
||||
boilerplate, err := arguments.LoadGoBoilerplate()
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed loading boilerplate: %v", err)
|
||||
}
|
||||
|
||||
packages := generator.Packages{}
|
||||
for _, inputDir := range arguments.InputDirs {
|
||||
pkg := context.Universe.Package(inputDir)
|
||||
internal, err := isInternal(pkg)
|
||||
if err != nil {
|
||||
glog.V(5).Infof("skipping the generation of %s file, due to err %v", arguments.OutputFileBaseName, err)
|
||||
continue
|
||||
}
|
||||
if internal {
|
||||
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)
|
||||
continue
|
||||
}
|
||||
registerFileName := "register.go"
|
||||
searchPath := path.Join(args.DefaultSourceTree(), inputDir, registerFileName)
|
||||
if _, err := os.Stat(path.Join(searchPath)); err == nil {
|
||||
glog.V(5).Infof("skipping the generation of %s file because %s already exists in the path %s", arguments.OutputFileBaseName, registerFileName, searchPath)
|
||||
continue
|
||||
} else if err != nil && !os.IsNotExist(err) {
|
||||
glog.Fatalf("an error %v has occurred while checking if %s exists", err, registerFileName)
|
||||
}
|
||||
|
||||
gv := clientgentypes.GroupVersion{}
|
||||
{
|
||||
pathParts := strings.Split(pkg.Path, "/")
|
||||
if len(pathParts) < 2 {
|
||||
glog.Errorf("the path of the package must contain the group name and the version, path = %s", pkg.Path)
|
||||
continue
|
||||
}
|
||||
gv.Group = clientgentypes.Group(pathParts[len(pathParts)-2])
|
||||
gv.Version = clientgentypes.Version(pathParts[len(pathParts)-1])
|
||||
|
||||
// if there is a comment of the form "// +groupName=somegroup" or "// +groupName=somegroup.foo.bar.io",
|
||||
// extract the fully qualified API group name from it and overwrite the group inferred from the package path
|
||||
if override := types.ExtractCommentTags("+", pkg.DocComments)["groupName"]; override != nil {
|
||||
groupName := override[0]
|
||||
glog.V(5).Infof("overriding the group name with = %s", groupName)
|
||||
gv.Group = clientgentypes.Group(groupName)
|
||||
}
|
||||
}
|
||||
|
||||
typesToRegister := []*types.Type{}
|
||||
for _, t := range pkg.Types {
|
||||
glog.V(5).Infof("considering type = %s", t.Name.String())
|
||||
for _, typeMember := range t.Members {
|
||||
if typeMember.Name == "TypeMeta" && typeMember.Embedded == true {
|
||||
typesToRegister = append(typesToRegister, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packages = append(packages,
|
||||
&generator.DefaultPackage{
|
||||
PackageName: pkg.Name,
|
||||
PackagePath: pkg.Path,
|
||||
HeaderText: boilerplate,
|
||||
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
|
||||
return []generator.Generator{
|
||||
®isterExternalGenerator{
|
||||
DefaultGen: generator.DefaultGen{
|
||||
OptionalName: arguments.OutputFileBaseName,
|
||||
},
|
||||
gv: gv,
|
||||
typesToGenerate: typesToRegister,
|
||||
outputPackage: pkg.Path,
|
||||
imports: generator.NewImportTracker(),
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return packages
|
||||
}
|
||||
|
||||
// isInternal determines whether the given package
|
||||
// contains the internal types or not
|
||||
func isInternal(p *types.Package) (bool, error) {
|
||||
for _, t := range p.Types {
|
||||
for _, member := range t.Members {
|
||||
if member.Name == "TypeMeta" {
|
||||
return !strings.Contains(member.Tags, "json"), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, fmt.Errorf("unable to find TypeMeta for any types in package %s", p.Path)
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright 2018 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 (
|
||||
"io"
|
||||
"sort"
|
||||
|
||||
clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
type registerExternalGenerator struct {
|
||||
generator.DefaultGen
|
||||
outputPackage string
|
||||
gv clientgentypes.GroupVersion
|
||||
typesToGenerate []*types.Type
|
||||
imports namer.ImportTracker
|
||||
}
|
||||
|
||||
var _ generator.Generator = ®isterExternalGenerator{}
|
||||
|
||||
func (g *registerExternalGenerator) Filter(_ *generator.Context, _ *types.Type) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *registerExternalGenerator) Imports(c *generator.Context) (imports []string) {
|
||||
return g.imports.ImportLines()
|
||||
}
|
||||
|
||||
func (g *registerExternalGenerator) Namers(_ *generator.Context) namer.NameSystems {
|
||||
return namer.NameSystems{
|
||||
"raw": namer.NewRawNamer(g.outputPackage, g.imports),
|
||||
}
|
||||
}
|
||||
|
||||
func (g *registerExternalGenerator) Finalize(context *generator.Context, w io.Writer) error {
|
||||
typesToGenerateOnlyNames := make([]string, len(g.typesToGenerate))
|
||||
for index, typeToGenerate := range g.typesToGenerate {
|
||||
typesToGenerateOnlyNames[index] = typeToGenerate.Name.Name
|
||||
}
|
||||
|
||||
// sort the list of types to register, so that the generator produces stable output
|
||||
sort.Strings(typesToGenerateOnlyNames)
|
||||
|
||||
sw := generator.NewSnippetWriter(w, context, "$", "$")
|
||||
m := map[string]interface{}{
|
||||
"groupName": g.gv.Group,
|
||||
"version": g.gv.Version,
|
||||
"types": typesToGenerateOnlyNames,
|
||||
"addToGroupVersion": context.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "AddToGroupVersion"}),
|
||||
"groupVersion": context.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "GroupVersion"}),
|
||||
}
|
||||
sw.Do(registerExternalTypesTemplate, m)
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
var registerExternalTypesTemplate = `
|
||||
// GroupName specifies the group name used to register the objects.
|
||||
const GroupName = "$.groupName$"
|
||||
|
||||
// GroupVersion specifies the group and the version used to register the objects.
|
||||
var GroupVersion = $.groupVersion|raw${Group: GroupName, Version: "$.version$"}
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
// Deprecated: use GroupVersion instead.
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "$.version$"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
// Depreciated: use Install instead
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
Install = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addKnownTypes)
|
||||
}
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
$range .types -$
|
||||
&$.${},
|
||||
$end$
|
||||
)
|
||||
// AddToGroupVersion allows the serialization of client types like ListOptions.
|
||||
$.addToGroupVersion|raw$(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
`
|
52
staging/src/k8s.io/code-generator/cmd/register-gen/main.go
Normal file
52
staging/src/k8s.io/code-generator/cmd/register-gen/main.go
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2018 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 main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
generatorargs "k8s.io/code-generator/cmd/register-gen/args"
|
||||
"k8s.io/code-generator/cmd/register-gen/generators"
|
||||
"k8s.io/code-generator/pkg/util"
|
||||
"k8s.io/gengo/args"
|
||||
)
|
||||
|
||||
func main() {
|
||||
genericArgs := generatorargs.NewDefaults()
|
||||
genericArgs.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), util.BoilerplatePath())
|
||||
genericArgs.AddFlags(pflag.CommandLine)
|
||||
flag.Set("logtostderr", "true")
|
||||
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
|
||||
|
||||
pflag.Parse()
|
||||
if err := generatorargs.Validate(genericArgs); err != nil {
|
||||
glog.Fatalf("Error: %v", err)
|
||||
}
|
||||
|
||||
if err := genericArgs.Execute(
|
||||
generators.NameSystems(),
|
||||
generators.DefaultNameSystem(),
|
||||
generators.Packages,
|
||||
); err != nil {
|
||||
glog.Fatalf("Error: %v", err)
|
||||
}
|
||||
glog.V(2).Info("Completed successfully.")
|
||||
}
|
Loading…
Reference in New Issue
Block a user