checkpoint: generate code for internal/executor/execute.go

This commit is contained in:
Dan Anglin 2024-08-12 16:01:50 +01:00
parent de740de211
commit bb815b05ce
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
6 changed files with 185 additions and 45 deletions

View file

@ -1,6 +1,7 @@
package main package main
import ( import (
"embed"
"flag" "flag"
"fmt" "fmt"
"os" "os"
@ -11,13 +12,9 @@ import (
) )
func main() { func main() {
var ( var enbasCLISchemaFilepath string
enbasCLISchemaFilepath string
executorsFilePath string
)
flag.StringVar(&enbasCLISchemaFilepath, "path-to-enbas-cli-schema", "", "The path to the Enbas CLI schema file") 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() flag.Parse()
schema, err := newEnbasCLISchemaFromFile(enbasCLISchemaFilepath) schema, err := newEnbasCLISchemaFromFile(enbasCLISchemaFilepath)
@ -25,16 +22,20 @@ func main() {
fmt.Printf("ERROR: Unable to read the schema file: %v.\n", err) 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) 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{ funcMap := template.FuncMap{
"capitalise": capitalise, "capitalise": capitalise,
"flagFieldName": flagFieldName, "flagFieldName": flagFieldName,
@ -43,16 +44,39 @@ func generateExecutors(schema enbasCLISchema, output string) error {
"internalFlagValue": internalFlagValue, "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 !strings.HasSuffix(templateFilename, ".go.gotmpl") {
if err != nil { continue
return fmt.Errorf("unable to create the output file: %w", err) }
}
defer file.Close()
if err := tmpl.Execute(file, schema.Commands); err != nil { if err := func() error {
return fmt.Errorf("unable to generate the code from the template: %w", err) 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 return nil

View file

@ -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
}

View file

@ -1,6 +1,8 @@
package main {{- /* vim: set noexpandtab : */ -}}
{{- /* vim: set tabstop=8 : */ -}}
var executorsFileTemplate = `/* {{- /* vim: set shiftwidth=8 : */ -}}
{{- /* vim: set softtabstop=8 : */ -}}
/*
This file is generated by the enbas-codegen This file is generated by the enbas-codegen
DO NOT EDIT. DO NOT EDIT.
*/ */
@ -104,4 +106,3 @@ func {{ $new_executor_function_name }}(
return &exe return &exe
} }
{{ end }} {{ end }}
`

View file

@ -0,0 +1,3 @@
package executor
//go:generate go run ../../cmd/enbas-codegen --path-to-enbas-cli-schema ../../schema/enbas_cli_schema.json

View file

@ -1,3 +1,8 @@
/*
This file is generated by the enbas-codegen
DO NOT EDIT.
*/
package executor package executor
import ( import (
@ -20,7 +25,7 @@ func Execute(
) )
switch command { switch command {
case commandInit, commandVersion: case "init", "version":
enbasPrinter = printer.NewPrinter(noColor, "", 0) enbasPrinter = printer.NewPrinter(noColor, "", 0)
default: default:
enbasConfig, err = config.NewConfigFromFile(configDir) enbasConfig, err = config.NewConfigFromFile(configDir)
@ -61,78 +66,78 @@ func execute(
configDir string, configDir string,
) error { ) error {
executorMap := map[string]Executor{ executorMap := map[string]Executor{
commandAccept: NewAcceptExecutor( "accept": NewAcceptExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandAdd: NewAddExecutor( "add": NewAddExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandBlock: NewBlockExecutor( "block": NewBlockExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandCreate: NewCreateExecutor( "create": NewCreateExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandDelete: NewDeleteExecutor( "delete": NewDeleteExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandEdit: NewEditExecutor( "edit": NewEditExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandFollow: NewFollowExecutor( "follow": NewFollowExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandInit: NewInitExecutor( "init": NewInitExecutor(
enbasPrinter, enbasPrinter,
configDir, configDir,
), ),
commandLogin: NewLoginExecutor( "login": NewLoginExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandMute: NewMuteExecutor( "mute": NewMuteExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandReject: NewRejectExecutor( "reject": NewRejectExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandRemove: NewRemoveExecutor( "remove": NewRemoveExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandSwitch: NewSwitchExecutor( "show": NewShowExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandUnfollow: NewUnfollowExecutor( "switch": NewSwitchExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandUnmute: NewUnmuteExecutor( "unblock": NewUnblockExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandUnblock: NewUnblockExecutor( "unfollow": NewUnfollowExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandShow: NewShowExecutor( "unmute": NewUnmuteExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),
commandVersion: NewVersionExecutor( "version": NewVersionExecutor(
enbasPrinter, enbasPrinter,
), ),
commandWhoami: NewWhoamiExecutor( "whoami": NewWhoamiExecutor(
enbasPrinter, enbasPrinter,
enbasConfig, enbasConfig,
), ),

View file

@ -1,7 +1,5 @@
package internal 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 ( const (
ApplicationName = "enbas" ApplicationName = "enbas"
ApplicationWebsite = "https://codeflow.dananglin.me.uk/apollo/enbas" ApplicationWebsite = "https://codeflow.dananglin.me.uk/apollo/enbas"