diff --git a/cmd/genconversion/conversion.go b/cmd/genconversion/conversion.go index c60b8f1dacd..c25fb0d0aad 100644 --- a/cmd/genconversion/conversion.go +++ b/cmd/genconversion/conversion.go @@ -17,16 +17,13 @@ limitations under the License. package main import ( - "fmt" "io" "os" - "path" "runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" _ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1" pkg_runtime "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" flag "github.com/spf13/pflag" @@ -53,9 +50,7 @@ func main() { funcOut = file } - generator := pkg_runtime.NewConversionGenerator(api.Scheme.Raw(), path.Join("github.com/GoogleCloudPlatform/kubernetes/pkg/api", *version)) - apiShort := generator.AddImport("github.com/GoogleCloudPlatform/kubernetes/pkg/api") - generator.AddImport("github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource") + generator := pkg_runtime.NewConversionGenerator(api.Scheme.Raw()) // TODO(wojtek-t): Change the overwrites to a flag. generator.OverwritePackage(*version, "") for _, knownType := range api.Scheme.KnownTypes(*version) { @@ -63,14 +58,10 @@ func main() { glog.Errorf("error while generating conversion functions for %v: %v", knownType, err) } } - generator.RepackImports(util.NewStringSet()) - if err := generator.WriteImports(funcOut); err != nil { - glog.Fatalf("error while writing imports: %v", err) - } if err := generator.WriteConversionFunctions(funcOut); err != nil { glog.Fatalf("Error while writing conversion functions: %v", err) } - if err := generator.RegisterConversionFunctions(funcOut, fmt.Sprintf("%s.Scheme", apiShort)); err != nil { + if err := generator.RegisterConversionFunctions(funcOut); err != nil { glog.Fatalf("Error while writing conversion functions: %v", err) } } diff --git a/cmd/gendeepcopy/deep_copy.go b/cmd/gendeepcopy/deep_copy.go index dcb1c33766d..59ac43bb72f 100644 --- a/cmd/gendeepcopy/deep_copy.go +++ b/cmd/gendeepcopy/deep_copy.go @@ -19,14 +19,12 @@ package main import ( "io" "os" - "path" "runtime" "strings" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" _ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1" pkg_runtime "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" flag "github.com/spf13/pflag" @@ -55,14 +53,10 @@ func main() { } knownVersion := *version - registerTo := "api.Scheme" if knownVersion == "api" { knownVersion = api.Scheme.Raw().InternalVersion - registerTo = "Scheme" } - pkgPath := path.Join("github.com/GoogleCloudPlatform/kubernetes/pkg/api", knownVersion) - generator := pkg_runtime.NewDeepCopyGenerator(api.Scheme.Raw(), pkgPath, util.NewStringSet("github.com/GoogleCloudPlatform/kubernetes")) - generator.AddImport("github.com/GoogleCloudPlatform/kubernetes/pkg/api") + generator := pkg_runtime.NewDeepCopyGenerator(api.Scheme.Raw()) for _, overwrite := range strings.Split(*overwrites, ",") { vals := strings.Split(overwrite, "=") @@ -73,14 +67,13 @@ func main() { glog.Errorf("error while generating deep copy functions for %v: %v", knownType, err) } } - generator.RepackImports() - if err := generator.WriteImports(funcOut); err != nil { + if err := generator.WriteImports(funcOut, *version); err != nil { glog.Fatalf("error while writing imports: %v", err) } if err := generator.WriteDeepCopyFunctions(funcOut); err != nil { glog.Fatalf("error while writing deep copy functions: %v", err) } - if err := generator.RegisterDeepCopyFunctions(funcOut, registerTo); err != nil { + if err := generator.RegisterDeepCopyFunctions(funcOut, *version); err != nil { glog.Fatalf("error while registering deep copy functions: %v", err) } } diff --git a/hack/update-generated-conversions.sh b/hack/update-generated-conversions.sh index 7df31ca18f8..d7b9f9fd591 100755 --- a/hack/update-generated-conversions.sh +++ b/hack/update-generated-conversions.sh @@ -33,6 +33,14 @@ function generate_version() { cat >> $TMPFILE < 0 { - name = dirname + name - if _, ok := g.shortImports[name]; !ok { - g.imports[pkg] = name - g.shortImports[name] = pkg - return name - } - if subdirname := path.Base(path.Dir(path.Dir(pkg))); len(subdirname) > 0 { - name = subdirname + name - if _, ok := g.shortImports[name]; !ok { - g.imports[pkg] = name - g.shortImports[name] = pkg - return name - } - } - } - for i := 2; i < 100; i++ { - generatedName := fmt.Sprintf("%s%d", name, i) - if _, ok := g.shortImports[generatedName]; !ok { - g.imports[pkg] = generatedName - g.shortImports[generatedName] = pkg - return generatedName - } - } - panic(fmt.Sprintf("unable to find a unique name for the package path %q: %v", pkg, g.shortImports)) -} - func (g *conversionGenerator) typeName(inType reflect.Type) string { switch inType.Kind() { + case reflect.Map: + return fmt.Sprintf("map[%s]%s", g.typeName(inType.Key()), g.typeName(inType.Elem())) case reflect.Slice: return fmt.Sprintf("[]%s", g.typeName(inType.Elem())) case reflect.Ptr: return fmt.Sprintf("*%s", g.typeName(inType.Elem())) - case reflect.Map: - if len(inType.Name()) == 0 { - return fmt.Sprintf("map[%s]%s", g.typeName(inType.Key()), g.typeName(inType.Elem())) - } - fallthrough default: - pkg, name := inType.PkgPath(), inType.Name() - if len(name) == 0 && inType.Kind() == reflect.Struct { - return "struct{}" - } - if len(pkg) == 0 { + typeWithPkg := fmt.Sprintf("%s", inType) + slices := strings.Split(typeWithPkg, ".") + if len(slices) == 1 { // Default package. - return name + return slices[0] } - if val, found := g.pkgOverwrites[pkg]; found { - pkg = val + if len(slices) == 2 { + pkg := slices[0] + if val, found := g.pkgOverwrites[pkg]; found { + pkg = val + } + if pkg != "" { + pkg = pkg + "." + } + return pkg + slices[1] } - if len(pkg) == 0 { - return name - } - short := g.addImportByPath(pkg) - if len(short) > 0 { - return fmt.Sprintf("%s.%s", short, name) - } - return name + panic("Incorrect type name: " + typeWithPkg) } } @@ -785,10 +658,6 @@ func (g *conversionGenerator) existsDedicatedConversionFunction(inType, outType // unnamed. Thus we return false here. return false } - // TODO: no way to handle private conversions in different packages - if g.assumePrivateConversions { - return false - } return g.scheme.Converter().HasConversionFunc(inType, outType) } diff --git a/pkg/runtime/deep_copy_generator.go b/pkg/runtime/deep_copy_generator.go index 20d931caa0a..7be7af6bd86 100644 --- a/pkg/runtime/deep_copy_generator.go +++ b/pkg/runtime/deep_copy_generator.go @@ -19,7 +19,6 @@ package runtime import ( "fmt" "io" - "path" "reflect" "sort" "strings" @@ -39,20 +38,9 @@ type DeepCopyGenerator interface { // functions for this type and all nested types will be generated. AddType(inType reflect.Type) error - // ReplaceType registers a type that should be used instead of the type - // with the provided pkgPath and name. - ReplaceType(pkgPath, name string, in interface{}) - - // AddImport registers a package name with the generator and returns its - // short name. - AddImport(pkgPath string) string - - // RepackImports creates a stable ordering of import short names - RepackImports() - // Writes all imports that are necessary for deep-copy function and // their registration. - WriteImports(w io.Writer) error + WriteImports(w io.Writer, pkg string) error // Writes deel-copy functions for all types added via AddType() method // and their nested types. @@ -69,80 +57,20 @@ type DeepCopyGenerator interface { OverwritePackage(pkg, overwrite string) } -func NewDeepCopyGenerator(scheme *conversion.Scheme, targetPkg string, include util.StringSet) DeepCopyGenerator { - g := &deepCopyGenerator{ +func NewDeepCopyGenerator(scheme *conversion.Scheme) DeepCopyGenerator { + return &deepCopyGenerator{ scheme: scheme, - targetPkg: targetPkg, copyables: make(map[reflect.Type]bool), - imports: make(map[string]string), - shortImports: make(map[string]string), + imports: util.StringSet{}, pkgOverwrites: make(map[string]string), - replace: make(map[pkgPathNamePair]reflect.Type), - include: include, } - g.targetPackage(targetPkg) - g.AddImport("github.com/GoogleCloudPlatform/kubernetes/pkg/conversion") - return g -} - -type pkgPathNamePair struct { - PkgPath string - Name string } type deepCopyGenerator struct { - scheme *conversion.Scheme - targetPkg string - copyables map[reflect.Type]bool - // map of package names to shortname - imports map[string]string - // map of short names to package names - shortImports map[string]string + scheme *conversion.Scheme + copyables map[reflect.Type]bool + imports util.StringSet pkgOverwrites map[string]string - replace map[pkgPathNamePair]reflect.Type - include util.StringSet -} - -func (g *deepCopyGenerator) addImportByPath(pkg string) string { - if name, ok := g.imports[pkg]; ok { - return name - } - name := path.Base(pkg) - if _, ok := g.shortImports[name]; !ok { - g.imports[pkg] = name - g.shortImports[name] = pkg - return name - } - if dirname := path.Base(path.Dir(pkg)); len(dirname) > 0 { - name = dirname + name - if _, ok := g.shortImports[name]; !ok { - g.imports[pkg] = name - g.shortImports[name] = pkg - return name - } - if subdirname := path.Base(path.Dir(path.Dir(pkg))); len(subdirname) > 0 { - name = subdirname + name - if _, ok := g.shortImports[name]; !ok { - g.imports[pkg] = name - g.shortImports[name] = pkg - return name - } - } - } - for i := 2; i < 100; i++ { - generatedName := fmt.Sprintf("%s%d", name, i) - if _, ok := g.shortImports[generatedName]; !ok { - g.imports[pkg] = generatedName - g.shortImports[generatedName] = pkg - return generatedName - } - } - panic(fmt.Sprintf("unable to find a unique name for the package path %q: %v", pkg, g.shortImports)) -} - -func (g *deepCopyGenerator) targetPackage(pkg string) { - g.imports[pkg] = "" - g.shortImports[""] = pkg } func (g *deepCopyGenerator) addAllRecursiveTypes(inType reflect.Type) error { @@ -162,18 +90,11 @@ func (g *deepCopyGenerator) addAllRecursiveTypes(inType reflect.Type) error { return err } case reflect.Interface: - g.addImportByPath(inType.PkgPath()) + g.imports.Insert(inType.PkgPath()) return nil case reflect.Struct: - g.addImportByPath(inType.PkgPath()) - found := false - for s := range g.include { - if strings.HasPrefix(inType.PkgPath(), s) { - found = true - break - } - } - if !found { + g.imports.Insert(inType.PkgPath()) + if !strings.HasPrefix(inType.PkgPath(), "github.com/GoogleCloudPlatform/kubernetes") { return nil } for i := 0; i < inType.NumField(); i++ { @@ -189,15 +110,6 @@ func (g *deepCopyGenerator) addAllRecursiveTypes(inType reflect.Type) error { return nil } -func (g *deepCopyGenerator) AddImport(pkg string) string { - return g.addImportByPath(pkg) -} - -// ReplaceType registers a replacement type to be used instead of the named type -func (g *deepCopyGenerator) ReplaceType(pkgPath, name string, t interface{}) { - g.replace[pkgPathNamePair{pkgPath, name}] = reflect.TypeOf(t) -} - func (g *deepCopyGenerator) AddType(inType reflect.Type) error { if inType.Kind() != reflect.Struct { return fmt.Errorf("non-struct copies are not supported") @@ -205,23 +117,10 @@ func (g *deepCopyGenerator) AddType(inType reflect.Type) error { return g.addAllRecursiveTypes(inType) } -func (g *deepCopyGenerator) RepackImports() { - var packages []string - for key := range g.imports { - packages = append(packages, key) - } - sort.Strings(packages) - g.imports = make(map[string]string) - g.shortImports = make(map[string]string) - - g.targetPackage(g.targetPkg) - for _, pkg := range packages { - g.addImportByPath(pkg) - } -} - -func (g *deepCopyGenerator) WriteImports(w io.Writer) error { +func (g *deepCopyGenerator) WriteImports(w io.Writer, pkg string) error { var packages []string + packages = append(packages, "github.com/GoogleCloudPlatform/kubernetes/pkg/api") + packages = append(packages, "github.com/GoogleCloudPlatform/kubernetes/pkg/conversion") for key := range g.imports { packages = append(packages, key) } @@ -231,13 +130,10 @@ func (g *deepCopyGenerator) WriteImports(w io.Writer) error { indent := 0 buffer.addLine("import (\n", indent) for _, importPkg := range packages { - if len(importPkg) == 0 { + if strings.HasSuffix(importPkg, pkg) { continue } - if len(g.imports[importPkg]) == 0 { - continue - } - buffer.addLine(fmt.Sprintf("%s \"%s\"\n", g.imports[importPkg], importPkg), indent+1) + buffer.addLine(fmt.Sprintf("\"%s\"\n", importPkg), indent+1) } buffer.addLine(")\n", indent) buffer.addLine("\n", indent) @@ -263,47 +159,35 @@ func (s byPkgAndName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (g *deepCopyGenerator) nameForType(inType reflect.Type) string { +func (g *deepCopyGenerator) typeName(inType reflect.Type) string { switch inType.Kind() { + case reflect.Map: + return fmt.Sprintf("map[%s]%s", g.typeName(inType.Key()), g.typeName(inType.Elem())) case reflect.Slice: return fmt.Sprintf("[]%s", g.typeName(inType.Elem())) case reflect.Ptr: return fmt.Sprintf("*%s", g.typeName(inType.Elem())) - case reflect.Map: - if len(inType.Name()) == 0 { - return fmt.Sprintf("map[%s]%s", g.typeName(inType.Key()), g.typeName(inType.Elem())) - } - fallthrough default: - pkg, name := inType.PkgPath(), inType.Name() - if len(name) == 0 && inType.Kind() == reflect.Struct { - return "struct{}" - } - if len(pkg) == 0 { + typeWithPkg := fmt.Sprintf("%s", inType) + slices := strings.Split(typeWithPkg, ".") + if len(slices) == 1 { // Default package. - return name + return slices[0] } - if val, found := g.pkgOverwrites[pkg]; found { - pkg = val + if len(slices) == 2 { + pkg := slices[0] + if val, found := g.pkgOverwrites[pkg]; found { + pkg = val + } + if pkg != "" { + pkg = pkg + "." + } + return pkg + slices[1] } - if len(pkg) == 0 { - return name - } - short := g.addImportByPath(pkg) - if len(short) > 0 { - return fmt.Sprintf("%s.%s", short, name) - } - return name + panic("Incorrect type name: " + typeWithPkg) } } -func (g *deepCopyGenerator) typeName(inType reflect.Type) string { - if t, ok := g.replace[pkgPathNamePair{inType.PkgPath(), inType.Name()}]; ok { - return g.nameForType(t) - } - return g.nameForType(inType) -} - func (g *deepCopyGenerator) deepCopyFunctionName(inType reflect.Type) string { funcNameFormat := "deepCopy_%s_%s" inPkg := packageForName(inType) @@ -558,8 +442,12 @@ func (g *deepCopyGenerator) writeDeepCopyForType(b *buffer, inType reflect.Type, func (g *deepCopyGenerator) writeRegisterHeader(b *buffer, pkg string, indent int) { b.addLine("func init() {\n", indent) - registerFormat := "err := %s.AddGeneratedDeepCopyFuncs(\n" - b.addLine(fmt.Sprintf(registerFormat, pkg), indent+1) + registerFormat := "err := %sScheme.AddGeneratedDeepCopyFuncs(\n" + if pkg == "api" { + b.addLine(fmt.Sprintf(registerFormat, ""), indent+1) + } else { + b.addLine(fmt.Sprintf(registerFormat, "api."), indent+1) + } } func (g *deepCopyGenerator) writeRegisterFooter(b *buffer, indent int) {