package cmd import ( "fmt" "go/ast" "go/parser" "go/token" "path" "path/filepath" "strings" "github.com/spf13/cobra" ) var ( inFile string svcName string resName string resType string filePath string ) var getFieldsCmd = &cobra.Command{ Use: "get-fields", Short: "get fields from file", Long: `...`, PreRunE: func(_ *cobra.Command, _ []string) error { typeStr := "data_source" if resType != "resource" && resType != "datasource" { return fmt.Errorf("--type can only be resource or datasource") } if resType == "resource" { typeStr = resType } if inFile == "" && svcName == "" && resName == "" { return fmt.Errorf("--infile or --service and --resource must be provided") } if inFile != "" { if svcName != "" || resName != "" { return fmt.Errorf("--infile is provided and excludes --service and --resource") } p, err := filepath.Abs(inFile) if err != nil { return err } filePath = p return nil } if svcName != "" && resName == "" { return fmt.Errorf("if --service is provided, you MUST also provide --resource") } if svcName == "" && resName != "" { return fmt.Errorf("if --resource is provided, you MUST also provide --service") } p, err := filepath.Abs( path.Join( "stackit", "internal", "services", svcName, resName, fmt.Sprintf("%ss_gen", resType), fmt.Sprintf("%s_%s_gen.go", resName, typeStr), ), ) if err != nil { return err } filePath = p //// Enum check // switch format { // case "json", "yaml": //default: // return fmt.Errorf("invalid --format: %s (want json|yaml)", format) //} return nil }, RunE: func(_ *cobra.Command, _ []string) error { return getFields(filePath) }, } func getFields(f string) error { tokens, err := getTokens(f) if err != nil { return err } for _, item := range tokens { fmt.Printf("%s \n", item) } return nil } func getTokens(fileName string) ([]string, error) { fset := token.NewFileSet() var result []string node, err := parser.ParseFile(fset, fileName, nil, parser.ParseComments) if err != nil { return nil, err } ast.Inspect( node, func(n ast.Node) bool { // Suche nach Typ-Deklarationen (structs) ts, ok := n.(*ast.TypeSpec) if ok { if strings.Contains(ts.Name.Name, "Model") { ast.Inspect( ts, func(sn ast.Node) bool { tts, tok := sn.(*ast.Field) if tok { result = append(result, tts.Names[0].String()) } return true }, ) } } return true }, ) return result, nil } func NewGetFieldsCmd() *cobra.Command { return getFieldsCmd } func init() { //nolint:gochecknoinits //this is the only way to add the command to the rootCmd getFieldsCmd.Flags().StringVarP(&inFile, "infile", "i", "", "input filename incl path") getFieldsCmd.Flags().StringVarP(&svcName, "service", "s", "", "service name") getFieldsCmd.Flags().StringVarP(&resName, "resource", "r", "", "resource name") getFieldsCmd.Flags().StringVarP( &resType, "type", "t", "resource", "resource type (data-source or resource [default])", ) }