1
0
Fork 0

chore: update docker and k8s

This commit is contained in:
Ludovic Fernandez 2019-08-05 18:24:03 +02:00 committed by Traefiker Bot
parent 2b5c7f9e91
commit c2d440a914
1283 changed files with 67741 additions and 27918 deletions

View file

@ -1,3 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- lavalamp
- wojtek-t

View file

@ -1,4 +1,4 @@
See [generating-clientset.md](https://git.k8s.io/community/contributors/devel/generating-clientset.md)
See [generating-clientset.md](https://git.k8s.io/community/contributors/devel/sig-api-machinery/generating-clientset.md)
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/staging/src/k8s.io/code-generator/client-gen/README.md?pixel)]()

View file

@ -27,12 +27,13 @@ import (
"k8s.io/code-generator/cmd/client-gen/generators/util"
"k8s.io/code-generator/cmd/client-gen/path"
clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
codegennamer "k8s.io/code-generator/pkg/namer"
"k8s.io/gengo/args"
"k8s.io/gengo/generator"
"k8s.io/gengo/namer"
"k8s.io/gengo/types"
"github.com/golang/glog"
"k8s.io/klog"
)
// NameSystems returns the name system used by the generators in this package.
@ -101,7 +102,7 @@ func NameSystems() namer.NameSystems {
"publicPlural": publicPluralNamer,
"privatePlural": privatePluralNamer,
"allLowercasePlural": lowercaseNamer,
"resource": NewTagOverrideNamer("resourceName", lowercaseNamer),
"resource": codegennamer.NewTagOverrideNamer("resourceName", lowercaseNamer),
}
}
@ -130,7 +131,7 @@ func DefaultNameSystem() string {
}
func packageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetPackage string, groupPackageName string, groupGoName string, apiPath string, srcTreePath string, inputPackage string, boilerplate []byte) generator.Package {
groupVersionClientPackage := strings.ToLower(filepath.Join(clientsetPackage, "typed", groupPackageName, gv.Version.NonEmpty()))
groupVersionClientPackage := filepath.Join(clientsetPackage, "typed", strings.ToLower(groupPackageName), strings.ToLower(gv.Version.NonEmpty()))
return &generator.DefaultPackage{
PackageName: strings.ToLower(gv.Version.NonEmpty()),
PackagePath: groupVersionClientPackage,
@ -318,12 +319,12 @@ func applyGroupOverrides(universe types.Universe, customArgs *clientgenargs.Cust
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
boilerplate, err := arguments.LoadGoBoilerplate()
if err != nil {
glog.Fatalf("Failed loading boilerplate: %v", err)
klog.Fatalf("Failed loading boilerplate: %v", err)
}
customArgs, ok := arguments.CustomArgs.(*clientgenargs.CustomArgs)
if !ok {
glog.Fatalf("cannot convert arguments.CustomArgs to clientgenargs.CustomArgs")
klog.Fatalf("cannot convert arguments.CustomArgs to clientgenargs.CustomArgs")
}
includedTypesOverrides := customArgs.IncludedTypesOverrides
@ -400,27 +401,3 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
return generator.Packages(packageList)
}
// tagOverrideNamer is a namer which pulls names from a given tag, if specified,
// and otherwise falls back to a different namer.
type tagOverrideNamer struct {
tagName string
fallback namer.Namer
}
func (n *tagOverrideNamer) Name(t *types.Type) string {
if nameOverride := extractTag(n.tagName, append(t.SecondClosestCommentLines, t.CommentLines...)); nameOverride != "" {
return nameOverride
}
return n.fallback.Name(t)
}
// NewTagOverrideNamer creates a namer.Namer which uses the contents of the given tag as
// the name, or falls back to another Namer if the tag is not present.
func NewTagOverrideNamer(tagName string, fallback namer.Namer) namer.Namer {
return &tagOverrideNamer{
tagName: tagName,
fallback: fallback,
}
}

View file

@ -30,9 +30,9 @@ import (
)
func PackageForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetPackage string, groupPackageName string, groupGoName string, inputPackage string, boilerplate []byte) generator.Package {
outputPackage := strings.ToLower(filepath.Join(clientsetPackage, "typed", groupPackageName, gv.Version.NonEmpty(), "fake"))
outputPackage := filepath.Join(clientsetPackage, "typed", strings.ToLower(groupPackageName), strings.ToLower(gv.Version.NonEmpty()), "fake")
// TODO: should make this a function, called by here and in client-generator.go
realClientPackage := filepath.Join(clientsetPackage, "typed", groupPackageName, gv.Version.NonEmpty())
realClientPackage := filepath.Join(clientsetPackage, "typed", strings.ToLower(groupPackageName), strings.ToLower(gv.Version.NonEmpty()))
return &generator.DefaultPackage{
PackageName: "fake",
PackagePath: outputPackage,

View file

@ -60,12 +60,12 @@ func (g *genClientset) Imports(c *generator.Context) (imports []string) {
imports = append(imports, g.imports.ImportLines()...)
for _, group := range g.groups {
for _, version := range group.Versions {
groupClientPackage := filepath.Join(g.fakeClientsetPackage, "typed", group.PackageName, version.NonEmpty())
groupClientPackage := filepath.Join(g.fakeClientsetPackage, "typed", strings.ToLower(group.PackageName), strings.ToLower(version.NonEmpty()))
fakeGroupClientPackage := filepath.Join(groupClientPackage, "fake")
groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{Group: group.Group, Version: 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)))
imports = append(imports, fmt.Sprintf("%s%s \"%s\"", groupAlias, strings.ToLower(version.NonEmpty()), groupClientPackage))
imports = append(imports, fmt.Sprintf("fake%s%s \"%s\"", groupAlias, strings.ToLower(version.NonEmpty()), fakeGroupClientPackage))
}
}
// the package that has the clientset Interface
@ -102,10 +102,6 @@ func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Wr
}
sw.Do(clientsetInterfaceImplTemplate, m)
// don't generated the default method if generating internalversion clientset
if group.IsDefaultVersion && group.Version != "" {
sw.Do(clientsetInterfaceDefaultVersionImpl, m)
}
}
return sw.Error()
@ -125,7 +121,7 @@ func NewSimpleClientset(objects ...runtime.Object) *Clientset {
}
}
cs := &Clientset{}
cs := &Clientset{tracker: o}
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
cs.AddReactor("*", "*", testing.ObjectReaction(o))
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
@ -147,11 +143,16 @@ func NewSimpleClientset(objects ...runtime.Object) *Clientset {
type Clientset struct {
testing.Fake
discovery *fakediscovery.FakeDiscovery
tracker testing.ObjectTracker
}
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
return c.discovery
}
func (c *Clientset) Tracker() testing.ObjectTracker {
return c.tracker
}
`
var checkImpl = `

View file

