diff --git a/cmd/enbas-codegen/main.go b/cmd/enbas-codegen/main.go index ec562e0..ef66aea 100644 --- a/cmd/enbas-codegen/main.go +++ b/cmd/enbas-codegen/main.go @@ -1,6 +1,7 @@ package main import ( + "embed" "flag" "fmt" "os" @@ -11,13 +12,9 @@ import ( ) func main() { - var ( - enbasCLISchemaFilepath string - executorsFilePath string - ) + var enbasCLISchemaFilepath 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) @@ -25,16 +22,20 @@ func main() { fmt.Printf("ERROR: Unable to read the schema file: %v.\n", err) } - if err := generateExecutors(schema, executorsFilePath); err != nil { + if err := generateExecutors(schema); 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 { +//go:embed templates/executor/* +var executorTemplates embed.FS + +func generateExecutors(schema enbasCLISchema) error { + fsDir, err := executorTemplates.ReadDir("templates/executor") + if err != nil { + return fmt.Errorf("unable to read the template directory in the file system (FS): %w", err) + } + funcMap := template.FuncMap{ "capitalise": capitalise, "flagFieldName": flagFieldName, @@ -43,16 +44,39 @@ func generateExecutors(schema enbasCLISchema, output string) error { "internalFlagValue": internalFlagValue, } - tmpl := template.Must(template.New("executor-template").Funcs(funcMap).Parse(executorsFileTemplate)) + for _, obj := range fsDir { + templateFilename := obj.Name() - file, err := os.Create(output) - if err != nil { - return fmt.Errorf("unable to create the output file: %w", err) - } - defer file.Close() + if !strings.HasSuffix(templateFilename, ".go.gotmpl") { + continue + } - if err := tmpl.Execute(file, schema.Commands); err != nil { - return fmt.Errorf("unable to generate the code from the template: %w", err) + if err := func() error { + tmpl := template.Must(template.New(templateFilename). + Funcs(funcMap). + ParseFS(executorTemplates, "templates/executor/"+templateFilename), + ) + + output := strings.TrimSuffix(templateFilename, ".gotmpl") + + 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) + } + + if err := runGoImports(output); err != nil { + return fmt.Errorf("unable to run goimports: %w", err) + } + + return nil + }(); err != nil { + return fmt.Errorf("received an error after attempting to generate the code for %q: %w", templateFilename, err) + } } return nil diff --git a/cmd/enbas-codegen/templates/executor/execute.go.gotmpl b/cmd/enbas-codegen/templates/executor/execute.go.gotmpl new file mode 100644 index 0000000..7150211 --- /dev/null +++ b/cmd/enbas-codegen/templates/executor/execute.go.gotmpl @@ -0,0 +1,109 @@ +{{- /* vim: set noexpandtab : */ -}} +{{- /* vim: set tabstop=8 : */ -}} +{{- /* vim: set shiftwidth=8 : */ -}} +{{- /* vim: set softtabstop=8 : */ -}} +/* + This file is generated by the enbas-codegen + DO NOT EDIT. +*/ +{{ print "" }} +package executor +{{ print "" }} +{{ print "" }} +import "fmt" +import "codeflow.dananglin.me.uk/apollo/enbas/internal/config" +import "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" +{{ print "" }} +{{ print "" }} +func Execute( + command string, + args []string, + noColor bool, + configDir string, +) error { + var ( + enbasConfig *config.Config + enbasPrinter *printer.Printer + err error + ) + + switch command { + case "init", "version": + enbasPrinter = printer.NewPrinter(noColor, "", 0) + default: + enbasConfig, err = config.NewConfigFromFile(configDir) + if err != nil { + enbasPrinter = printer.NewPrinter(noColor, "", 0) + enbasPrinter.PrintFailure("unable to load the configuration: " + err.Error() + ".") + + return err + } + + enbasPrinter = printer.NewPrinter( + noColor, + enbasConfig.Integrations.Pager, + enbasConfig.LineWrapMaxWidth, + ) + } + + if err = execute( + command, + args, + enbasPrinter, + enbasConfig, + configDir, + ); err != nil { + enbasPrinter.PrintFailure("(" + command + ") " + err.Error() + ".") + + return err + } + + return nil +} +{{ print "" }} +{{ print "" }} +func execute( + command string, + args []string, + enbasPrinter *printer.Printer, + enbasConfig *config.Config, + configDir string, +) error { + executorMap := map[string]Executor{ + {{- range $name, $command := . -}} + {{- $new_executor_function_name := capitalise $name | printf "New%sExecutor" -}} + {{ print "" }} + {{ printf "%q" $name }}: {{ $new_executor_function_name }}( + {{- if $command.UsePrinter -}} + {{ print "" }} + enbasPrinter, + {{- end -}} + {{- if $command.UseConfig -}} + {{ print "" }} + enbasConfig, + {{- end -}} + {{- range $field := $command.AdditionalFields -}} + {{ print "" }} + {{ $field.Name }}, + {{- end -}} + {{ print "" }} + ), + {{- end -}} + {{ print "" }} + } + + exe, ok := executorMap[command] + if !ok { + return UnknownCommandError{Command: command} + } + + if err := exe.Parse(args); err != nil { + return fmt.Errorf("flag parsing error: %w", err) + } + + if err := exe.Execute(); err != nil { + return fmt.Errorf("execution error: %w", err) + } + + return nil +} diff --git a/cmd/enbas-codegen/templates.go b/cmd/enbas-codegen/templates/executor/executors.go.gotmpl similarity index 95% rename from cmd/enbas-codegen/templates.go rename to cmd/enbas-codegen/templates/executor/executors.go.gotmpl index a7fd082..9af5f1c 100644 --- a/cmd/enbas-codegen/templates.go +++ b/cmd/enbas-codegen/templates/executor/executors.go.gotmpl @@ -1,6 +1,8 @@ -package main - -var executorsFileTemplate = `/* +{{- /* vim: set noexpandtab : */ -}} +{{- /* vim: set tabstop=8 : */ -}} +{{- /* vim: set shiftwidth=8 : */ -}} +{{- /* vim: set softtabstop=8 : */ -}} +/* This file is generated by the enbas-codegen DO NOT EDIT. */ @@ -104,4 +106,3 @@ func {{ $new_executor_function_name }}( return &exe } {{ end }} -` diff --git a/internal/executor/codegen.go b/internal/executor/codegen.go new file mode 100644 index 0000000..c6ac0a9 --- /dev/null +++ b/internal/executor/codegen.go @@ -0,0 +1,3 @@ +package executor + +//go:generate go run ../../cmd/enbas-codegen --path-to-enbas-cli-schema ../../schema/enbas_cli_schema.json diff --git a/internal/executor/execute.go b/internal/executor/execute.go index fe4b2ab..8ffa917 100644 --- a/internal/executor/execute.go +++ b/internal/executor/execute.go @@ -1,3 +1,8 @@ +/* + This file is generated by the enbas-codegen + DO NOT EDIT. +*/ + package executor import ( @@ -20,7 +25,7 @@ func Execute( ) switch command { - case commandInit, commandVersion: + case "init", "version": enbasPrinter = printer.NewPrinter(noColor, "", 0) default: enbasConfig, err = config.NewConfigFromFile(configDir) @@ -61,78 +66,78 @@ func execute( configDir string, ) error { executorMap := map[string]Executor{ - commandAccept: NewAcceptExecutor( + "accept": NewAcceptExecutor( enbasPrinter, enbasConfig, ), - commandAdd: NewAddExecutor( + "add": NewAddExecutor( enbasPrinter, enbasConfig, ), - commandBlock: NewBlockExecutor( + "block": NewBlockExecutor( enbasPrinter, enbasConfig, ), - commandCreate: NewCreateExecutor( + "create": NewCreateExecutor( enbasPrinter, enbasConfig, ), - commandDelete: NewDeleteExecutor( + "delete": NewDeleteExecutor( enbasPrinter, enbasConfig, ), - commandEdit: NewEditExecutor( + "edit": NewEditExecutor( enbasPrinter, enbasConfig, ), - commandFollow: NewFollowExecutor( + "follow": NewFollowExecutor( enbasPrinter, enbasConfig, ), - commandInit: NewInitExecutor( + "init": NewInitExecutor( enbasPrinter, configDir, ), - commandLogin: NewLoginExecutor( + "login": NewLoginExecutor( enbasPrinter, enbasConfig, ), - commandMute: NewMuteExecutor( + "mute": NewMuteExecutor( enbasPrinter, enbasConfig, ), - commandReject: NewRejectExecutor( + "reject": NewRejectExecutor( enbasPrinter, enbasConfig, ), - commandRemove: NewRemoveExecutor( + "remove": NewRemoveExecutor( enbasPrinter, enbasConfig, ), - commandSwitch: NewSwitchExecutor( + "show": NewShowExecutor( enbasPrinter, enbasConfig, ), - commandUnfollow: NewUnfollowExecutor( + "switch": NewSwitchExecutor( enbasPrinter, enbasConfig, ), - commandUnmute: NewUnmuteExecutor( + "unblock": NewUnblockExecutor( enbasPrinter, enbasConfig, ), - commandUnblock: NewUnblockExecutor( + "unfollow": NewUnfollowExecutor( enbasPrinter, enbasConfig, ), - commandShow: NewShowExecutor( + "unmute": NewUnmuteExecutor( enbasPrinter, enbasConfig, ), - commandVersion: NewVersionExecutor( + "version": NewVersionExecutor( enbasPrinter, ), - commandWhoami: NewWhoamiExecutor( + "whoami": NewWhoamiExecutor( enbasPrinter, enbasConfig, ), diff --git a/internal/internal.go b/internal/internal.go index e9a7cd5..b47f3df 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -1,7 +1,5 @@ package internal -//go:generate go run ../cmd/enbas-codegen --path-to-enbas-cli-schema ../schema/enbas_cli_schema.json --path-to-enbas-executors ./executor/executors.go - const ( ApplicationName = "enbas" ApplicationWebsite = "https://codeflow.dananglin.me.uk/apollo/enbas"