// Packages makes the client package definition. func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } groupToTypes := map[string][]*types.Type{} for _, inputDir := range arguments.InputDirs { p := context.Universe.Package(inputDir) for _, t := range p.Types { if types.ExtractCommentTags("+", t.SecondClosestCommentLines)["genclient"] != "true" { continue } group := filepath.Base(t.Name.Package) // Special case for the legacy API. if group == "api" { group = "legacy" } if _, found := groupToTypes[group]; !found { groupToTypes[group] = []*types.Type{} } groupToTypes[group] = append(groupToTypes[group], t) } } var packageList []generator.Package orderer := namer.Orderer{namer.NewPrivateNamer(0)} for group, types := range groupToTypes { packageList = append(packageList, packageForGroup(group, "unversioned", orderer.OrderTypes(types), arguments.OutputPackagePath, boilerplate)) } return generator.Packages(packageList) }
// 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 }
// Packages makes the client package definition. func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } customArgs, ok := arguments.CustomArgs.(clientgenargs.Args) if !ok { glog.Fatalf("cannot convert arguments.CustomArgs to clientgenargs.Args") } if len(customArgs.CmdArgs) != 0 { boilerplate = append(boilerplate, []byte(fmt.Sprintf("\n// This file is generated by client-gen with arguments: %s\n\n", customArgs.CmdArgs))...) } else { boilerplate = append(boilerplate, []byte(fmt.Sprintf("\n// This file is generated by client-gen with the default arguments.\n\n"))...) } gvToTypes := map[unversioned.GroupVersion][]*types.Type{} for gv, inputDir := range customArgs.GroupVersionToInputPath { p := context.Universe.Package(inputDir) for _, t := range p.Types { if types.ExtractCommentTags("+", t.SecondClosestCommentLines)["genclient"] != "true" { continue } if _, found := gvToTypes[gv]; !found { gvToTypes[gv] = []*types.Type{} } gvToTypes[gv] = append(gvToTypes[gv], t) } } var packageList []generator.Package typedClientBasePath := filepath.Join(customArgs.ClientsetOutputPath, customArgs.ClientsetName, "typed") packageList = append(packageList, packageForClientset(customArgs, typedClientBasePath, boilerplate)) if customArgs.FakeClient { packageList = append(packageList, fake.PackageForClientset(customArgs, typedClientBasePath, boilerplate)) } // If --clientset-only=true, we don't regenerate the individual typed clients. if customArgs.ClientsetOnly { return generator.Packages(packageList) } orderer := namer.Orderer{namer.NewPrivateNamer(0)} for _, gv := range customArgs.GroupVersions { types := gvToTypes[gv] packageList = append(packageList, packageForGroup(normalization.GroupVersion(gv), orderer.OrderTypes(types), typedClientBasePath, arguments.OutputBase, boilerplate)) if customArgs.FakeClient { packageList = append(packageList, fake.PackageForGroup(normalization.GroupVersion(gv), orderer.OrderTypes(types), typedClientBasePath, arguments.OutputBase, boilerplate)) } } return generator.Packages(packageList) }
// Packages makes the client package definition. func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } groupToTypes := map[string][]*types.Type{} for _, inputDir := range arguments.InputDirs { p := context.Universe.Package(inputDir) for _, t := range p.Types { if types.ExtractCommentTags("+", t.SecondClosestCommentLines)["genclient"] != "true" { continue } group := filepath.Base(t.Name.Package) // Special case for the core API. if group == "api" { group = "core" } if _, found := groupToTypes[group]; !found { groupToTypes[group] = []*types.Type{} } groupToTypes[group] = append(groupToTypes[group], t) } } customArgs, ok := arguments.CustomArgs.(ClientGenArgs) if !ok { glog.Fatalf("cannot convert arguments.CustomArgs to ClientGenArgs") } var packageList []generator.Package packageList = append(packageList, packageForClientset(customArgs, arguments.OutputPackagePath, boilerplate)) if customArgs.FakeClient { packageList = append(packageList, fake.PackageForClientset(arguments.OutputPackagePath, customArgs.GroupVersions, boilerplate)) } // If --clientset-only=true, we don't regenerate the individual typed clients. if customArgs.ClientsetOnly { return generator.Packages(packageList) } orderer := namer.Orderer{namer.NewPrivateNamer(0)} for group, types := range groupToTypes { packageList = append(packageList, packageForGroup(group, "unversioned", orderer.OrderTypes(types), arguments.OutputPackagePath, arguments.OutputBase, boilerplate)) if customArgs.FakeClient { packageList = append(packageList, fake.PackageForGroup(group, "unversioned", orderer.OrderTypes(types), arguments.OutputPackagePath, arguments.OutputBase, boilerplate)) } } return generator.Packages(packageList) }
// Packages makes the client package definition. func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } return generator.Packages{&generator.DefaultPackage{ PackageName: "unversioned", PackagePath: arguments.OutputPackagePath, HeaderText: append(boilerplate, []byte( ` // This file was autogenerated by the command: // $ `+strings.Join(os.Args, " ")+` // Do not edit it manually! `)...), PackageDocumentation: []byte( `// Package unversioned has the automatically generated clients for unversioned resources. `), // GeneratorFunc returns a list of generators. Each generator makes a // single file. GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { generators = []generator.Generator{ // Always generate a "doc.go" file. generator.DefaultGen{OptionalName: "doc"}, } // Since we want a file per type that we generate a client for, we // have to provide a function for this. for _, t := range c.Order { generators = append(generators, &genClientForType{ DefaultGen: generator.DefaultGen{ // Use the privatized version of the // type name as the file name. // // TODO: make a namer that converts // camelCase to '-' separation for file // names? OptionalName: c.Namers["private"].Name(t), }, outputPackage: arguments.OutputPackagePath, typeToMatch: t, imports: generator.NewImportTracker(), }) } return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { return types.ExtractCommentTags("+", t.CommentLines)["genclient"] == "true" }, }} }
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(arguments.InputDirs...) packages := generator.Packages{} header := append([]byte( ` // +build !ignore_autogenerated `), boilerplate...) header = append(header, []byte( ` // This file was autogenerated by deepcopy-gen. Do not edit it manually! `)...) for _, p := range context.Universe { copyableType := false for _, t := range p.Types { if copyableWithinPackage(t) { copyableType = true } } if copyableType { path := p.Path packages = append(packages, &generator.DefaultPackage{ PackageName: filepath.Base(path), PackagePath: path, HeaderText: header, GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { generators = []generator.Generator{} generators = append( generators, NewGenDeepCopy("deep_copy_generated", path, inputs.Has(path))) return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { if t.Name.Package != path { return false } return copyableWithinPackage(t) }, }) } } return packages }
// Packages makes the client package definition. func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } customArgs, ok := arguments.CustomArgs.(ClientGenArgs) if !ok { glog.Fatalf("cannot convert arguments.CustomArgs to ClientGenArgs") } gvToTypes := map[unversioned.GroupVersion][]*types.Type{} for gv, inputDir := range customArgs.GroupVersionToInputPath { p := context.Universe.Package(inputDir) for _, t := range p.Types { if types.ExtractCommentTags("+", t.SecondClosestCommentLines)["genclient"] != "true" { continue } if _, found := gvToTypes[gv]; !found { gvToTypes[gv] = []*types.Type{} } gvToTypes[gv] = append(gvToTypes[gv], t) } } var packageList []generator.Package packageList = append(packageList, packageForClientset(customArgs, arguments.OutputPackagePath, boilerplate)) if customArgs.FakeClient { packageList = append(packageList, fake.PackageForClientset(arguments.OutputPackagePath, customArgs.GroupVersions, boilerplate)) } // If --clientset-only=true, we don't regenerate the individual typed clients. if customArgs.ClientsetOnly { return generator.Packages(packageList) } orderer := namer.Orderer{namer.NewPrivateNamer(0)} for _, gv := range customArgs.GroupVersions { types := gvToTypes[gv] packageList = append(packageList, packageForGroup(normalization.GroupVersion(gv), orderer.OrderTypes(types), arguments.OutputPackagePath, arguments.OutputBase, boilerplate)) if customArgs.FakeClient { packageList = append(packageList, fake.PackageForGroup(normalization.GroupVersion(gv), orderer.OrderTypes(types), arguments.OutputPackagePath, arguments.OutputBase, boilerplate)) } } return generator.Packages(packageList) }
func Packages(_ *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } packages := generator.Packages{} for _, inputDir := range arguments.InputDirs { packages = append(packages, &generator.DefaultPackage{ PackageName: filepath.Base(inputDir), PackagePath: inputDir, HeaderText: append(boilerplate, []byte( ` // This file was autogenerated by the command: // $ `+strings.Join(os.Args, " ")+` // Do not edit it manually! `)...), GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { generators = []generator.Generator{} // TODO: Check whether anything will be generated. generators = append(generators, NewGenDeepCopy("deep_copy_generated", inputDir)) return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { switch t.Kind { case types.Func, types.Chan: // These types can't be copied. return false case types.Unknown, types.Unsupported: // These types are explicitly ignored. return false case types.Array: // We don't support arrays. return false } // Also, filter out private types. if strings.ToLower(t.Name.Name[:1]) == t.Name.Name[:1] { return false } return true }, }) } return packages }
// Packages makes the client package definition. func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } customArgs, ok := arguments.CustomArgs.(clientgenargs.Args) if !ok { glog.Fatalf("cannot convert arguments.CustomArgs to clientgenargs.Args") } includedTypesOverrides := customArgs.IncludedTypesOverrides generatedBy := generatedBy(customArgs) gvToTypes := map[unversioned.GroupVersion][]*types.Type{} for gv, inputDir := range customArgs.GroupVersionToInputPath { p := context.Universe.Package(inputDir) for n, t := range p.Types { // filter out types which are not included in user specified overrides. typesOverride, ok := includedTypesOverrides[gv] if ok { found := false for _, typeStr := range typesOverride { if typeStr == n { found = true } } if !found { continue } } else { // User has not specified any override for this group version. // filter out types which dont have genclient=true. if types.ExtractCommentTags("+", t.SecondClosestCommentLines)["genclient"] != "true" { continue } } if _, found := gvToTypes[gv]; !found { gvToTypes[gv] = []*types.Type{} } gvToTypes[gv] = append(gvToTypes[gv], t) } } var packageList []generator.Package typedClientBasePath := filepath.Join(customArgs.ClientsetOutputPath, customArgs.ClientsetName, "typed") packageList = append(packageList, packageForClientset(customArgs, typedClientBasePath, boilerplate, generatedBy)) if customArgs.FakeClient { packageList = append(packageList, fake.PackageForClientset(customArgs, typedClientBasePath, boilerplate, generatedBy)) } // If --clientset-only=true, we don't regenerate the individual typed clients. if customArgs.ClientsetOnly { return generator.Packages(packageList) } orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} for _, gv := range customArgs.GroupVersions { types := gvToTypes[gv] inputPath := customArgs.GroupVersionToInputPath[gv] packageList = append(packageList, packageForGroup(normalization.GroupVersion(gv), orderer.OrderTypes(types), typedClientBasePath, arguments.OutputBase, inputPath, boilerplate, generatedBy)) if customArgs.FakeClient { packageList = append(packageList, fake.PackageForGroup(normalization.GroupVersion(gv), orderer.OrderTypes(types), typedClientBasePath, arguments.OutputBase, inputPath, boilerplate, generatedBy)) } } return generator.Packages(packageList) }
// Packages makes the sets package definition. func Packages(_ *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } return generator.Packages{&generator.DefaultPackage{ PackageName: "sets", PackagePath: arguments.OutputPackagePath, HeaderText: append(boilerplate, []byte( ` // This file was autogenerated by set-gen. Do not edit it manually! `)...), PackageDocumentation: []byte( `// Package sets has auto-generated set types. `), // GeneratorFunc returns a list of generators. Each generator makes a // single file. GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { generators = []generator.Generator{ // Always generate a "doc.go" file. generator.DefaultGen{OptionalName: "doc"}, // Make a separate file for the Empty type, since it's shared by every type. generator.DefaultGen{ OptionalName: "empty", OptionalBody: []byte(emptyTypeDecl), }, } // Since we want a file per type that we generate a set for, we // have to provide a function for this. for _, t := range c.Order { generators = append(generators, &genSet{ DefaultGen: generator.DefaultGen{ // Use the privatized version of the // type name as the file name. // // TODO: make a namer that converts // camelCase to '-' separation for file // names? OptionalName: c.Namers["private"].Name(t), }, outputPackage: arguments.OutputPackagePath, typeToMatch: t, imports: generator.NewImportTracker(), }) } return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { // It would be reasonable to filter by the type's package here. // It might be necessary if your input directory has a big // import graph. switch t.Kind { case types.Map, types.Slice, types.Pointer: // These types can't be keys in a map. return false case types.Builtin: return true case types.Struct: // Only some structs can be keys in a map. This is triggered by the line // // +genset // or // // +genset=true return types.ExtractCommentTags("+", t.CommentLines)["genset"] == "true" } return false }, }} }
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 deepcopy-gen. Do not edit it manually! `)...) boundingDirs := []string{} if customArgs, ok := arguments.CustomArgs.(*CustomArgs); ok { for i := range customArgs.BoundingDirs { // Strip any trailing slashes - they are not exactly "correct" but // this is friendlier. boundingDirs = append(boundingDirs, strings.TrimRight(customArgs.BoundingDirs[i], "/")) } } 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 } ptag := extractTag(pkg.Comments) ptagValue := "" ptagRegister := false if ptag != nil { ptagValue = ptag.value if ptagValue != tagValuePackage { glog.Fatalf("Package %v: unsupported %s value: %q", i, tagName, ptagValue) } ptagRegister = ptag.register glog.V(5).Infof(" tag.value: %q, tag.register: %t", ptagValue, ptagRegister) } else { glog.V(5).Infof(" no tag") } // If the pkg-scoped tag says to generate, we can skip scanning types. pkgNeedsGeneration := (ptagValue == tagValuePackage) if !pkgNeedsGeneration { // If the pkg-scoped tag did not exist, scan all types for one that // explicitly wants generation. for _, t := range pkg.Types { glog.V(5).Infof(" considering type %q", t.Name.String()) ttag := extractTag(t.CommentLines) if ttag != nil && ttag.value == "true" { glog.V(5).Infof(" tag=true") if !copyableType(t) { glog.Fatalf("Type %v requests deepcopy generation but is not copyable", t) } pkgNeedsGeneration = true break } } } if pkgNeedsGeneration { packages = append(packages, &generator.DefaultPackage{ PackageName: strings.Split(filepath.Base(pkg.Path), ".")[0], PackagePath: pkg.Path, HeaderText: header, GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { generators = []generator.Generator{} generators = append( generators, NewGenDeepCopy(arguments.OutputFileBaseName, pkg.Path, boundingDirs, (ptagValue == tagValuePackage), ptagRegister)) return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { return t.Name.Package == pkg.Path }, }) } } return packages }
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } initInputs := sets.NewString() explicitInputs := sets.NewString() inputs := sets.NewString() for _, s := range arguments.InputDirs { switch { case strings.HasPrefix(s, "+"): // packages with '+' prefix get functions generated for everything except gencopy=false, but // no init function s = strings.TrimPrefix(s, "+") inputs.Insert(s) case strings.HasPrefix(s, "-"): // packages with '-' prefix only get functions generated for those with gencopy=true s = strings.TrimPrefix(s, "-") inputs.Insert(s) explicitInputs.Insert(s) default: inputs.Insert(s) initInputs.Insert(s) } } var restrictRange []string if c, ok := arguments.CustomArgs.(Constraints); ok { restrictRange = c.PackageConstraints } packages := generator.Packages{} header := append([]byte( `// +build !ignore_autogenerated `), boilerplate...) header = append(header, []byte( ` // This file was autogenerated by deepcopy-gen. Do not edit it manually! `)...) for _, p := range context.Universe { copyableType := false for _, t := range p.Types { if copyableWithinPackage(t, explicitInputs.Has(t.Name.Package)) && inputs.Has(t.Name.Package) { copyableType = true } } if copyableType { // TODO: replace this with a more sophisticated algorithm that generates private copy methods // (like auto_DeepCopy_...) for any type that is outside of the PackageConstraints. That would // avoid having to make a reflection call. canInlineTypeFn := func(c *generator.Context, t *types.Type) bool { // types must be public structs or have a custom DeepCopy_<method> already defined if !copyableWithinPackage(t, explicitInputs.Has(t.Name.Package)) && !publicCopyFunctionDefined(c, t) { return false } // only packages within the restricted range can be inlined for _, s := range restrictRange { if strings.HasPrefix(t.Name.Package, s) { return true } } return false } path := p.Path packages = append(packages, &generator.DefaultPackage{ PackageName: strings.Split(filepath.Base(path), ".")[0], PackagePath: path, HeaderText: header, GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { generators = []generator.Generator{} generators = append( generators, NewGenDeepCopy("deep_copy_generated", path, initInputs.Has(path), explicitInputs.Has(path), canInlineTypeFn)) return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { return t.Name.Package == path }, }) } } return packages }
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(arguments.InputDirs...) packages := generator.Packages{} header := append([]byte( `// +build !ignore_autogenerated `), boilerplate...) header = append(header, []byte( ` // This file was autogenerated by conversion-gen. Do not edit it manually! `)...) // Compute all pre-existing conversion functions. preexisting := existingConversionFunctions(context) preexistingDefaults := existingDefaultingFunctions(context) // We are generating conversions only for packages that are explicitly // passed as InputDir, and only for those that have a corresponding type // (in the directory one above) and can be automatically converted to. for _, p := range context.Universe { path := p.Path if !inputs.Has(path) { continue } // Only generate conversions for package which explicitly requested it // byt setting "+genversion=true" in their doc.go file. filtered := false for _, comment := range p.DocComments { comment := strings.Trim(comment, "//") if types.ExtractCommentTags("+", comment)["genconversion"] == "true" { filtered = true } } if !filtered { continue } convertibleType := false for _, t := range p.Types { // Check whether this type can be auto-converted to the internal // version. internalType, exists := getInternalTypeFor(context, t) if !exists { // There is no corresponding type in the internal package. continue } // We won't be able to convert to private type. if namer.IsPrivateGoName(internalType.Name.Name) { continue } // If we can generate conversion in any direction, we should // generate this package. if isConvertible(t, internalType, preexisting) || isConvertible(internalType, t, preexisting) { convertibleType = true } } if convertibleType { packages = append(packages, &generator.DefaultPackage{ PackageName: filepath.Base(path), PackagePath: path, HeaderText: header, GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { generators = []generator.Generator{} generators = append( generators, NewGenConversion("conversion_generated", path, preexisting, preexistingDefaults)) return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { return t.Name.Package == path }, }) } } return packages }
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(arguments.InputDirs...) packages := generator.Packages{} header := append([]byte( ` // +build !ignore_autogenerated `), boilerplate...) header = append(header, []byte( ` // This file was autogenerated by conversion-gen. Do not edit it manually! `)...) // Compute all pre-existing conversion functions. preexisting := existingConversionFunctions(context) // We are generating conversions only for packages that are explicitly // passed as InputDir, and only for those that have a corresponding type // (in the directory one above) and can be automatically converted to. for _, p := range context.Universe { path := p.Path // TODO: Only a subset of InputDirs is actually where we would like // to generate conversions, the rest of files are added, because either // conversion methods are generated there or they contain types // necessary for conversions. if !inputs.Has(path) { continue } convertibleType := false for _, t := range p.Types { // Check whether this type can be auto-converted to the internal // version. internalType, exists := getInternalTypeFor(context, t) if !exists { // There is no corresponding type in the internal package. continue } // If we can generate conversion in any direction, we should // generate this package. if isConvertible(t, internalType, preexisting) || isConvertible(internalType, t, preexisting) { convertibleType = true } } if convertibleType { packages = append(packages, &generator.DefaultPackage{ PackageName: filepath.Base(path), PackagePath: path, HeaderText: header, GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { generators = []generator.Generator{} generators = append( generators, NewGenConversion("conversion_generated", path, preexisting)) return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { return t.Name.Package == path }, }) } } return packages }
// Packages makes the client package definition. func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages { boilerplate, err := arguments.LoadGoBoilerplate() if err != nil { glog.Fatalf("Failed loading boilerplate: %v", err) } groupToTypes := map[string][]*types.Type{} for _, inputDir := range arguments.InputDirs { p := context.Universe.Package(inputDir) for _, t := range p.Types { if types.ExtractCommentTags("+", t.CommentLines)["genclient"] != "true" { continue } group := filepath.Base(t.Name.Package) // Special case for the legacy API. if group == "api" { group = "" } if _, found := groupToTypes[group]; !found { groupToTypes[group] = []*types.Type{} } groupToTypes[group] = append(groupToTypes[group], t) } } return generator.Packages{&generator.DefaultPackage{ PackageName: filepath.Base(arguments.OutputPackagePath), PackagePath: arguments.OutputPackagePath, HeaderText: boilerplate, PackageDocumentation: []byte( `// Package unversioned has the automatically generated clients for unversioned resources. `), // GeneratorFunc returns a list of generators. Each generator makes a // single file. GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { generators = []generator.Generator{ // Always generate a "doc.go" file. generator.DefaultGen{OptionalName: "doc"}, } // Since we want a file per type that we generate a client for, we // have to provide a function for this. for _, t := range c.Order { generators = append(generators, &genClientForType{ DefaultGen: generator.DefaultGen{ // Use the privatized version of the // type name as the file name. // // TODO: make a namer that converts // camelCase to '-' separation for file // names? OptionalName: c.Namers["private"].Name(t), }, outputPackage: arguments.OutputPackagePath, typeToMatch: t, imports: generator.NewImportTracker(), }) } for group, types := range groupToTypes { generators = append(generators, &genGroup{ DefaultGen: generator.DefaultGen{ OptionalName: group, }, outputPackage: arguments.OutputPackagePath, group: group, types: types, imports: generator.NewImportTracker(), }) } return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { return types.ExtractCommentTags("+", t.CommentLines)["genclient"] == "true" }, }} }
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 }
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...) header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...) header = append(header, []byte( ` // This file was autogenerated by openapi-gen. Do not edit it manually! `)...) targets := []*types.Type{} for i := range inputs { glog.V(5).Infof("considering pkg %q", i) pkg, ok := context.Universe[i] if !ok { // If the input had no Go files, for example. continue } for _, t := range pkg.Types { if hasOpenAPITagValue(t.CommentLines, tagTargetType) { glog.V(5).Infof("target type : %q", t) targets = append(targets, t) } } } switch len(targets) { case 0: // If no target package found, that means the generated file in target package is up to date // and build excluded the target package. return generator.Packages{} case 1: pkg := context.Universe[targets[0].Name.Package] return generator.Packages{&generator.DefaultPackage{ PackageName: strings.Split(filepath.Base(pkg.Path), ".")[0], PackagePath: pkg.Path, HeaderText: header, GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { return []generator.Generator{NewOpenAPIGen(arguments.OutputFileBaseName, targets[0], context)} }, FilterFunc: func(c *generator.Context, t *types.Type) bool { // There is a conflict between this codegen and codecgen, we should avoid types generated for codecgen if strings.HasPrefix(t.Name.Name, "codecSelfer") { return false } pkg := context.Universe.Package(t.Name.Package) if hasOpenAPITagValue(pkg.Comments, tagValueTrue) { return !hasOpenAPITagValue(t.CommentLines, tagValueFalse) } if hasOpenAPITagValue(t.CommentLines, tagValueTrue) { return true } return false }, }, } default: glog.Fatalf("Duplicate target type found: %v", targets) } return generator.Packages{} }