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.
pull/6/head
Clayton Coleman 2016-05-01 23:05:13 -04:00
parent 7e7465e2d4
commit 4554889ae9
No known key found for this signature in database
GPG Key ID: 3D16906B4F1C5CB3
2 changed files with 53 additions and 44 deletions

View File

@ -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)
}

View File

@ -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)