// Packages makes the sets package definition. func Packages(c *generator.Context, arguments *args.GeneratorArgs) generator.Packages { pkgs := generator.Packages{} c.FileTypes = map[string]generator.FileType{ importBossFileType: importRuleFile{}, } for _, p := range c.Universe { if !arguments.InputIncludes(p) { // Don't run on e.g. third party dependencies. continue } savedPackage := p pkgs = append(pkgs, &generator.DefaultPackage{ PackageName: p.Name, PackagePath: p.Path, // GeneratorFunc returns a list of generators. Each generator makes a // single file. GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { return []generator.Generator{&importRules{ myPackage: savedPackage, }} }, FilterFunc: func(c *generator.Context, t *types.Type) bool { return false }, }) } return pkgs }
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } inputs := sets.NewString(context.Inputs...) packages := generator.Packages{} header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...) header = append(header, []byte( ` // This file was autogenerated by conversion-gen. Do not edit it manually! `)...) // Accumulate pre-existing conversion and default functions. // TODO: This is too ad-hoc. We need a better way. manualConversions := conversionFuncMap{} manualDefaults := defaulterFuncMap{} // We are generating conversions only for packages that are explicitly // passed as InputDir. for i := range inputs { glog.V(5).Infof("considering pkg %q", i) pkg := context.Universe[i] if pkg == nil { // If the input had no Go files, for example. continue } // Add conversion and defaulting functions. getManualConversionFunctions(context, pkg, manualConversions) getManualDefaultingFunctions(context, pkg, manualDefaults) // Only generate conversions for packages which explicitly request it // by specifying one or more "+k8s:conversion-gen=<peer-pkg>" // in their doc.go file. peerPkgs := extractTag(pkg.Comments) if peerPkgs != nil { glog.V(5).Infof(" tags: %q", peerPkgs) } else { glog.V(5).Infof(" no tag") continue } if customArgs, ok := arguments.CustomArgs.(*CustomArgs); ok { if len(customArgs.ExtraPeerDirs) > 0 { peerPkgs = append(peerPkgs, customArgs.ExtraPeerDirs...) } } // Make sure our peer-packages are added and fully parsed. for _, pp := range peerPkgs { context.AddDir(pp) getManualConversionFunctions(context, context.Universe[pp], manualConversions) getManualDefaultingFunctions(context, context.Universe[pp], manualDefaults) } pkgNeedsGeneration := false for _, t := range pkg.Types { // Check whether this type can be auto-converted to the peer // package type. peerType := getPeerTypeFor(context, t, peerPkgs) if peerType == nil { // We did not find a corresponding type. continue } if namer.IsPrivateGoName(peerType.Name.Name) { // We won't be able to convert to a private type. glog.V(5).Infof(" found a peer type %v, but it is a private name", t) continue } // If we can generate conversion in any direction, we should // generate this package. if isConvertible(t, peerType, manualConversions) || isConvertible(peerType, t, manualConversions) { pkgNeedsGeneration = true break } } if !pkgNeedsGeneration { glog.V(5).Infof(" no viable conversions, not generating for this package") continue } packages = append(packages, &generator.DefaultPackage{ PackageName: filepath.Base(pkg.Path), PackagePath: pkg.Path, HeaderText: header, GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { generators = []generator.Generator{} generators = append( generators, NewGenConversion(arguments.OutputFileBaseName, pkg.Path, manualConversions, manualDefaults, peerPkgs)) return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { return t.Name.Package == pkg.Path }, }) } return packages }