k3s/vendor/github.com/rancher/wrangler/pkg/controller-gen/main.go

300 lines
8.0 KiB
Go
Raw Normal View History

2019-05-09 22:03:45 +00:00
package controllergen
import (
"io"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
"github.com/sirupsen/logrus"
cgargs "github.com/rancher/wrangler/pkg/controller-gen/args"
"github.com/rancher/wrangler/pkg/controller-gen/generators"
"k8s.io/apimachinery/pkg/runtime/schema"
csargs "k8s.io/code-generator/cmd/client-gen/args"
clientgenerators "k8s.io/code-generator/cmd/client-gen/generators"
cs "k8s.io/code-generator/cmd/client-gen/generators"
types2 "k8s.io/code-generator/cmd/client-gen/types"
dpargs "k8s.io/code-generator/cmd/deepcopy-gen/args"
infargs "k8s.io/code-generator/cmd/informer-gen/args"
inf "k8s.io/code-generator/cmd/informer-gen/generators"
lsargs "k8s.io/code-generator/cmd/lister-gen/args"
ls "k8s.io/code-generator/cmd/lister-gen/generators"
"k8s.io/gengo/args"
dp "k8s.io/gengo/examples/deepcopy-gen/generators"
"k8s.io/gengo/types"
)
func Run(opts cgargs.Options) {
customArgs := &cgargs.CustomArgs{
Options: opts,
TypesByGroup: map[schema.GroupVersion][]*types.Name{},
Package: opts.OutputPackage,
}
genericArgs := args.Default().WithoutDefaultFlagParsing()
genericArgs.CustomArgs = customArgs
genericArgs.GoHeaderFilePath = opts.Boilerplate
genericArgs.InputDirs = parseTypes(customArgs)
if genericArgs.OutputBase == "./" { //go modules
tempDir, err := ioutil.TempDir("", "")
if err != nil {
return
}
genericArgs.OutputBase = tempDir
defer os.RemoveAll(tempDir)
}
customArgs.OutputBase = genericArgs.OutputBase
clientGen := generators.NewClientGenerator()
if err := genericArgs.Execute(
clientgenerators.NameSystems(),
clientgenerators.DefaultNameSystem(),
clientGen.Packages,
); err != nil {
logrus.Fatalf("Error: %v", err)
}
groups := map[string]bool{}
for groupName, group := range customArgs.Options.Groups {
if group.GenerateTypes {
groups[groupName] = true
}
}
if len(groups) == 0 {
if err := copyGoPathToModules(customArgs); err != nil {
logrus.Fatalf("go modules copy failed: %v", err)
}
if err := clientGen.GenerateMocks(); err != nil {
logrus.Errorf("mocks failed: %v", err)
return
}
return
}
if err := copyGoPathToModules(customArgs); err != nil {
logrus.Fatalf("go modules copy failed: %v", err)
}
if err := generateDeepcopy(groups, customArgs); err != nil {
logrus.Fatalf("deepcopy failed: %v", err)
}
if err := generateClientset(groups, customArgs); err != nil {
logrus.Fatalf("clientset failed: %v", err)
}
if err := generateListers(groups, customArgs); err != nil {
logrus.Fatalf("listers failed: %v", err)
}
if err := generateInformers(groups, customArgs); err != nil {
logrus.Fatalf("informers failed: %v", err)
}
if err := copyGoPathToModules(customArgs); err != nil {
logrus.Fatalf("go modules copy failed: %v", err)
}
if err := clientGen.GenerateMocks(); err != nil {
logrus.Errorf("mocks failed: %v", err)
return
2019-05-09 22:03:45 +00:00
}
}
func sourcePackagePath(customArgs *cgargs.CustomArgs, pkgName string) string {
pkgSplit := strings.Split(pkgName, string(os.PathSeparator))
pkg := filepath.Join(customArgs.OutputBase, strings.Join(pkgSplit[:3], string(os.PathSeparator)))
return pkg
}
//until k8s code-gen supports gopath
func copyGoPathToModules(customArgs *cgargs.CustomArgs) error {
pathsToCopy := map[string]bool{}
for _, types := range customArgs.TypesByGroup {
for _, names := range types {
pkg := sourcePackagePath(customArgs, names.Package)
pathsToCopy[pkg] = true
}
}
pkg := sourcePackagePath(customArgs, customArgs.Package)
pathsToCopy[pkg] = true
for pkg, _ := range pathsToCopy {
if _, err := os.Stat(pkg); os.IsNotExist(err) {
continue
}
return filepath.Walk(pkg, func(path string, info os.FileInfo, err error) error {
newPath := strings.Replace(path, pkg, ".", 1)
if _, err := os.Stat(newPath); os.IsNotExist(err) {
if info.IsDir() {
return os.Mkdir(newPath, info.Mode())
}
return copyFile(path, newPath)
}
return err
})
}
return nil
}
func copyFile(src, dst string) error {
var err error
var srcfd *os.File
var dstfd *os.File
var srcinfo os.FileInfo
if srcfd, err = os.Open(src); err != nil {
return err
}
defer srcfd.Close()
if dstfd, err = os.Create(dst); err != nil {
return err
}
defer dstfd.Close()
if _, err = io.Copy(dstfd, srcfd); err != nil {
return err
}
if srcinfo, err = os.Stat(src); err != nil {
return err
}
return os.Chmod(dst, srcinfo.Mode())
}
func generateDeepcopy(groups map[string]bool, customArgs *cgargs.CustomArgs) error {
deepCopyCustomArgs := &dpargs.CustomArgs{}
args := args.Default().WithoutDefaultFlagParsing()
args.CustomArgs = deepCopyCustomArgs
args.OutputBase = customArgs.OutputBase
args.OutputFileBaseName = "zz_generated_deepcopy"
args.GoHeaderFilePath = customArgs.Options.Boilerplate
for gv, names := range customArgs.TypesByGroup {
if !groups[gv.Group] {
continue
}
args.InputDirs = append(args.InputDirs, names[0].Package)
deepCopyCustomArgs.BoundingDirs = append(deepCopyCustomArgs.BoundingDirs, names[0].Package)
}
return args.Execute(dp.NameSystems(),
dp.DefaultNameSystem(),
dp.Packages)
}
func generateClientset(groups map[string]bool, customArgs *cgargs.CustomArgs) error {
args, clientSetArgs := csargs.NewDefaults()
clientSetArgs.ClientsetName = "versioned"
args.OutputBase = customArgs.OutputBase
args.OutputPackagePath = filepath.Join(customArgs.Package, "clientset")
args.GoHeaderFilePath = customArgs.Options.Boilerplate
var order []schema.GroupVersion
for gv := range customArgs.TypesByGroup {
if !groups[gv.Group] {
continue
}
order = append(order, gv)
}
sort.Slice(order, func(i, j int) bool {
return order[i].Group < order[j].Group
})
for _, gv := range order {
names := customArgs.TypesByGroup[gv]
args.InputDirs = append(args.InputDirs, names[0].Package)
clientSetArgs.Groups = append(clientSetArgs.Groups, types2.GroupVersions{
PackageName: gv.Group,
Group: types2.Group(gv.Group),
Versions: []types2.PackageVersion{
{
Version: types2.Version(gv.Version),
Package: names[0].Package,
},
},
})
}
return args.Execute(cs.NameSystems(),
cs.DefaultNameSystem(),
cs.Packages)
}
func generateInformers(groups map[string]bool, customArgs *cgargs.CustomArgs) error {
args, clientSetArgs := infargs.NewDefaults()
clientSetArgs.VersionedClientSetPackage = filepath.Join(customArgs.Package, "clientset/versioned")
clientSetArgs.ListersPackage = filepath.Join(customArgs.Package, "listers")
args.OutputBase = customArgs.OutputBase
args.OutputPackagePath = filepath.Join(customArgs.Package, "informers")
args.GoHeaderFilePath = customArgs.Options.Boilerplate
for gv, names := range customArgs.TypesByGroup {
if !groups[gv.Group] {
continue
}
args.InputDirs = append(args.InputDirs, names[0].Package)
}
return args.Execute(inf.NameSystems(),
inf.DefaultNameSystem(),
inf.Packages)
}
func generateListers(groups map[string]bool, customArgs *cgargs.CustomArgs) error {
args, _ := lsargs.NewDefaults()
args.OutputBase = customArgs.OutputBase
args.OutputPackagePath = filepath.Join(customArgs.Package, "listers")
args.GoHeaderFilePath = customArgs.Options.Boilerplate
for gv, names := range customArgs.TypesByGroup {
if !groups[gv.Group] {
continue
}
args.InputDirs = append(args.InputDirs, names[0].Package)
}
return args.Execute(ls.NameSystems(),
ls.DefaultNameSystem(),
ls.Packages)
}
func parseTypes(customArgs *cgargs.CustomArgs) []string {
for groupName, group := range customArgs.Options.Groups {
if group.GenerateTypes {
group.InformersPackage = filepath.Join(customArgs.Package, "informers/externalversions")
group.ClientSetPackage = filepath.Join(customArgs.Package, "clientset/versioned")
group.ListersPackage = filepath.Join(customArgs.Package, "listers")
customArgs.Options.Groups[groupName] = group
}
}
for groupName, group := range customArgs.Options.Groups {
cgargs.ObjectsToGroupVersion(groupName, group.Types, customArgs.TypesByGroup)
}
var inputDirs []string
for _, names := range customArgs.TypesByGroup {
inputDirs = append(inputDirs, names[0].Package)
}
return inputDirs
}