From 4554889ae9ab0eb8b9d26d53cc7ca0912d7e249e Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sun, 1 May 2016 23:05:13 -0400 Subject: [PATCH 1/2] Conversions have kube-isms and are not portable for downstream Some minor fixes to enable generators for OpenShift and others who need to generate conversions on Kube API groups outside the core. --- .../conversion-gen/generators/conversion.go | 50 ++++++++++--------- .../deepcopy-gen/generators/deepcopy.go | 47 +++++++++-------- 2 files changed, 53 insertions(+), 44 deletions(-) diff --git a/cmd/libs/go2idl/conversion-gen/generators/conversion.go b/cmd/libs/go2idl/conversion-gen/generators/conversion.go index 3afae34983f..73ce61f97d1 100644 --- a/cmd/libs/go2idl/conversion-gen/generators/conversion.go +++ b/cmd/libs/go2idl/conversion-gen/generators/conversion.go @@ -379,6 +379,8 @@ type genConversion struct { defaulters defaulters imports namer.ImportTracker typesForInit []conversionType + + globalVariables map[string]interface{} } func NewGenConversion(sanitizedName, targetPackage string, preexisting conversions, defaulters defaulters) generator.Generator { @@ -459,12 +461,6 @@ func (g *genConversion) isOtherPackage(pkg string) bool { func (g *genConversion) Imports(c *generator.Context) (imports []string) { var importLines []string - if g.isOtherPackage(apiPackagePath) { - importLines = append(importLines, "api \""+apiPackagePath+"\"") - } - if g.isOtherPackage(conversionPackagePath) { - importLines = append(importLines, "conversion \""+conversionPackagePath+"\"") - } for _, singleImport := range g.imports.ImportLines() { if g.isOtherPackage(singleImport) { importLines = append(importLines, singleImport) @@ -473,7 +469,16 @@ func (g *genConversion) Imports(c *generator.Context) (imports []string) { return importLines } -func argsFromType(inType, outType *types.Type) interface{} { +func (g *genConversion) withGlobals(args map[string]interface{}) map[string]interface{} { + for k, v := range g.globalVariables { + if _, ok := args[k]; !ok { + args[k] = v + } + } + return args +} + +func argsFromType(inType, outType *types.Type) map[string]interface{} { return map[string]interface{}{ "inType": inType, "outType": outType, @@ -498,13 +503,20 @@ func (g *genConversion) preexists(inType, outType *types.Type) (*types.Type, boo } func (g *genConversion) Init(c *generator.Context, w io.Writer) error { + scheme := c.Universe.Variable(types.Name{Package: apiPackagePath, Name: "Scheme"}) + g.imports.AddType(scheme) + scope := c.Universe.Type(types.Name{Package: conversionPackagePath, Name: "Scope"}) + g.imports.AddType(scope) + g.globalVariables = map[string]interface{}{ + "scheme": scheme, + "Scope": scope, + } + sw := generator.NewSnippetWriter(w, c, "$", "$") sw.Do("func init() {\n", nil) - if g.targetPackage == apiPackagePath { - sw.Do("if err := Scheme.AddGeneratedConversionFuncs(\n", nil) - } else { - sw.Do("if err := api.Scheme.AddGeneratedConversionFuncs(\n", nil) - } + sw.Do("if err := $.scheme|raw$.AddGeneratedConversionFuncs(\n", map[string]interface{}{ + "scheme": scheme, + }) for _, conv := range g.typesForInit { funcName := g.funcNameTmpl(conv.inType, conv.outType) sw.Do(fmt.Sprintf("%s,\n", funcName), argsFromType(conv.inType, conv.outType)) @@ -531,27 +543,19 @@ func (g *genConversion) GenerateType(c *generator.Context, t *types.Type, w io.W func (g *genConversion) generateConversion(inType, outType *types.Type, sw *generator.SnippetWriter) { funcName := g.funcNameTmpl(inType, outType) - if g.targetPackage == conversionPackagePath { - sw.Do(fmt.Sprintf("func auto%s(in *$.inType|raw$, out *$.outType|raw$, s Scope) error {\n", funcName), argsFromType(inType, outType)) - } else { - sw.Do(fmt.Sprintf("func auto%s(in *$.inType|raw$, out *$.outType|raw$, s conversion.Scope) error {\n", funcName), argsFromType(inType, outType)) - } + + sw.Do(fmt.Sprintf("func auto%s(in *$.inType|raw$, out *$.outType|raw$, s $.Scope|raw$) error {\n", funcName), g.withGlobals(argsFromType(inType, outType))) // if no defaulter of form SetDefaults_XXX is defined, do not inline a check for defaulting. if function, ok := g.defaulters[inType]; ok { sw.Do("$.|raw$(in)\n", function) } - g.generateFor(inType, outType, sw) sw.Do("return nil\n", nil) sw.Do("}\n\n", nil) // If there is no public preexisting Convert method, generate it. if _, ok := g.preexists(inType, outType); !ok { - if g.targetPackage == conversionPackagePath { - sw.Do(fmt.Sprintf("func %s(in *$.inType|raw$, out *$.outType|raw$, s Scope) error {\n", funcName), argsFromType(inType, outType)) - } else { - sw.Do(fmt.Sprintf("func %s(in *$.inType|raw$, out *$.outType|raw$, s conversion.Scope) error {\n", funcName), argsFromType(inType, outType)) - } + sw.Do(fmt.Sprintf("func %s(in *$.inType|raw$, out *$.outType|raw$, s $.Scope|raw$) error {\n", funcName), g.withGlobals(argsFromType(inType, outType))) sw.Do(fmt.Sprintf("return auto%s(in, out, s)\n", funcName), argsFromType(inType, outType)) sw.Do("}\n\n", nil) } diff --git a/cmd/libs/go2idl/deepcopy-gen/generators/deepcopy.go b/cmd/libs/go2idl/deepcopy-gen/generators/deepcopy.go index 67a08bd0bea..d4cd5460e93 100644 --- a/cmd/libs/go2idl/deepcopy-gen/generators/deepcopy.go +++ b/cmd/libs/go2idl/deepcopy-gen/generators/deepcopy.go @@ -76,7 +76,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat for _, p := range context.Universe { copyableType := false for _, t := range p.Types { - if copyableWithinPackage(t) { + if copyableWithinPackage(t) && inputs.Has(t.Name.Package) { copyableType = true } } @@ -114,6 +114,8 @@ type genDeepCopy struct { imports namer.ImportTracker typesForInit []*types.Type generateInitFunc bool + + globalVariables map[string]interface{} } func NewGenDeepCopy(sanitizedName, targetPackage string, generateInitFunc bool) generator.Generator { @@ -143,9 +145,6 @@ func (g *genDeepCopy) Filter(c *generator.Context, t *types.Type) bool { } func copyableWithinPackage(t *types.Type) bool { - if !strings.HasPrefix(t.Name.Package, "k8s.io/kubernetes/") { - return false - } if types.ExtractCommentTags("+", t.CommentLines)["gencopy"] == "false" { return false } @@ -172,12 +171,6 @@ func (g *genDeepCopy) isOtherPackage(pkg string) bool { func (g *genDeepCopy) Imports(c *generator.Context) (imports []string) { importLines := []string{} - if g.isOtherPackage(apiPackagePath) && g.generateInitFunc { - importLines = append(importLines, "api \""+apiPackagePath+"\"") - } - if g.isOtherPackage(conversionPackagePath) { - importLines = append(importLines, "conversion \""+conversionPackagePath+"\"") - } for _, singleImport := range g.imports.ImportLines() { if g.isOtherPackage(singleImport) { importLines = append(importLines, singleImport) @@ -186,7 +179,16 @@ func (g *genDeepCopy) Imports(c *generator.Context) (imports []string) { return importLines } -func argsFromType(t *types.Type) interface{} { +func (g *genDeepCopy) withGlobals(args map[string]interface{}) map[string]interface{} { + for k, v := range g.globalVariables { + if _, ok := args[k]; !ok { + args[k] = v + } + } + return args +} + +func argsFromType(t *types.Type) map[string]interface{} { return map[string]interface{}{ "type": t, } @@ -202,19 +204,26 @@ func (g *genDeepCopy) funcNameTmpl(t *types.Type) string { } func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error { + cloner := c.Universe.Type(types.Name{Package: conversionPackagePath, Name: "Cloner"}) + g.imports.AddType(cloner) + g.globalVariables = map[string]interface{}{ + "Cloner": cloner, + } if !g.generateInitFunc { // TODO: We should come up with a solution to register all generated // deep-copy functions. However, for now, to avoid import cycles // we register only those explicitly requested. return nil } + scheme := c.Universe.Variable(types.Name{Package: apiPackagePath, Name: "Scheme"}) + g.imports.AddType(scheme) + g.globalVariables["scheme"] = scheme + sw := generator.NewSnippetWriter(w, c, "$", "$") sw.Do("func init() {\n", nil) - if g.targetPackage == apiPackagePath { - sw.Do("if err := Scheme.AddGeneratedDeepCopyFuncs(\n", nil) - } else { - sw.Do("if err := api.Scheme.AddGeneratedDeepCopyFuncs(\n", nil) - } + sw.Do("if err := $.scheme|raw$.AddGeneratedDeepCopyFuncs(\n", map[string]interface{}{ + "scheme": scheme, + }) for _, t := range g.typesForInit { sw.Do(fmt.Sprintf("%s,\n", g.funcNameTmpl(t)), argsFromType(t)) } @@ -229,11 +238,7 @@ func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error { func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { sw := generator.NewSnippetWriter(w, c, "$", "$") funcName := g.funcNameTmpl(t) - if g.targetPackage == conversionPackagePath { - sw.Do(fmt.Sprintf("func %s(in $.type|raw$, out *$.type|raw$, c *Cloner) error {\n", funcName), argsFromType(t)) - } else { - sw.Do(fmt.Sprintf("func %s(in $.type|raw$, out *$.type|raw$, c *conversion.Cloner) error {\n", funcName), argsFromType(t)) - } + sw.Do(fmt.Sprintf("func %s(in $.type|raw$, out *$.type|raw$, c *$.Cloner|raw$) error {\n", funcName), g.withGlobals(argsFromType(t))) g.generateFor(t, sw) sw.Do("return nil\n", nil) sw.Do("}\n\n", nil) From adf3c387ee9b822baf17dc0f63d7212729589b2f Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Mon, 2 May 2016 00:40:04 -0400 Subject: [PATCH 2/2] Regenerate api/unversioned by hand so that it is complete We need to break the circular dependency on generation to the scheme. --- pkg/api/unversioned/deep_copy_generated.go | 190 ++++++++++++++++++++- 1 file changed, 189 insertions(+), 1 deletion(-) diff --git a/pkg/api/unversioned/deep_copy_generated.go b/pkg/api/unversioned/deep_copy_generated.go index 6a7cd5c5333..c4a551d657b 100644 --- a/pkg/api/unversioned/deep_copy_generated.go +++ b/pkg/api/unversioned/deep_copy_generated.go @@ -21,15 +21,127 @@ limitations under the License. package unversioned import ( + "time" + conversion "k8s.io/kubernetes/pkg/conversion" - time "time" ) +func DeepCopy_unversioned_APIGroup(in APIGroup, out *APIGroup, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + out.Name = in.Name + if in.Versions != nil { + in, out := in.Versions, &out.Versions + *out = make([]GroupVersionForDiscovery, len(in)) + for i := range in { + if err := DeepCopy_unversioned_GroupVersionForDiscovery(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Versions = nil + } + if err := DeepCopy_unversioned_GroupVersionForDiscovery(in.PreferredVersion, &out.PreferredVersion, c); err != nil { + return err + } + if in.ServerAddressByClientCIDRs != nil { + in, out := in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs + *out = make([]ServerAddressByClientCIDR, len(in)) + for i := range in { + if err := DeepCopy_unversioned_ServerAddressByClientCIDR(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.ServerAddressByClientCIDRs = nil + } + return nil +} + +func DeepCopy_unversioned_APIGroupList(in APIGroupList, out *APIGroupList, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if in.Groups != nil { + in, out := in.Groups, &out.Groups + *out = make([]APIGroup, len(in)) + for i := range in { + if err := DeepCopy_unversioned_APIGroup(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Groups = nil + } + return nil +} + +func DeepCopy_unversioned_APIResource(in APIResource, out *APIResource, c *conversion.Cloner) error { + out.Name = in.Name + out.Namespaced = in.Namespaced + out.Kind = in.Kind + return nil +} + +func DeepCopy_unversioned_APIResourceList(in APIResourceList, out *APIResourceList, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + out.GroupVersion = in.GroupVersion + if in.APIResources != nil { + in, out := in.APIResources, &out.APIResources + *out = make([]APIResource, len(in)) + for i := range in { + if err := DeepCopy_unversioned_APIResource(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.APIResources = nil + } + return nil +} + +func DeepCopy_unversioned_APIVersions(in APIVersions, out *APIVersions, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if in.Versions != nil { + in, out := in.Versions, &out.Versions + *out = make([]string, len(in)) + copy(*out, in) + } else { + out.Versions = nil + } + if in.ServerAddressByClientCIDRs != nil { + in, out := in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs + *out = make([]ServerAddressByClientCIDR, len(in)) + for i := range in { + if err := DeepCopy_unversioned_ServerAddressByClientCIDR(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.ServerAddressByClientCIDRs = nil + } + return nil +} + func DeepCopy_unversioned_Duration(in Duration, out *Duration, c *conversion.Cloner) error { out.Duration = in.Duration return nil } +func DeepCopy_unversioned_ExportOptions(in ExportOptions, out *ExportOptions, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + out.Export = in.Export + out.Exact = in.Exact + return nil +} + func DeepCopy_unversioned_GroupKind(in GroupKind, out *GroupKind, c *conversion.Cloner) error { out.Group = in.Group out.Kind = in.Kind @@ -48,6 +160,12 @@ func DeepCopy_unversioned_GroupVersion(in GroupVersion, out *GroupVersion, c *co return nil } +func DeepCopy_unversioned_GroupVersionForDiscovery(in GroupVersionForDiscovery, out *GroupVersionForDiscovery, c *conversion.Cloner) error { + out.GroupVersion = in.GroupVersion + out.Version = in.Version + return nil +} + func DeepCopy_unversioned_GroupVersionKind(in GroupVersionKind, out *GroupVersionKind, c *conversion.Cloner) error { out.Group = in.Group out.Version = in.Version @@ -105,6 +223,76 @@ func DeepCopy_unversioned_ListMeta(in ListMeta, out *ListMeta, c *conversion.Clo return nil } +func DeepCopy_unversioned_Patch(in Patch, out *Patch, c *conversion.Cloner) error { + return nil +} + +func DeepCopy_unversioned_RootPaths(in RootPaths, out *RootPaths, c *conversion.Cloner) error { + if in.Paths != nil { + in, out := in.Paths, &out.Paths + *out = make([]string, len(in)) + copy(*out, in) + } else { + out.Paths = nil + } + return nil +} + +func DeepCopy_unversioned_ServerAddressByClientCIDR(in ServerAddressByClientCIDR, out *ServerAddressByClientCIDR, c *conversion.Cloner) error { + out.ClientCIDR = in.ClientCIDR + out.ServerAddress = in.ServerAddress + return nil +} + +func DeepCopy_unversioned_Status(in Status, out *Status, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := DeepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + out.Status = in.Status + out.Message = in.Message + out.Reason = in.Reason + if in.Details != nil { + in, out := in.Details, &out.Details + *out = new(StatusDetails) + if err := DeepCopy_unversioned_StatusDetails(*in, *out, c); err != nil { + return err + } + } else { + out.Details = nil + } + out.Code = in.Code + return nil +} + +func DeepCopy_unversioned_StatusCause(in StatusCause, out *StatusCause, c *conversion.Cloner) error { + out.Type = in.Type + out.Message = in.Message + out.Field = in.Field + return nil +} + +func DeepCopy_unversioned_StatusDetails(in StatusDetails, out *StatusDetails, c *conversion.Cloner) error { + out.Name = in.Name + out.Group = in.Group + out.Kind = in.Kind + if in.Causes != nil { + in, out := in.Causes, &out.Causes + *out = make([]StatusCause, len(in)) + for i := range in { + if err := DeepCopy_unversioned_StatusCause(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Causes = nil + } + out.RetryAfterSeconds = in.RetryAfterSeconds + return nil +} + func DeepCopy_unversioned_Time(in Time, out *Time, c *conversion.Cloner) error { if newVal, err := c.DeepCopy(in.Time); err != nil { return err