package main import ( "flag" "fmt" "os" "os/exec" "strings" "text/template" "unicode" ) func main() { var ( enbasCLISchemaFilepath string executorsFilePath string ) flag.StringVar(&enbasCLISchemaFilepath, "path-to-enbas-cli-schema", "", "The path to the Enbas CLI schema file") flag.StringVar(&executorsFilePath, "path-to-enbas-executors", "", "The path to the executors Go file") flag.Parse() schema, err := newEnbasCLISchemaFromFile(enbasCLISchemaFilepath) if err != nil { fmt.Printf("ERROR: Unable to read the schema file: %v.\n", err) } if err := generateExecutors(schema, executorsFilePath); err != nil { fmt.Printf("ERROR: Unable to generate the executors: %v.\n", err) } if err := runGoImports(executorsFilePath); err != nil { fmt.Printf("ERROR: Unable to run goimports: %v.\n", err) } } func generateExecutors(schema enbasCLISchema, output string) error { funcMap := template.FuncMap{ "capitalise": capitalise, "convertFlagToMixedCaps": convertFlagToMixedCaps, "getFlagType": schema.Flags.getType, "getFlagDescription": schema.Flags.getDescription, } tmpl := template.Must(template.New("executor-template").Funcs(funcMap).Parse(executorsFileTemplate)) file, err := os.Create(output) if err != nil { return fmt.Errorf("unable to create the output file: %w", err) } defer file.Close() if err := tmpl.Execute(file, schema.Commands); err != nil { return fmt.Errorf("unable to generate the code from the template: %w", err) } return nil } func runGoImports(path string) error { imports := exec.Command("goimports", "-w", path) if err := imports.Run(); err != nil { return fmt.Errorf("received an error after running goimports: %w", err) } return nil } func capitalise(str string) string { runes := []rune(str) runes[0] = unicode.ToUpper(runes[0]) return string(runes) } func convertFlagToMixedCaps(value string) string { var builder strings.Builder runes := []rune(value) numRunes := len(runes) cursor := 0 for cursor < numRunes { if runes[cursor] != '-' { builder.WriteRune(runes[cursor]) cursor++ } else { if cursor != numRunes-1 && unicode.IsLower(runes[cursor+1]) { builder.WriteRune(unicode.ToUpper(runes[cursor+1])) cursor += 2 } else { cursor++ } } } return builder.String() }