github.com/rancher/types@v0.0.0-20220328215343-4370ff10ecd5/generator/generator.go (about)

     1  package generator
     2  
     3  import (
     4  	"fmt"
     5  	"path"
     6  	"strings"
     7  
     8  	"net/http"
     9  	"os"
    10  	"os/exec"
    11  	"path/filepath"
    12  	"text/template"
    13  
    14  	"github.com/rancher/norman/generator"
    15  	"github.com/rancher/norman/types"
    16  	"github.com/rancher/norman/types/convert"
    17  	"k8s.io/apimachinery/pkg/runtime/schema"
    18  	"k8s.io/gengo/args"
    19  )
    20  
    21  var (
    22  	basePackage = "github.com/rancher/types"
    23  	baseCattle  = "client"
    24  	baseK8s     = "apis"
    25  	baseCompose = "compose"
    26  )
    27  
    28  func funcs() template.FuncMap {
    29  	return template.FuncMap{
    30  		"capitalize":   convert.Capitalize,
    31  		"unCapitalize": convert.Uncapitalize,
    32  		"upper":        strings.ToUpper,
    33  		"toLower":      strings.ToLower,
    34  		"hasGet":       hasGet,
    35  		"hasPost":      hasPost,
    36  	}
    37  }
    38  
    39  func hasGet(schema *types.Schema) bool {
    40  	return contains(schema.CollectionMethods, http.MethodGet)
    41  }
    42  
    43  func hasPost(schema *types.Schema) bool {
    44  	return contains(schema.CollectionMethods, http.MethodPost)
    45  }
    46  
    47  func contains(list []string, needle string) bool {
    48  	for _, i := range list {
    49  		if i == needle {
    50  			return true
    51  		}
    52  	}
    53  	return false
    54  }
    55  
    56  func Generate(schemas *types.Schemas, backendTypes map[string]bool) {
    57  	version := getVersion(schemas)
    58  	group := strings.Split(version.Group, ".")[0]
    59  
    60  	cattleOutputPackage := path.Join(basePackage, baseCattle, group, version.Version)
    61  	k8sOutputPackage := path.Join(basePackage, baseK8s, version.Group, version.Version)
    62  
    63  	if err := generator.Generate(schemas, backendTypes, cattleOutputPackage, k8sOutputPackage); err != nil {
    64  		panic(err)
    65  	}
    66  }
    67  
    68  func GenerateComposeType(projectSchemas *types.Schemas, managementSchemas *types.Schemas, clusterSchemas *types.Schemas) {
    69  	if err := generateComposeType(filepath.Join(basePackage, baseCompose), projectSchemas, managementSchemas, clusterSchemas); err != nil {
    70  		panic(err)
    71  	}
    72  }
    73  
    74  func generateComposeType(baseCompose string, projectSchemas *types.Schemas, managementSchemas *types.Schemas, clusterSchemas *types.Schemas) error {
    75  	outputDir := filepath.Join(args.DefaultSourceTree(), baseCompose)
    76  	if err := os.MkdirAll(outputDir, 0755); err != nil {
    77  		return err
    78  	}
    79  	filePath := "zz_generated_compose.go"
    80  	output, err := os.Create(path.Join(outputDir, filePath))
    81  	if err != nil {
    82  		return err
    83  	}
    84  	defer output.Close()
    85  
    86  	typeTemplate, err := template.New("compose.template").
    87  		Funcs(funcs()).
    88  		Parse(strings.Replace(composeTemplate, "%BACK%", "`", -1))
    89  	if err != nil {
    90  		return err
    91  	}
    92  
    93  	if err := typeTemplate.Execute(output, map[string]interface{}{
    94  		"managementSchemas": managementSchemas.Schemas(),
    95  		"projectSchemas":    projectSchemas.Schemas(),
    96  		"clusterSchemas":    clusterSchemas.Schemas(),
    97  	}); err != nil {
    98  		return err
    99  	}
   100  
   101  	return gofmt(args.DefaultSourceTree(), baseCompose)
   102  }
   103  
   104  func gofmt(workDir, pkg string) error {
   105  	cmd := exec.Command("goimports", "-w", "-l", "./"+pkg)
   106  	cmd.Dir = workDir
   107  	cmd.Stdout = os.Stdout
   108  	cmd.Stderr = os.Stderr
   109  
   110  	return cmd.Run()
   111  }
   112  
   113  func GenerateNativeTypes(gv schema.GroupVersion, nsObjs []interface{}, objs []interface{}) {
   114  	version := gv.Version
   115  	group := gv.Group
   116  	groupPath := group
   117  
   118  	if groupPath == "" {
   119  		groupPath = "core"
   120  	}
   121  
   122  	k8sOutputPackage := path.Join(basePackage, baseK8s, groupPath, version)
   123  
   124  	if err := generator.GenerateControllerForTypes(&types.APIVersion{
   125  		Version: version,
   126  		Group:   group,
   127  		Path:    fmt.Sprintf("/k8s/%s-%s", groupPath, version),
   128  	}, k8sOutputPackage, nsObjs, objs); err != nil {
   129  		panic(err)
   130  	}
   131  }
   132  
   133  func getVersion(schemas *types.Schemas) *types.APIVersion {
   134  	var version types.APIVersion
   135  	for _, schema := range schemas.Schemas() {
   136  		if version.Group == "" {
   137  			version = schema.Version
   138  			continue
   139  		}
   140  		if version.Group != schema.Version.Group ||
   141  			version.Version != schema.Version.Version {
   142  			panic("schema set contains two APIVersions")
   143  		}
   144  	}
   145  
   146  	return &version
   147  }