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

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