@ -64,7 +64,7 @@ func (g *genFakeForGroup) Namers(c *generator.Context) namer.NameSystems {
func (g *genFakeForGroup) Imports(c *generator.Context) (imports []string) {
imports = g.imports.ImportLines()
if len(g.types) != 0 {
imports = append(imports, strings.ToLower(fmt.Sprintf("%s \"%s\"", filepath.Base(g.realClientPackage), g.realClientPackage)))
imports = append(imports, fmt.Sprintf("%s \"%s\"", strings.ToLower(filepath.Base(g.realClientPackage)), g.realClientPackage))
}
return imports
}

View file

@ -362,7 +362,7 @@ var getSubresourceTemplate = `
func (c *Fake$.type|publicPlural$) Get($.type|private$Name string, options $.GetOptions|raw$) (result *$.resultType|raw$, err error) {
obj, err := c.Fake.
$if .namespaced$Invokes($.NewGetSubresourceAction|raw$($.type|allLowercasePlural$Resource, c.ns, "$.subresourcePath$", $.type|private$Name), &$.resultType|raw${})
$else$Invokes($.NewRootGetSubresourceAction|raw$($.type|allLowercasePlural$Resource, $.type|private$Name), &$.resultType|raw${})$end$
$else$Invokes($.NewRootGetSubresourceAction|raw$($.type|allLowercasePlural$Resource, "$.subresourcePath$", $.type|private$Name), &$.resultType|raw${})$end$
if obj == nil {
return nil, err
}
@ -469,8 +469,8 @@ var patchTemplate = `
// Patch applies the patch and returns the patched $.resultType|private$.
func (c *Fake$.type|publicPlural$) Patch(name string, pt $.PatchType|raw$, data []byte, subresources ...string) (result *$.resultType|raw$, err error) {
obj, err := c.Fake.
$if .namespaced$Invokes($.NewPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, c.ns, name, data, subresources... ), &$.resultType|raw${})
$else$Invokes($.NewRootPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, name, data, subresources...), &$.resultType|raw${})$end$
$if .namespaced$Invokes($.NewPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, c.ns, name, pt, data, subresources... ), &$.resultType|raw${})
$else$Invokes($.NewRootPatchSubresourceAction|raw$($.type|allLowercasePlural$Resource, name, pt, data, subresources...), &$.resultType|raw${})$end$
if obj == nil {
return nil, err
}

View file

