github.com/argoproj/argo-cd@v1.8.7/hack/known_types/main.go (about)

     1  package main
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"go/importer"
     7  	"go/types"
     8  	"io/ioutil"
     9  	"os"
    10  	"runtime"
    11  	"strings"
    12  
    13  	"github.com/spf13/cobra"
    14  )
    15  
    16  func main() {
    17  	if err := newCommand().Execute(); err != nil {
    18  		os.Exit(1)
    19  	}
    20  }
    21  
    22  const (
    23  	packagePrefix = "k8s.io/api/"
    24  )
    25  
    26  func newCommand() *cobra.Command {
    27  	var (
    28  		docsOutputPath string = ""
    29  	)
    30  	var command = &cobra.Command{
    31  		Use:     "go run github.com/argoproj/argo-cd/hack/known_types ALIAS PACKAGE_PATH OUTPUT_PATH",
    32  		Example: "go run github.com/argoproj/argo-cd/hack/known_types corev1 k8s.io/api/core/v1 corev1_known_types.go",
    33  		RunE: func(c *cobra.Command, args []string) error {
    34  			if len(args) < 3 {
    35  				return errors.New("alias and package are not specified")
    36  			}
    37  			alias := args[0]
    38  			packagePath := args[1]
    39  			outputPath := args[2]
    40  
    41  			var imprt types.Importer
    42  			if runtime.GOOS == "linux" {
    43  				// nolint:staticcheck
    44  				imprt = importer.For("source", nil)
    45  			} else {
    46  				imprt = importer.Default()
    47  			}
    48  
    49  			pkg, err := imprt.Import(packagePath)
    50  			if err != nil {
    51  				return err
    52  			}
    53  			if !strings.HasPrefix(packagePath, packagePrefix) {
    54  				return fmt.Errorf("package must be under %s", packagePrefix)
    55  			}
    56  			shortPackagePath := strings.TrimPrefix(packagePath, packagePrefix)
    57  
    58  			var mapItems []string
    59  			var docs []string
    60  
    61  			names := pkg.Scope().Names()
    62  			for i := range names {
    63  				obj := pkg.Scope().Lookup(names[i])
    64  				typeName, ok := obj.(*types.TypeName)
    65  				if !ok || !typeName.Exported() {
    66  					continue
    67  				}
    68  				_, isStruct := typeName.Type().Underlying().(*types.Struct)
    69  				_, isMap := typeName.Type().Underlying().(*types.Map)
    70  				if !isStruct && !isMap {
    71  					continue
    72  				}
    73  
    74  				docs = append(docs, fmt.Sprintf("%s/%s", shortPackagePath, typeName.Name()))
    75  				mapItems = append(mapItems, fmt.Sprintf(`
    76  	knownTypes["%s/%s"] = func() interface{} {
    77  		return &%s.%s{}
    78  	}`, shortPackagePath, typeName.Name(), alias, typeName.Name()))
    79  			}
    80  			res := fmt.Sprintf(`// Code generated by github.com/argoproj/argo-cd/hack/known_types. DO NOT EDIT.
    81  package normalizers
    82  
    83  import corev1 "k8s.io/api/core/v1"
    84  
    85  func init() {%s
    86  }`, strings.Join(mapItems, ""))
    87  			if docsOutputPath != "" {
    88  				if err = ioutil.WriteFile(docsOutputPath, []byte(strings.Join(docs, "\n")), 0644); err != nil {
    89  					return err
    90  				}
    91  			}
    92  
    93  			return ioutil.WriteFile(outputPath, []byte(res), 0644)
    94  		},
    95  	}
    96  	command.Flags().StringVar(&docsOutputPath, "docs", "", "Docs output file path")
    97  	return command
    98  }