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