@ -58,9 +58,9 @@ func (g *genClientset) Imports(c *generator.Context) (imports []string) {
imports = append(imports, g.imports.ImportLines()...)
for _, group := range g.groups {
for _, version := range group.Versions {
typedClientPath := filepath.Join(g.clientsetPackage, "typed", group.PackageName, version.NonEmpty())
typedClientPath := filepath.Join(g.clientsetPackage, "typed", strings.ToLower(group.PackageName), strings.ToLower(version.NonEmpty()))
groupAlias := strings.ToLower(g.groupGoNames[clientgentypes.GroupVersion{Group: group.Group, Version: version.Version}])
imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", groupAlias, version.NonEmpty(), typedClientPath)))
imports = append(imports, fmt.Sprintf("%s%s \"%s\"", groupAlias, strings.ToLower(version.NonEmpty()), typedClientPath))
}
}
return
@ -88,10 +88,6 @@ func (g *genClientset) GenerateType(c *generator.Context, t *types.Type, w io.Wr
sw.Do(clientsetTemplate, m)
for _, g := range allGroups {
sw.Do(clientsetInterfaceImplTemplate, g)
// don't generated the default method if generating internalversion clientset
if g.IsDefaultVersion && g.Version != "" {
sw.Do(clientsetInterfaceDefaultVersionImpl, g)
}
}
sw.Do(getDiscoveryTemplate, m)
sw.Do(newClientsetForConfigTemplate, m)
@ -105,9 +101,7 @@ var clientsetInterface = `
type Interface interface {
Discovery() $.DiscoveryInterface|raw$
$range .allGroups$$.GroupGoName$$.Version$() $.PackageAlias$.$.GroupGoName$$.Version$Interface
$if .IsDefaultVersion$// Deprecated: please explicitly pick a version if possible.
$.GroupGoName$() $.PackageAlias$.$.GroupGoName$$.Version$Interface
$end$$end$
$end$
}
`
@ -128,14 +122,6 @@ func (c *Clientset) $.GroupGoName$$.Version$() $.PackageAlias$.$.GroupGoName$$.V
}
`
var clientsetInterfaceDefaultVersionImpl = `
// Deprecated: $.GroupGoName$ retrieves the default version of $.GroupGoName$Client.
// Please explicitly pick a version.
func (c *Clientset) $.GroupGoName$() $.PackageAlias$.$.GroupGoName$$.Version$Interface {
return c.$.LowerCaseGroupGoName$$.Version$
}
`
var getDiscoveryTemplate = `
// Discovery retrieves the DiscoveryClient
func (c *Clientset) Discovery() $.DiscoveryInterface|raw$ {

View file

@ -98,7 +98,6 @@ func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer
"apiPath": apiPath(g.group),
"schemaGroupVersion": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime/schema", Name: "GroupVersion"}),
"runtimeAPIVersionInternal": c.Universe.Variable(types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "APIVersionInternal"}),
"serializerDirectCodecFactory": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime/serializer", Name: "DirectCodecFactory"}),
"restConfig": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Config"}),
"restDefaultKubernetesUserAgent": c.Universe.Function(types.Name{Package: "k8s.io/client-go/rest", Name: "DefaultKubernetesUserAgent"}),
"restRESTClientInterface": c.Universe.Type(types.Name{Package: "k8s.io/client-go/rest", Name: "Interface"}),
@ -236,7 +235,7 @@ func setConfigDefaults(config *$.restConfig|raw$) error {
gv := $.SchemeGroupVersion|raw$
config.GroupVersion = &gv
config.APIPath = $.apiPath$
config.NegotiatedSerializer = $.serializerDirectCodecFactory|raw${CodecFactory: scheme.Codecs}
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
if config.UserAgent == "" {
config.UserAgent = $.restDefaultKubernetesUserAgent|raw$()

View file

@ -387,11 +387,16 @@ func new$.type|publicPlural$(c *$.GroupGoName$$.Version$Client) *$.type|privateP
var listTemplate = `
// List takes label and field selectors, and returns the list of $.resultType|publicPlural$ that match those selectors.
func (c *$.type|privatePlural$) List(opts $.ListOptions|raw$) (result *$.resultType|raw$List, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil{
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &$.resultType|raw$List{}
err = c.client.Get().
$if .namespaced$Namespace(c.ns).$end$
Resource("$.type|resource$").
VersionedParams(&opts, $.schemeParameterCodec|raw$).
Timeout(timeout).
Do().
Into(result)
return
@ -401,6 +406,10 @@ func (c *$.type|privatePlural$) List(opts $.ListOptions|raw$) (result *$.resultT
var listSubresourceTemplate = `
// List takes $.type|raw$ name, label and field selectors, and returns the list of $.resultType|publicPlural$ that match those selectors.
func (c *$.type|privatePlural$) List($.type|private$Name string, opts $.ListOptions|raw$) (result *$.resultType|raw$List, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil{
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &$.resultType|raw$List{}
err = c.client.Get().
$if .namespaced$Namespace(c.ns).$end$
@ -408,6 +417,7 @@ func (c *$.type|privatePlural$) List($.type|private$Name string, opts $.ListOpti
Name($.type|private$Name).
SubResource("$.subresourcePath$").
VersionedParams(&opts, $.schemeParameterCodec|raw$).
Timeout(timeout).
Do().
Into(result)
return
@ -461,10 +471,15 @@ func (c *$.type|privatePlural$) Delete(name string, options *$.DeleteOptions|raw
var deleteCollectionTemplate = `
// DeleteCollection deletes a collection of objects.
func (c *$.type|privatePlural$) DeleteCollection(options *$.DeleteOptions|raw$, listOptions $.ListOptions|raw$) error {
var timeout time.Duration
if listOptions.TimeoutSeconds != nil{
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
}
return c.client.Delete().
$if .namespaced$Namespace(c.ns).$end$
Resource("$.type|resource$").
VersionedParams(&listOptions, $.schemeParameterCodec|raw$).
Timeout(timeout).
Body(options).
Do().
Error()
@ -553,11 +568,16 @@ func (c *$.type|privatePlural$) UpdateStatus($.type|private$ *$.type|raw$) (resu
var watchTemplate = `
// Watch returns a $.watchInterface|raw$ that watches the requested $.type|privatePlural$.
func (c *$.type|privatePlural$) Watch(opts $.ListOptions|raw$) ($.watchInterface|raw$, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil{
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
$if .namespaced$Namespace(c.ns).$end$
Resource("$.type|resource$").
VersionedParams(&opts, $.schemeParameterCodec|raw$).
Timeout(timeout).
Watch()
}
`

View file

@ -69,10 +69,11 @@ func (g *GenScheme) Imports(c *generator.Context) (imports []string) {
packagePath = filepath.Dir(packagePath)
}
packagePath = filepath.Join(packagePath, "install")
imports = append(imports, strings.ToLower(fmt.Sprintf("%s \"%s\"", groupAlias, path.Vendorless(packagePath))))
imports = append(imports, fmt.Sprintf("%s \"%s\"", groupAlias, path.Vendorless(packagePath)))
break
} else {
imports = append(imports, strings.ToLower(fmt.Sprintf("%s%s \"%s\"", groupAlias, version.Version.NonEmpty(), path.Vendorless(packagePath))))
imports = append(imports, fmt.Sprintf("%s%s \"%s\"", groupAlias, strings.ToLower(version.Version.NonEmpty()), path.Vendorless(packagePath)))
}
}
}
@ -93,6 +94,8 @@ func (g *GenScheme) GenerateType(c *generator.Context, t *types.Type, w io.Write
"runtimeNewScheme": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "NewScheme"}),
"serializerNewCodecFactory": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/runtime/serializer", Name: "NewCodecFactory"}),
"runtimeScheme": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "Scheme"}),
"runtimeSchemeBuilder": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime", Name: "SchemeBuilder"}),
"runtimeUtilMust": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/util/runtime", Name: "Must"}),
"schemaGroupVersion": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/runtime/schema", Name: "GroupVersion"}),
"metav1AddToGroupVersion": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "AddToGroupVersion"}),
}
@ -130,10 +133,10 @@ func (g *GenScheme) GenerateType(c *generator.Context, t *types.Type, w io.Write
var globalsTemplate = `
var $.Scheme$ = $.runtimeNewScheme|raw$()
var $.Codecs$ = $.serializerNewCodecFactory|raw$($.Scheme$)
var $.ParameterCodec$ = $.runtimeNewParameterCodec|raw$($.Scheme$)
`
var $.ParameterCodec$ = $.runtimeNewParameterCodec|raw$($.Scheme$)`
var registryRegistration = `
func init() {
$.metav1AddToGroupVersion|raw$($.Scheme$, $.schemaGroupVersion|raw${Version: "v1"})
Install($.Scheme$)
@ -151,11 +154,13 @@ func Install(scheme *$.runtimeScheme|raw$) {
`
var simpleRegistration = `
func init() {
$.metav1AddToGroupVersion|raw$($.Scheme$, $.schemaGroupVersion|raw${Version: "v1"})
AddToScheme($.Scheme$)
var localSchemeBuilder = $.runtimeSchemeBuilder|raw${
$- range .allGroupVersions$
$.PackageAlias$.AddToScheme,
$- end$
$if .customRegister$
ExtraAddToScheme,
$end -$
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
@ -168,16 +173,14 @@ func init() {
// )
//
// kclientset, _ := kubernetes.NewForConfig(c)
// aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
//
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
// correctly.
func AddToScheme(scheme *$.runtimeScheme|raw$) {
$- range .allGroupVersions$
$.PackageAlias$.AddToScheme(scheme)
$- end$
$if .customRegister$
ExtraAddToScheme(scheme)
$end -$
var AddToScheme = localSchemeBuilder.AddToScheme
func init() {
$.metav1AddToGroupVersion|raw$($.Scheme$, $.schemaGroupVersion|raw${Version: "v1"})
$.runtimeUtilMust|raw$(AddToScheme($.Scheme$))
}
`

View file

@ -1,32 +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 (
"k8s.io/gengo/types"
)
// extractTag gets the comment-tags for the key. If the tag did not exist, it
// returns the empty string.
func extractTag(key string, lines []string) string {
val, present := types.ExtractCommentTags("+", lines)[key]
if !present || len(val) < 1 {
return ""
}
return val[0]
}

View file

@ -21,9 +21,9 @@ import (
"flag"
"path/filepath"
"github.com/golang/glog"
"github.com/spf13/pflag"
"k8s.io/gengo/args"
"k8s.io/klog"
generatorargs "k8s.io/code-generator/cmd/client-gen/args"
"k8s.io/code-generator/cmd/client-gen/generators"
@ -31,6 +31,7 @@ import (
)
func main() {
klog.InitFlags(nil)
genericArgs, customArgs := generatorargs.NewDefaults()
// Override defaults.
@ -52,7 +53,7 @@ func main() {
}
if err := generatorargs.Validate(genericArgs); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
if err := genericArgs.Execute(
@ -60,6 +61,6 @@ func main() {
generators.DefaultNameSystem(),
generators.Packages,
); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
}

View file

@ -73,7 +73,7 @@ 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
// without specifying the version (e.g., c.CoreV1(), instead of c.CoreV1()), the
// default version will be returned.
func defaultVersion(versions []PackageVersion) Version {
var versionStrings []string
@ -88,14 +88,12 @@ func defaultVersion(versions []PackageVersion) Version {
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.Version}]
groupVersionPackages = append(groupVersionPackages, GroupVersionInfo{
Group: Group(namer.IC(group.Group.NonEmpty())),
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),
})

View file

@ -62,11 +62,8 @@ type GroupVersions 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.,
// c.Core(), instead of c.CoreV1()), the default version will be returned.
IsDefaultVersion bool
Group Group
Version Version
PackageAlias string
GroupGoName string
LowerCaseGroupGoName string

View file

@ -29,7 +29,7 @@ import (
"k8s.io/gengo/namer"
"k8s.io/gengo/types"
"github.com/golang/glog"
"k8s.io/klog"
conversionargs "k8s.io/code-generator/cmd/conversion-gen/args"
)
@ -124,10 +124,10 @@ type conversionFuncMap map[conversionPair]*types.Type
// Returns all manually-defined conversion functions in the package.
func getManualConversionFunctions(context *generator.Context, pkg *types.Package, manualMap conversionFuncMap) {
if pkg == nil {
glog.Warningf("Skipping nil package passed to getManualConversionFunctions")
klog.Warningf("Skipping nil package passed to getManualConversionFunctions")
return
}
glog.V(5).Infof("Scanning for conversion functions in %v", pkg.Name)
klog.V(5).Infof("Scanning for conversion functions in %v", pkg.Name)
scopeName := types.Ref(conversionPackagePath, "Scope").Name
errorName := types.Ref("", "error").Name
@ -136,34 +136,34 @@ func getManualConversionFunctions(context *generator.Context, pkg *types.Package
for _, f := range pkg.Functions {
if f.Underlying == nil || f.Underlying.Kind != types.Func {
glog.Errorf("Malformed function: %#v", f)
klog.Errorf("Malformed function: %#v", f)
continue
}
if f.Underlying.Signature == nil {
glog.Errorf("Function without signature: %#v", f)
klog.Errorf("Function without signature: %#v", f)
continue
}
glog.V(8).Infof("Considering function %s", f.Name)
klog.V(8).Infof("Considering function %s", f.Name)
signature := f.Underlying.Signature
// Check whether the function is conversion function.
// Note that all of them have signature:
// func Convert_inType_To_outType(inType, outType, conversion.Scope) error
if signature.Receiver != nil {
glog.V(8).Infof("%s has a receiver", f.Name)
klog.V(8).Infof("%s has a receiver", f.Name)
continue
}
if len(signature.Parameters) != 3 || signature.Parameters[2].Name != scopeName {
glog.V(8).Infof("%s has wrong parameters", f.Name)
klog.V(8).Infof("%s has wrong parameters", f.Name)
continue
}
if len(signature.Results) != 1 || signature.Results[0].Name != errorName {
glog.V(8).Infof("%s has wrong results", f.Name)
klog.V(8).Infof("%s has wrong results", f.Name)
continue
}
inType := signature.Parameters[0]
outType := signature.Parameters[1]
if inType.Kind != types.Pointer || outType.Kind != types.Pointer {
glog.V(8).Infof("%s has wrong parameter types", f.Name)
klog.V(8).Infof("%s has wrong parameter types", f.Name)
continue
}
// Now check if the name satisfies the convention.
@ -171,15 +171,19 @@ func getManualConversionFunctions(context *generator.Context, pkg *types.Package
args := argsFromType(inType.Elem, outType.Elem)
sw.Do("Convert_$.inType|public$_To_$.outType|public$", args)
if f.Name.Name == buffer.String() {
glog.V(4).Infof("Found conversion function %s", f.Name)
klog.V(4).Infof("Found conversion function %s", f.Name)
key := conversionPair{inType.Elem, outType.Elem}
// We might scan the same package twice, and that's OK.
if v, ok := manualMap[key]; ok && v != nil && v.Name.Package != pkg.Path {
panic(fmt.Sprintf("duplicate static conversion defined: %s -> %s", key.inType, key.outType))
panic(fmt.Sprintf("duplicate static conversion defined: %s -> %s from:\n%s.%s\n%s.%s", key.inType, key.outType, v.Name.Package, v.Name.Name, f.Name.Package, f.Name.Name))
}
manualMap[key] = f
} else {
glog.V(8).Infof("%s has wrong name", f.Name)
// prevent user error when they don't get the correct conversion signature
if strings.HasPrefix(f.Name.Name, "Convert_") {
klog.Errorf("Rename function %s %s -> %s to match expected conversion signature", f.Name.Package, f.Name.Name, buffer.String())
}
klog.V(8).Infof("%s has wrong name", f.Name)
}
buffer.Reset()
}
@ -188,7 +192,7 @@ func getManualConversionFunctions(context *generator.Context, pkg *types.Package
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
boilerplate, err := arguments.LoadGoBoilerplate()
if err != nil {
glog.Fatalf("Failed loading boilerplate: %v", err)
klog.Fatalf("Failed loading boilerplate: %v", err)
}
packages := generator.Packages{}
@ -216,7 +220,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
}
processed[i] = true
glog.V(5).Infof("considering pkg %q", i)
klog.V(5).Infof("considering pkg %q", i)
pkg := context.Universe[i]
// typesPkg is where the versioned types are defined. Sometimes it is
// different from pkg. For example, kubernetes core/v1 types are defined
@ -235,9 +239,9 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
// in their doc.go file.
peerPkgs := extractTag(pkg.Comments)
if peerPkgs != nil {
glog.V(5).Infof(" tags: %q", peerPkgs)
klog.V(5).Infof(" tags: %q", peerPkgs)
} else {
glog.V(5).Infof(" no tag")
klog.V(5).Infof(" no tag")
continue
}
skipUnsafe := false
@ -251,14 +255,14 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
externalTypesValues := extractExternalTypesTag(pkg.Comments)
if externalTypesValues != nil {
if len(externalTypesValues) != 1 {
glog.Fatalf(" expect only one value for %q tag, got: %q", externalTypesTagName, externalTypesValues)
klog.Fatalf(" expect only one value for %q tag, got: %q", externalTypesTagName, externalTypesValues)
}
externalTypes := externalTypesValues[0]
glog.V(5).Infof(" external types tags: %q", externalTypes)
klog.V(5).Infof(" external types tags: %q", externalTypes)
var err error
typesPkg, err = context.AddDirectory(externalTypes)
if err != nil {
glog.Fatalf("cannot import package %s", externalTypes)
klog.Fatalf("cannot import package %s", externalTypes)
}
// update context.Order to the latest context.Universe
orderer := namer.Orderer{Namer: namer.NewPublicNamer(1)}
@ -287,7 +291,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
context.AddDir(pp)
p := context.Universe[pp]
if nil == p {
glog.Fatalf("failed to find pkg: %s", pp)
klog.Fatalf("failed to find pkg: %s", pp)
}
getManualConversionFunctions(context, p, manualConversions)
}
@ -331,7 +335,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
// from being a candidate for unsafe conversion
for k, v := range manualConversions {
if isCopyOnly(v.CommentLines) {
glog.V(5).Infof("Conversion function %s will not block memory copy because it is copy-only", v.Name)
klog.V(5).Infof("Conversion function %s will not block memory copy because it is copy-only", v.Name)
continue
}
// this type should be excluded from all equivalence, because the converter must be called.
@ -514,9 +518,9 @@ func (g *genConversion) convertibleOnlyWithinPackage(inType, outType *types.Type
tagvals := extractTag(t.CommentLines)
if tagvals != nil {
if tagvals[0] != "false" {
glog.Fatalf("Type %v: unsupported %s value: %q", t, tagName, tagvals[0])
klog.Fatalf("Type %v: unsupported %s value: %q", t, tagName, tagvals[0])
}
glog.V(5).Infof("type %v requests no conversion generation, skipping", t)
klog.V(5).Infof("type %v requests no conversion generation, skipping", t)
return false
}
// TODO: Consider generating functions for other kinds too.
@ -578,10 +582,10 @@ func (g *genConversion) preexists(inType, outType *types.Type) (*types.Type, boo
}
func (g *genConversion) Init(c *generator.Context, w io.Writer) error {
if glog.V(5) {
if klog.V(5) {
if m, ok := g.useUnsafe.(equalMemoryTypes); ok {
var result []string
glog.Infof("All objects without identical memory layout:")
klog.Infof("All objects without identical memory layout:")
for k, v := range m {
if v {
continue
@ -590,7 +594,7 @@ func (g *genConversion) Init(c *generator.Context, w io.Writer) error {
}
sort.Strings(result)
for _, s := range result {
glog.Infof(s)
klog.Infof(s)
}
}
}
@ -606,20 +610,40 @@ func (g *genConversion) Init(c *generator.Context, w io.Writer) error {
}
sw.Do("// RegisterConversions adds conversion functions to the given scheme.\n", nil)
sw.Do("// Public to allow building arbitrary schemes.\n", nil)
sw.Do("func RegisterConversions(scheme $.|raw$) error {\n", schemePtr)
sw.Do("return scheme.AddGeneratedConversionFuncs(\n", nil)
sw.Do("func RegisterConversions(s $.|raw$) error {\n", schemePtr)
for _, t := range g.types {
peerType := getPeerTypeFor(c, t, g.peerPackages)
sw.Do(nameTmpl+",\n", argsFromType(t, peerType))
sw.Do(nameTmpl+",\n", argsFromType(peerType, t))
args := argsFromType(t, peerType).With("Scope", types.Ref(conversionPackagePath, "Scope"))
sw.Do("if err := s.AddGeneratedConversionFunc((*$.inType|raw$)(nil), (*$.outType|raw$)(nil), func(a, b interface{}, scope $.Scope|raw$) error { return "+nameTmpl+"(a.(*$.inType|raw$), b.(*$.outType|raw$), scope) }); err != nil { return err }\n", args)
args = argsFromType(peerType, t).With("Scope", types.Ref(conversionPackagePath, "Scope"))
sw.Do("if err := s.AddGeneratedConversionFunc((*$.inType|raw$)(nil), (*$.outType|raw$)(nil), func(a, b interface{}, scope $.Scope|raw$) error { return "+nameTmpl+"(a.(*$.inType|raw$), b.(*$.outType|raw$), scope) }); err != nil { return err }\n", args)
}
sw.Do(")\n", nil)
var pairs []conversionPair
for pair, t := range g.manualConversions {
if t.Name.Package != g.outputPackage {
continue
}
pairs = append(pairs, pair)
}
// sort by name of the conversion function
sort.Slice(pairs, func(i, j int) bool {
if g.manualConversions[pairs[i]].Name.Name < g.manualConversions[pairs[j]].Name.Name {
return true
}
return false
})
for _, pair := range pairs {
args := argsFromType(pair.inType, pair.outType).With("Scope", types.Ref(conversionPackagePath, "Scope")).With("fn", g.manualConversions[pair])
sw.Do("if err := s.AddConversionFunc((*$.inType|raw$)(nil), (*$.outType|raw$)(nil), func(a, b interface{}, scope $.Scope|raw$) error { return $.fn|raw$(a.(*$.inType|raw$), b.(*$.outType|raw$), scope) }); err != nil { return err }\n", args)
}
sw.Do("return nil\n", nil)
sw.Do("}\n\n", nil)
return sw.Error()
}
func (g *genConversion) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
glog.V(5).Infof("generating for type %v", t)
klog.V(5).Infof("generating for type %v", t)
peerType := getPeerTypeFor(c, t, g.peerPackages)
sw := generator.NewSnippetWriter(w, c, "$", "$")
g.generateConversion(t, peerType, sw)
@ -640,10 +664,10 @@ func (g *genConversion) generateConversion(inType, outType *types.Type, sw *gene
// There is a public manual Conversion method: use it.
} else if skipped := g.skippedFields[inType]; len(skipped) != 0 {
// The inType had some fields we could not generate.
glog.Errorf("Warning: could not find nor generate a final Conversion function for %v -> %v", inType, outType)
glog.Errorf(" the following fields need manual conversion:")
klog.Errorf("Warning: could not find nor generate a final Conversion function for %v -> %v", inType, outType)
klog.Errorf(" the following fields need manual conversion:")
for _, f := range skipped {
glog.Errorf(" - %v", f)
klog.Errorf(" - %v", f)
}
} else {
// Emit a public conversion function.
@ -658,7 +682,7 @@ func (g *genConversion) generateConversion(inType, outType *types.Type, sw *gene
// at any nesting level. This makes the autogenerator easy to understand, and
// the compiler shouldn't care.
func (g *genConversion) generateFor(inType, outType *types.Type, sw *generator.SnippetWriter) {
glog.V(5).Infof("generating %v -> %v", inType, outType)
klog.V(5).Infof("generating %v -> %v", inType, outType)
var f func(*types.Type, *types.Type, *generator.SnippetWriter)
switch inType.Kind {
@ -829,7 +853,7 @@ func (g *genConversion) doStruct(inType, outType *types.Type, sw *generator.Snip
sw.Do("}\n", nil)
continue
}
glog.V(5).Infof("Skipped function %s because it is copy-only and we can use direct assignment", function.Name)
klog.V(5).Infof("Skipped function %s because it is copy-only and we can use direct assignment", function.Name)
}
// If we can't auto-convert, punt before we emit any code.

View file

@ -14,20 +14,59 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// conversion-gen is a tool for auto-generating Conversion functions.
// conversion-gen is a tool for auto-generating functions that convert
// between internal and external types. A general conversion code
// generation task involves three sets of packages: (1) a set of
// packages containing internal types, (2) a single package containing
// the external types, and (3) a single destination package (i.e.,
// where the generated conversion functions go, and where the
// developer-authored conversion functions are). The packages
// containing the internal types play the role known as "peer
// packages" in the general code-generation framework of Kubernetes.
//
// Given a list of input directories, it will scan for "peer" packages and
// generate functions that efficiently convert between same-name types in each
// package. For any pair of types that has a
// `Convert_<pkg1>_<type>_To_<pkg2>_<Type()`
// function (and its reciprocal), it will simply call that. use standard value
// assignment whenever possible. The resulting file will be stored in the same
// directory as the processed source package.
// For each conversion task, `conversion-gen` will generate functions
// that efficiently convert between same-name types in the two
// (internal, external) packages. The generated functions include
// ones named
// autoConvert_<pkg1>_<type>_To_<pkg2>_<type>
// for each such pair of types --- both with (pkg1,pkg2) =
// (internal,external) and (pkg1,pkg2) = (external,internal).
// Additionally: if the destination package does not contain one in a
// non-generated file then a function named
// Convert_<pkg1>_<type>_To_<pkg2>_<type>
// is also generated and it simply calls the `autoConvert...`
// function. The generated conversion functions use standard value
// assignment wherever possible. For compound types, the generated
// conversion functions call the `Convert...` functions for the
// subsidiary types. Thus developers can override the behavior for
// selected types. For a top-level object type (i.e., the type of an
// object that will be input to an apiserver), for such an override to
// be used by the apiserver the developer-maintained conversion
// functions must also be registered by invoking the
// `AddConversionFuncs` method of the relevant `Scheme` object from
// k8s.io/apimachinery/pkg/runtime.
//
// Generation is governed by comment tags in the source. Any package may
// request Conversion generation by including a comment in the file-comments of
// one file, of the form:
// // +k8s:conversion-gen=<import-path-of-peer-package>
// `conversion-gen` will scan its `--input-dirs`, looking at the
// package defined in each of those directories for comment tags that
// define a conversion code generation task. A package requests
// conversion code generation by including one or more comment in the
// package's `doc.go` file (currently anywhere in that file is
// acceptable, but the recommended location is above the `package`
// statement), of the form:
// // +k8s:conversion-gen=<import-path-of-internal-package>
// This introduces a conversion task, for which the destination
// package is the one containing the file with the tag and the tag
// identifies a package containing internal types. If there is also a
// tag of the form
// // +k8s:conversion-gen-external-types=<import-path-of-external-package>
// then it identifies the package containing the external types;
// otherwise they are in the destination package.
//
// For each conversion code generation task, the full set of internal
// packages (AKA peer packages) consists of the ones specified in the
// `k8s:conversion-gen` tags PLUS any specified in the
// `--base-peer-dirs` and `--extra-peer-dirs` flags on the command
// line.
//
// When generating for a package, individual types or fields of structs may opt
// out of Conversion generation by specifying a comment on the of the form:
@ -38,9 +77,9 @@ import (
"flag"
"path/filepath"
"github.com/golang/glog"
"github.com/spf13/pflag"
"k8s.io/gengo/args"
"k8s.io/klog"
generatorargs "k8s.io/code-generator/cmd/conversion-gen/args"
"k8s.io/code-generator/cmd/conversion-gen/generators"
@ -48,6 +87,7 @@ import (
)
func main() {
klog.InitFlags(nil)
genericArgs, customArgs := generatorargs.NewDefaults()
// Override defaults.
@ -61,7 +101,7 @@ func main() {
pflag.Parse()
if err := generatorargs.Validate(genericArgs); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
// Run it.
@ -70,7 +110,7 @@ func main() {
generators.DefaultNameSystem(),
generators.Packages,
); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
glog.V(2).Info("Completed successfully.")
klog.V(2).Info("Completed successfully.")
}

View file

@ -46,16 +46,17 @@ import (
"flag"
"path/filepath"
"github.com/golang/glog"
"github.com/spf13/pflag"
"k8s.io/gengo/args"
"k8s.io/gengo/examples/deepcopy-gen/generators"
"k8s.io/klog"
generatorargs "k8s.io/code-generator/cmd/deepcopy-gen/args"
"k8s.io/code-generator/pkg/util"
)
func main() {
klog.InitFlags(nil)
genericArgs, customArgs := generatorargs.NewDefaults()
// Override defaults.
@ -69,7 +70,7 @@ func main() {
pflag.Parse()
if err := generatorargs.Validate(genericArgs); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
// Run it.
@ -78,7 +79,7 @@ func main() {
generators.DefaultNameSystem(),
generators.Packages,
); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
glog.V(2).Info("Completed successfully.")
klog.V(2).Info("Completed successfully.")
}

View file

@ -45,16 +45,17 @@ import (
"flag"
"path/filepath"
"github.com/golang/glog"
"github.com/spf13/pflag"
"k8s.io/gengo/args"
"k8s.io/gengo/examples/defaulter-gen/generators"
"k8s.io/klog"
generatorargs "k8s.io/code-generator/cmd/defaulter-gen/args"
"k8s.io/code-generator/pkg/util"
)
func main() {
klog.InitFlags(nil)
genericArgs, customArgs := generatorargs.NewDefaults()
// Override defaults.
@ -68,7 +69,7 @@ func main() {
pflag.Parse()
if err := generatorargs.Validate(genericArgs); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
// Run it.
@ -77,7 +78,7 @@ func main() {
generators.DefaultNameSystem(),
generators.Packages,
); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
glog.V(2).Info("Completed successfully.")
klog.V(2).Info("Completed successfully.")
}

View file

@ -1,3 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- smarterclayton
reviewers:

View file

@ -25,16 +25,20 @@ import (
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
flag "github.com/spf13/pflag"
"gonum.org/v1/gonum/graph"
"gonum.org/v1/gonum/graph/simple"
"gonum.org/v1/gonum/graph/topo"
"k8s.io/code-generator/pkg/util"
"k8s.io/gengo/args"
"k8s.io/gengo/generator"
"k8s.io/gengo/namer"
"k8s.io/gengo/parser"
"k8s.io/gengo/types"
flag "github.com/spf13/pflag"
)
type Generator struct {
@ -202,6 +206,18 @@ func Run(g *Generator) {
c.Verify = g.Common.VerifyOnly
c.FileTypes["protoidl"] = NewProtoFile()
// order package by imports, importees first
deps := deps(c, protobufNames.packages)
order, err := importOrder(deps)
if err != nil {
log.Fatalf("Failed to order packages by imports: %v", err)
}
topologicalPos := map[string]int{}
for i, p := range order {
topologicalPos[p] = i
}
sort.Sort(positionOrder{topologicalPos, protobufNames.packages})
var vendoredOutputPackages, localOutputPackages generator.Packages
for _, p := range protobufNames.packages {
if _, ok := nonOutputPackages[p.Name()]; ok {
@ -347,3 +363,66 @@ func Run(g *Generator) {
}
}
}
func deps(c *generator.Context, pkgs []*protobufPackage) map[string][]string {
ret := map[string][]string{}
for _, p := range pkgs {
for _, d := range c.Universe[p.PackagePath].Imports {
ret[p.PackagePath] = append(ret[p.PackagePath], d.Path)
}
}
return ret
}
func importOrder(deps map[string][]string) ([]string, error) {
nodes := map[string]graph.Node{}
names := map[int64]string{}
g := simple.NewDirectedGraph()
for pkg, imports := range deps {
for _, imp := range imports {
if _, found := nodes[pkg]; !found {
n := g.NewNode()
g.AddNode(n)
nodes[pkg] = n
names[n.ID()] = pkg
}
if _, found := nodes[imp]; !found {
n := g.NewNode()
g.AddNode(n)
nodes[imp] = n
names[n.ID()] = imp
}
g.SetEdge(g.NewEdge(nodes[imp], nodes[pkg]))
}
}
ret := []string{}
sorted, err := topo.Sort(g)
if err != nil {
return nil, err
}
for _, n := range sorted {
ret = append(ret, names[n.ID()])
fmt.Println("topological order", names[n.ID()])
}
return ret, nil
}
type positionOrder struct {
pos map[string]int
elements []*protobufPackage
}
func (o positionOrder) Len() int {
return len(o.elements)
}
func (o positionOrder) Less(i, j int) bool {
return o.pos[o.elements[i].PackagePath] < o.pos[o.elements[j].PackagePath]
}
func (o positionOrder) Swap(i, j int) {
x := o.elements[i]
o.elements[i] = o.elements[j]
o.elements[j] = x
}

View file

@ -25,7 +25,7 @@ import (
"strconv"
"strings"
"github.com/golang/glog"
"k8s.io/klog"
"k8s.io/gengo/generator"
"k8s.io/gengo/namer"
@ -85,7 +85,7 @@ func (g *genProtoIDL) Filter(c *generator.Context, t *types.Type) bool {
// Type specified "true".
return true
}
glog.Fatalf(`Comment tag "protobuf" must be true or false, found: %q`, tagVals[0])
klog.Fatalf(`Comment tag "protobuf" must be true or false, found: %q`, tagVals[0])
}
if !g.generateAll {
// We're not generating everything.
@ -724,6 +724,10 @@ func genComment(out io.Writer, lines []string, indent string) {
lines = lines[:l-1]
}
for _, c := range lines {
if len(c) == 0 {
fmt.Fprintf(out, "%s//\n", indent) // avoid trailing whitespace
continue
}
fmt.Fprintf(out, "%s// %s\n", indent, c)
}
}

View file

@ -17,8 +17,8 @@ limitations under the License.
package protobuf
import (
"github.com/golang/glog"
"k8s.io/gengo/types"
"k8s.io/klog"
)
// extractBoolTagOrDie gets the comment-tags for the key and asserts that, if
@ -27,7 +27,7 @@ import (
func extractBoolTagOrDie(key string, lines []string) bool {
val, err := types.ExtractSingleBoolCommentTag("+", key, false, lines)
if err != nil {
glog.Fatal(err)
klog.Fatal(err)
}
return val
}

View file

@ -22,9 +22,13 @@ limitations under the License.
//
// If an ".import-restrictions" file is found, then all imports of the package
// are checked against each "rule" in the file. A rule consists of three parts:
// * A SelectorRegexp, to select the import paths that the rule applies to.
// * A list of AllowedPrefixes
// * A list of ForbiddenPrefixes
//
// - A SelectorRegexp, to select the import paths that the rule applies to.
//
// - A list of AllowedPrefixes
//
// - A list of ForbiddenPrefixes
//
// An import is allowed if it matches at least one allowed prefix and does not
// match any forbidden prefix. An example file looks like this:
//
@ -63,10 +67,11 @@ import (
"k8s.io/gengo/args"
"k8s.io/gengo/examples/import-boss/generators"
"github.com/golang/glog"
"k8s.io/klog"
)
func main() {
klog.InitFlags(nil)
arguments := args.Default()
// Override defaults.
@ -82,8 +87,8 @@ func main() {
generators.DefaultNameSystem(),
generators.Packages,
); err != nil {
glog.Errorf("Error: %v", err)
klog.Errorf("Error: %v", err)
os.Exit(1)
}
glog.V(2).Info("Completed successfully.")
klog.V(2).Info("Completed successfully.")
}

View file

@ -25,7 +25,7 @@ import (
"k8s.io/gengo/namer"
"k8s.io/gengo/types"
"github.com/golang/glog"
"k8s.io/klog"
)
// factoryGenerator produces a file of listers for a given GroupVersion and
@ -65,7 +65,7 @@ func (g *factoryGenerator) Imports(c *generator.Context) (imports []string) {
func (g *factoryGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
sw := generator.NewSnippetWriter(w, c, "{{", "}}")
glog.V(5).Infof("processing type %v", t)
klog.V(5).Infof("processing type %v", t)
gvInterfaces := make(map[string]*types.Type)
gvNewFuncs := make(map[string]*types.Type)
@ -152,7 +152,7 @@ func NewSharedInformerFactory(client {{.clientSetInterface|raw}}, defaultResync
// as specified here.
// Deprecated: Please use NewSharedInformerFactoryWithOptions instead
func NewFilteredSharedInformerFactory(client {{.clientSetInterface|raw}}, defaultResync {{.timeDuration|raw}}, namespace string, tweakListOptions {{.interfacesTweakListOptionsFunc|raw}}) SharedInformerFactory {
return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))
return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions))
}
// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options.
@ -165,7 +165,7 @@ func NewSharedInformerFactoryWithOptions(client {{.clientSetInterface|raw}}, def
startedInformers: make(map[{{.reflectType|raw}}]bool),
customResync: make(map[{{.reflectType|raw}}]{{.timeDuration|raw}}),
}
// Apply all options
for _, opt := range options {
factory = opt(factory)

View file

@ -23,7 +23,7 @@ import (
"k8s.io/gengo/namer"
"k8s.io/gengo/types"
"github.com/golang/glog"
"k8s.io/klog"
)
// factoryInterfaceGenerator produces a file of interfaces used to break a dependency cycle for
@ -60,7 +60,7 @@ func (g *factoryInterfaceGenerator) Imports(c *generator.Context) (imports []str
func (g *factoryInterfaceGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
sw := generator.NewSnippetWriter(w, c, "{{", "}}")
glog.V(5).Infof("processing type %v", t)
klog.V(5).Infof("processing type %v", t)
m := map[string]interface{}{
"cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer),
@ -76,6 +76,7 @@ func (g *factoryInterfaceGenerator) GenerateType(c *generator.Context, t *types.
}
var externalSharedInformerFactoryInterface = `
// NewInformerFunc takes {{.clientSetPackage|raw}} and {{.timeDuration|raw}} to return a SharedIndexInformer.
type NewInformerFunc func({{.clientSetPackage|raw}}, {{.timeDuration|raw}}) cache.SharedIndexInformer
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
@ -84,5 +85,6 @@ type SharedInformerFactory interface {
InformerFor(obj {{.runtimeObject|raw}}, newFunc NewInformerFunc) {{.cacheSharedIndexInformer|raw}}
}
// TweakListOptionsFunc is a function that transforms a {{.v1ListOptions|raw}}.
type TweakListOptionsFunc func(*{{.v1ListOptions|raw}})
`

View file

@ -22,6 +22,7 @@ import (
"strings"
clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
codegennamer "k8s.io/code-generator/pkg/namer"
"k8s.io/gengo/generator"
"k8s.io/gengo/namer"
"k8s.io/gengo/types"
@ -56,6 +57,7 @@ func (g *genericGenerator) Namers(c *generator.Context) namer.NameSystems {
"raw": namer.NewRawNamer(g.outputPackage, g.imports),
"allLowercasePlural": namer.NewAllLowercasePluralNamer(pluralExceptions),
"publicPlural": namer.NewPublicPluralNamer(pluralExceptions),
"resource": codegennamer.NewTagOverrideNamer("resourceName", namer.NewAllLowercasePluralNamer(pluralExceptions)),
}
}
@ -111,7 +113,9 @@ func (g *genericGenerator) GenerateType(c *generator.Context, t *types.Type, w i
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"})
func() {
schemeGVs[version] = c.Universe.Variable(types.Name{Package: g.typesForGroupVersion[gv][0].Name.Package, Name: "SchemeGroupVersion"})
}()
group.Versions = append(group.Versions, version)
}
sort.Sort(versionSort(group.Versions))
@ -168,7 +172,7 @@ func (f *sharedInformerFactory) ForResource(resource {{.schemaGroupVersionResour
{{range $version := .Versions -}}
// Group={{$group.Name}}, Version={{.Name}}
{{range .Resources -}}
case {{index $.schemeGVs $version|raw}}.WithResource("{{.|allLowercasePlural}}"):
case {{index $.schemeGVs $version|raw}}.WithResource("{{.|resource}}"):
return &genericInformer{resource: resource.GroupResource(), informer: f.{{$GroupGoName}}().{{$version.GoName}}().{{.|publicPlural}}().Informer()}, nil
{{end}}
{{end}}

View file

@ -28,7 +28,7 @@ import (
"k8s.io/code-generator/cmd/client-gen/generators/util"
clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
"github.com/golang/glog"
"k8s.io/klog"
)
// informerGenerator produces a file of listers for a given GroupVersion and
@ -66,7 +66,7 @@ func (g *informerGenerator) Imports(c *generator.Context) (imports []string) {
func (g *informerGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
sw := generator.NewSnippetWriter(w, c, "$", "$")
glog.V(5).Infof("processing type %v", t)
klog.V(5).Infof("processing type %v", t)
listerPackage := fmt.Sprintf("%s/%s/%s", g.listersPackage, g.groupPkgName, strings.ToLower(g.groupVersion.Version.NonEmpty()))
clientSetInterface := c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"})

View file

@ -22,11 +22,11 @@ import (
"path/filepath"
"strings"
"github.com/golang/glog"
"k8s.io/gengo/args"
"k8s.io/gengo/generator"
"k8s.io/gengo/namer"
"k8s.io/gengo/types"
"k8s.io/klog"
"k8s.io/code-generator/cmd/client-gen/generators/util"
clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
@ -102,12 +102,12 @@ func vendorless(p string) string {
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
boilerplate, err := arguments.LoadGoBoilerplate()
if err != nil {
glog.Fatalf("Failed loading boilerplate: %v", err)
klog.Fatalf("Failed loading boilerplate: %v", err)
}
customArgs, ok := arguments.CustomArgs.(*informergenargs.CustomArgs)
if !ok {
glog.Fatalf("Wrong CustomArgs type: %T", arguments.CustomArgs)
klog.Fatalf("Wrong CustomArgs type: %T", arguments.CustomArgs)
}
internalVersionPackagePath := filepath.Join(arguments.OutputPackagePath)
@ -128,7 +128,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
objectMeta, internal, err := objectMetaForPackage(p)
if err != nil {
glog.Fatal(err)
klog.Fatal(err)
}
if objectMeta == nil {
// no types in this package had genclient
@ -141,7 +141,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
if internal {
lastSlash := strings.LastIndex(p.Path, "/")
if lastSlash == -1 {
glog.Fatalf("error constructing internal group version for package %q", p.Path)
klog.Fatalf("error constructing internal group version for package %q", p.Path)
}
gv.Group = clientgentypes.Group(p.Path[lastSlash+1:])
targetGroupVersions = internalGroupVersions
@ -320,9 +320,9 @@ func versionPackage(basePackage string, groupPkgName string, gv clientgentypes.G
DefaultGen: generator.DefaultGen{
OptionalName: "interface",
},
outputPackage: packagePath,
imports: generator.NewImportTracker(),
types: typesToGenerate,
outputPackage: packagePath,
imports: generator.NewImportTracker(),
types: typesToGenerate,
internalInterfacesPackage: packageForInternalInterfaces(basePackage),
})

View file

@ -1,33 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package generators
import (
"github.com/golang/glog"
"k8s.io/gengo/types"
)
// extractBoolTagOrDie gets the comment-tags for the key and asserts that, if
// it exists, the value is boolean. If the tag did not exist, it returns
// false.
func extractBoolTagOrDie(key string, lines []string) bool {
val, err := types.ExtractSingleBoolCommentTag("+", key, false, lines)
if err != nil {
glog.Fatal(err)
}
return val
}

View file

@ -63,7 +63,7 @@ func (g *versionInterfaceGenerator) GenerateType(c *generator.Context, t *types.
m := map[string]interface{}{
"interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}),
"interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}),
"types": g.types,
"types": g.types,
}
sw.Do(versionTemplate, m)

View file

@ -20,16 +20,17 @@ import (
"flag"
"path/filepath"
"github.com/golang/glog"
"github.com/spf13/pflag"
"k8s.io/code-generator/cmd/informer-gen/generators"
"k8s.io/code-generator/pkg/util"
"k8s.io/gengo/args"
"k8s.io/klog"
generatorargs "k8s.io/code-generator/cmd/informer-gen/args"
)
func main() {
klog.InitFlags(nil)
genericArgs, customArgs := generatorargs.NewDefaults()
// Override defaults.
@ -47,7 +48,7 @@ func main() {
pflag.Parse()
if err := generatorargs.Validate(genericArgs); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
// Run it.
@ -56,7 +57,7 @@ func main() {
generators.DefaultNameSystem(),
generators.Packages,
); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
glog.V(2).Info("Completed successfully.")
klog.V(2).Info("Completed successfully.")
}

View file

@ -30,7 +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"
"k8s.io/klog"
)
// NameSystems returns the name system used by the generators in this package.
@ -66,7 +66,7 @@ func DefaultNameSystem() string {
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
boilerplate, err := arguments.LoadGoBoilerplate()
if err != nil {
glog.Fatalf("Failed loading boilerplate: %v", err)
klog.Fatalf("Failed loading boilerplate: %v", err)
}
var packageList generator.Packages
@ -75,7 +75,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
objectMeta, internal, err := objectMetaForPackage(p)
if err != nil {
glog.Fatal(err)
klog.Fatal(err)
}
if objectMeta == nil {
// no types in this package had genclient
@ -88,7 +88,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
if internal {
lastSlash := strings.LastIndex(p.Path, "/")
if lastSlash == -1 {
glog.Fatalf("error constructing internal group version for package %q", p.Path)
klog.Fatalf("error constructing internal group version for package %q", p.Path)
}
gv.Group = clientgentypes.Group(p.Path[lastSlash+1:])
internalGVPkg = p.Path
@ -223,7 +223,7 @@ func (g *listerGenerator) Imports(c *generator.Context) (imports []string) {
func (g *listerGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
sw := generator.NewSnippetWriter(w, c, "$", "$")
glog.V(5).Infof("processing type %v", t)
klog.V(5).Infof("processing type %v", t)
m := map[string]interface{}{
"Resource": c.Universe.Function(types.Name{Package: t.Name.Package, Name: "Resource"}),
"type": t,

View file

@ -1,33 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package generators
import (
"github.com/golang/glog"
"k8s.io/gengo/types"
)
// extractBoolTagOrDie gets the comment-tags for the key and asserts that, if
// it exists, the value is boolean. If the tag did not exist, it returns
// false.
func extractBoolTagOrDie(key string, lines []string) bool {
val, err := types.ExtractSingleBoolCommentTag("+", key, false, lines)
if err != nil {
glog.Fatal(err)
}
return val
}

View file

@ -20,16 +20,17 @@ import (
"flag"
"path/filepath"
"github.com/golang/glog"
"github.com/spf13/pflag"
"k8s.io/code-generator/cmd/lister-gen/generators"
"k8s.io/code-generator/pkg/util"
"k8s.io/gengo/args"
"k8s.io/klog"
generatorargs "k8s.io/code-generator/cmd/lister-gen/args"
)
func main() {
klog.InitFlags(nil)
genericArgs, customArgs := generatorargs.NewDefaults()
// Override defaults.
@ -44,7 +45,7 @@ func main() {
pflag.Parse()
if err := generatorargs.Validate(genericArgs); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
// Run it.
@ -53,7 +54,7 @@ func main() {
generators.DefaultNameSystem(),
generators.Packages,
); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
glog.V(2).Info("Completed successfully.")
klog.V(2).Info("Completed successfully.")
}

View file

@ -1,13 +0,0 @@
# Generate OpenAPI definitions
- To generate definition for a specific type or package add "+k8s:openapi-gen=true" tag to the type/package comment lines.
- To exclude a type or a member from a tagged package/type, add "+k8s:openapi-gen=false" tag to the comment lines.
# OpenAPI Extensions
OpenAPI spec can have extensions on types. To define one or more extensions on a type or its member
add "+k8s:openapi-gen=x-kubernetes-$NAME:$VALUE" to the comment lines before type/member. A type/member can
have multiple extensions. The rest of the line in the comment will be used as $VALUE so there is no need to
escape or quote the value string. Extensions can be use to pass more information to client generators or
documentation generators. For example a type my have a friendly name to be displayed in documentation or
being used in a client's fluent interface.

View file

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors.
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.
@ -19,35 +19,21 @@ 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) {
func NewDefaults() *args.GeneratorArgs {
genericArgs := args.Default().WithoutDefaultFlagParsing()
customArgs := &CustomArgs{}
genericArgs.CustomArgs = customArgs
genericArgs.OutputFileBaseName = "openapi_generated"
return genericArgs, customArgs
genericArgs.OutputFileBaseName = "zz_generated.register"
return genericArgs
}
// AddFlags add the generator flags to the flag set.
func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) {}
// Validate checks the given arguments.
func Validate(genericArgs *args.GeneratorArgs) error {
_ = genericArgs.CustomArgs.(*CustomArgs)
if len(genericArgs.OutputFileBaseName) == 0 {
return fmt.Errorf("output file base name cannot be empty")
}
if len(genericArgs.OutputPackagePath) == 0 {
return fmt.Errorf("output package cannot be empty")
}
return nil
}

View file

@ -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"
"k8s.io/klog"
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 {
klog.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 {
klog.V(5).Infof("skipping the generation of %s file, due to err %v", arguments.OutputFileBaseName, err)
continue
}
if internal {
klog.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 {
klog.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) {
klog.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 {
klog.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]
klog.V(5).Infof("overriding the group name with = %s", groupName)
gv.Group = clientgentypes.Group(groupName)
}
}
typesToRegister := []*types.Type{}
for _, t := range pkg.Types {
klog.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{
&registerExternalGenerator{
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)
}

View file

@ -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 = &registerExternalGenerator{}
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
}
`

View file

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors.
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.
@ -14,48 +14,40 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// This package generates openAPI definition file to be used in open API spec generation on API servers. To generate
// definition for a specific type or package add "+k8s:openapi-gen=true" tag to the type/package comment lines. To
// exclude a type from a tagged package, add "+k8s:openapi-gen=false" tag to the type comment lines.
package main
import (
"flag"
"path/filepath"
"github.com/golang/glog"
"github.com/spf13/pflag"
"k8s.io/gengo/args"
"k8s.io/kube-openapi/pkg/generators"
"k8s.io/klog"
generatorargs "k8s.io/code-generator/cmd/openapi-gen/args"
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, customArgs := generatorargs.NewDefaults()
// Override defaults.
// TODO: move this out of openapi-gen
klog.InitFlags(nil)
genericArgs := generatorargs.NewDefaults()
genericArgs.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), util.BoilerplatePath())
genericArgs.AddFlags(pflag.CommandLine)
customArgs.AddFlags(pflag.CommandLine)
flag.Set("logtostderr", "true")
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
pflag.Parse()
pflag.Parse()
if err := generatorargs.Validate(genericArgs); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
// Run it.
if err := genericArgs.Execute(
generators.NameSystems(),
generators.DefaultNameSystem(),
generators.Packages,
); err != nil {
glog.Fatalf("Error: %v", err)
klog.Fatalf("Error: %v", err)
}
glog.V(2).Info("Completed successfully.")
klog.V(2).Info("Completed successfully.")
}

View file

@ -32,10 +32,11 @@ import (
"k8s.io/gengo/args"
"k8s.io/gengo/examples/set-gen/generators"
"github.com/golang/glog"
"k8s.io/klog"
)
func main() {
klog.InitFlags(nil)
arguments := args.Default()
// Override defaults.
@ -48,8 +49,8 @@ func main() {
generators.DefaultNameSystem(),
generators.Packages,
); err != nil {
glog.Errorf("Error: %v", err)
klog.Errorf("Error: %v", err)
os.Exit(1)
}
glog.V(2).Info("Completed successfully.")
klog.V(2).Info("Completed successfully.")
}