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

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

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
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,
),

View file

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