// 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) }
// NameSystems returns the name system used by the generators in this package. func NameSystems() namer.NameSystems { return namer.NameSystems{ "public": namer.NewPublicNamer(0), "private": namer.NewPrivateNamer(0), "raw": namer.NewRawNamer("", nil), } }
// 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) }
// NameSystems returns the name system used by the generators in this package. func NameSystems() namer.NameSystems { pluralExceptions := map[string]string{ "Endpoints": "Endpoints", "ComponentStatus": "ComponentStatus", } return namer.NameSystems{ "public": namer.NewPublicNamer(0), "private": namer.NewPrivateNamer(0), "raw": namer.NewRawNamer("", nil), "publicPlural": namer.NewPublicPluralNamer(pluralExceptions), "privatePlural": namer.NewPrivatePluralNamer(pluralExceptions), } }
// NameSystems returns the name system used by the generators in this package. func NameSystems() namer.NameSystems { pluralExceptions := map[string]string{ "Endpoints": "Endpoints", "SecurityContextConstraints": "SecurityContextConstraints", } return namer.NameSystems{ "public": namer.NewPublicNamer(0), "private": namer.NewPrivateNamer(0), "raw": namer.NewRawNamer("", nil), "publicPlural": namer.NewPublicPluralNamer(pluralExceptions), "privatePlural": namer.NewPrivatePluralNamer(pluralExceptions), "allLowercasePlural": namer.NewAllLowercasePluralNamer(pluralExceptions), } }
// 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 construct(t *testing.T, files map[string]string) *generator.Context { b := parser.New() for name, src := range files { if err := b.AddFile(name, []byte(src)); err != nil { t.Fatal(err) } } c, err := generator.NewContext(b, namer.NameSystems{ "public": namer.NewPublicNamer(0), "private": namer.NewPrivateNamer(0), }, "public") if err != nil { t.Fatal(err) } return c }
func construct(t *testing.T, files map[string]string) *generator.Context { b := parser.New() dir, err := ioutil.TempDir("", "snippet_writer_test") if err != nil { t.Fatal(err) } for name, src := range files { if err := b.AddFile(filepath.Join(dir, name), name, []byte(src)); err != nil { t.Fatal(err) } } c, err := generator.NewContext(b, namer.NameSystems{ "public": namer.NewPublicNamer(0), "private": namer.NewPrivateNamer(0), }, "public") if err != nil { t.Fatal(err) } return c }
// 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) }
func TestTypeKindParse(t *testing.T) { var testFiles = map[string]string{ "a/foo.go": "package a\ntype Test string\n", "b/foo.go": "package b\ntype Test map[int]string\n", "c/foo.go": "package c\ntype Test []string\n", "d/foo.go": "package d\ntype Test struct{a int; b struct{a int}; c map[int]string; d *string}\n", "e/foo.go": "package e\ntype Test *string\n", "f/foo.go": ` package f import ( "a" "b" ) type Test []a.Test type Test2 *a.Test type Test3 map[a.Test]b.Test type Test4 struct { a struct {a a.Test; b b.Test} b map[a.Test]b.Test c *a.Test d []a.Test e []string } `, "g/foo.go": ` package g type Test func(a, b string) (c, d string) func (t Test) Method(a, b string) (c, d string) { return t(a, b) } type Interface interface{Method(a, b string) (c, d string)} `, } // Check that the right types are found, and the namers give the expected names. assertions := []struct { Package, Name string k types.Kind names []string }{ { Package: "a", Name: "Test", k: types.Alias, names: []string{"Test", "ATest", "test", "aTest", "a.Test"}, }, { Package: "b", Name: "Test", k: types.Map, names: []string{"Test", "BTest", "test", "bTest", "b.Test"}, }, { Package: "c", Name: "Test", k: types.Slice, names: []string{"Test", "CTest", "test", "cTest", "c.Test"}, }, { Package: "d", Name: "Test", k: types.Struct, names: []string{"Test", "DTest", "test", "dTest", "d.Test"}, }, { Package: "e", Name: "Test", k: types.Pointer, names: []string{"Test", "ETest", "test", "eTest", "e.Test"}, }, { Package: "f", Name: "Test", k: types.Slice, names: []string{"Test", "FTest", "test", "fTest", "f.Test"}, }, { Package: "g", Name: "Test", k: types.Func, names: []string{"Test", "GTest", "test", "gTest", "g.Test"}, }, { Package: "g", Name: "Interface", k: types.Interface, names: []string{"Interface", "GInterface", "interface", "gInterface", "g.Interface"}, }, { Package: "", Name: "string", k: types.Builtin, names: []string{"String", "String", "string", "string", "string"}, }, { Package: "", Name: "int", k: types.Builtin, names: []string{"Int", "Int", "int", "int", "int"}, }, { Package: "", Name: "struct{a int}", k: types.Struct, names: []string{"StructInt", "StructInt", "structInt", "structInt", "struct{a int}"}, }, { Package: "", Name: "struct{a a.Test; b b.Test}", k: types.Struct, names: []string{"StructTestTest", "StructATestBTest", "structTestTest", "structATestBTest", "struct{a a.Test; b b.Test}"}, }, { Package: "", Name: "map[int]string", k: types.Map, names: []string{"MapIntToString", "MapIntToString", "mapIntToString", "mapIntToString", "map[int]string"}, }, { Package: "", Name: "map[a.Test]b.Test", k: types.Map, names: []string{"MapTestToTest", "MapATestToBTest", "mapTestToTest", "mapATestToBTest", "map[a.Test]b.Test"}, }, { Package: "", Name: "[]string", k: types.Slice, names: []string{"SliceString", "SliceString", "sliceString", "sliceString", "[]string"}, }, { Package: "", Name: "[]a.Test", k: types.Slice, names: []string{"SliceTest", "SliceATest", "sliceTest", "sliceATest", "[]a.Test"}, }, { Package: "", Name: "*string", k: types.Pointer, names: []string{"PointerString", "PointerString", "pointerString", "pointerString", "*string"}, }, { Package: "", Name: "*a.Test", k: types.Pointer, names: []string{"PointerTest", "PointerATest", "pointerTest", "pointerATest", "*a.Test"}, }, } namers := []namer.Namer{ namer.NewPublicNamer(0), namer.NewPublicNamer(1), namer.NewPrivateNamer(0), namer.NewPrivateNamer(1), namer.NewRawNamer("", nil), } for nameIndex, namer := range namers { _, u, _ := construct(t, testFiles, namer) t.Logf("Found types:\n") for pkgName, pkg := range u { for typeName, cur := range pkg.Types { t.Logf("%q-%q: %s %s", pkgName, typeName, cur.Name, cur.Kind) } } t.Logf("\n\n") for _, item := range assertions { n := types.Name{Package: item.Package, Name: item.Name} thisType := u.Get(n) if thisType == nil { t.Errorf("type %s not found", n) continue } if e, a := item.k, thisType.Kind; e != a { t.Errorf("%v-%s: type kind wrong, wanted %v, got %v (%#v)", nameIndex, n, e, a, thisType) } if e, a := item.names[nameIndex], namer.Name(thisType); e != a { t.Errorf("%v-%s: Expected %q, got %q", nameIndex, n, e, a) } } // Also do some one-off checks gtest := u.Get(types.Name{Package: "g", Name: "Test"}) if e, a := 1, len(gtest.Methods); e != a { t.Errorf("expected %v but found %v methods: %#v", e, a, gtest) } iface := u.Get(types.Name{Package: "g", Name: "Interface"}) if e, a := 1, len(iface.Methods); e != a { t.Errorf("expected %v but found %v methods: %#v", e, a, iface) } } }