checkpoint: move build information to internal package

- move the build information to the internal package to simplify the
  version executor.
- add the Executor interface to internal/executor/executors.go
This commit is contained in:
Dan Anglin 2024-08-12 12:39:43 +01:00
parent 43de60f5c2
commit de740de211
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
12 changed files with 246 additions and 225 deletions

View file

@ -9,6 +9,13 @@ package executor
{{ print "" }} {{ print "" }}
{{ print "" }} {{ print "" }}
import internalFlag "codeflow.dananglin.me.uk/apollo/enbas/internal/flag" import internalFlag "codeflow.dananglin.me.uk/apollo/enbas/internal/flag"
{{ print "" }}
{{ print "" }}
type Executor interface {
Name() string
Parse(args []string) error
Execute() error
}
{{ range $name, $command := . }} {{ range $name, $command := . }}
{{- $struct_name := capitalise $name | printf "%sExecutor" -}} {{- $struct_name := capitalise $name | printf "%sExecutor" -}}
{{- $new_executor_function_name := capitalise $name | printf "New%sExecutor" -}} {{- $new_executor_function_name := capitalise $name | printf "New%sExecutor" -}}

View file

@ -4,17 +4,8 @@ import (
"flag" "flag"
"os" "os"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
"codeflow.dananglin.me.uk/apollo/enbas/internal/executor" "codeflow.dananglin.me.uk/apollo/enbas/internal/executor"
internalFlag "codeflow.dananglin.me.uk/apollo/enbas/internal/flag" internalFlag "codeflow.dananglin.me.uk/apollo/enbas/internal/flag"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
)
var (
binaryVersion string //nolint:gochecknoglobals
buildTime string //nolint:gochecknoglobals
goVersion string //nolint:gochecknoglobals
gitCommit string //nolint:gochecknoglobals
) )
func main() { func main() {
@ -53,128 +44,5 @@ func run() error {
command := flag.Arg(0) command := flag.Arg(0)
args := flag.Args()[1:] args := flag.Args()[1:]
var ( return executor.Execute(command, args, noColor, configDir)
enbasConfig *config.Config
enbasPrinter *printer.Printer
err error
)
switch command {
case executor.CommandInit, executor.CommandVersion:
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,
)
}
executorMap := map[string]executor.Executor{
executor.CommandAccept: executor.NewAcceptExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandAdd: executor.NewAddExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandBlock: executor.NewBlockExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandCreate: executor.NewCreateExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandDelete: executor.NewDeleteExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandEdit: executor.NewEditExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandFollow: executor.NewFollowExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandInit: executor.NewInitExecutor(
enbasPrinter,
configDir,
),
executor.CommandLogin: executor.NewLoginExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandMute: executor.NewMuteExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandReject: executor.NewRejectExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandRemove: executor.NewRemoveExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandSwitch: executor.NewSwitchExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandUnfollow: executor.NewUnfollowExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandUnmute: executor.NewUnmuteExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandUnblock: executor.NewUnblockExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandShow: executor.NewShowExecutor(
enbasPrinter,
enbasConfig,
),
executor.CommandVersion: executor.NewVersionExecutor(
enbasPrinter,
binaryVersion,
buildTime,
goVersion,
gitCommit,
),
executor.CommandWhoami: executor.NewWhoamiExecutor(
enbasPrinter,
enbasConfig,
),
}
exe, ok := executorMap[command]
if !ok {
err = executor.UnknownCommandError{Command: command}
enbasPrinter.PrintFailure(err.Error() + ".")
flag.Usage()
return err
}
if err = executor.Execute(exe, args); err != nil {
enbasPrinter.PrintFailure("(" + command + ") " + err.Error() + ".")
return err
}
return nil
} }

View file

@ -6,6 +6,8 @@ import (
"slices" "slices"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"codeflow.dananglin.me.uk/apollo/enbas/internal/version"
) )
func usageFunc(summaries map[string]string) func() { func usageFunc(summaries map[string]string) func() {
@ -24,8 +26,8 @@ func usageFunc(summaries map[string]string) func() {
builder.WriteString("SUMMARY:\n enbas - A GoToSocial client for the terminal.\n\n") builder.WriteString("SUMMARY:\n enbas - A GoToSocial client for the terminal.\n\n")
if binaryVersion != "" { if version.BinaryVersion != "" {
builder.WriteString("VERSION:\n " + binaryVersion + "\n\n") builder.WriteString("VERSION:\n " + version.BinaryVersion + "\n\n")
} }
builder.WriteString("USAGE:\n enbas [flags]\n enbas [flags] [command]\n\nCOMMANDS:") builder.WriteString("USAGE:\n enbas [flags]\n enbas [flags] [command]\n\nCOMMANDS:")

View file

@ -1,25 +1,25 @@
package executor package executor
const ( const (
CommandAccept string = "accept" commandAccept string = "accept"
CommandAdd string = "add" commandAdd string = "add"
CommandBlock string = "block" commandBlock string = "block"
CommandCreate string = "create" commandCreate string = "create"
CommandDelete string = "delete" commandDelete string = "delete"
CommandEdit string = "edit" commandEdit string = "edit"
CommandFollow string = "follow" commandFollow string = "follow"
CommandInit string = "init" commandInit string = "init"
CommandLogin string = "login" commandLogin string = "login"
CommandMute string = "mute" commandMute string = "mute"
CommandReject string = "reject" commandReject string = "reject"
CommandRemove string = "remove" commandRemove string = "remove"
CommandShow string = "show" commandShow string = "show"
CommandSwitch string = "switch" commandSwitch string = "switch"
CommandUnblock string = "unblock" commandUnblock string = "unblock"
CommandUnfollow string = "unfollow" commandUnfollow string = "unfollow"
CommandUnmute string = "unmute" commandUnmute string = "unmute"
CommandVersion string = "version" commandVersion string = "version"
CommandWhoami string = "whoami" commandWhoami string = "whoami"
commandAcceptSummary string = "Accept a request (e.g. a follow request)" commandAcceptSummary string = "Accept a request (e.g. a follow request)"
commandAddSummary string = "Add a resource to another resource" commandAddSummary string = "Add a resource to another resource"
@ -44,25 +44,25 @@ const (
func CommandSummaryMap() map[string]string { func CommandSummaryMap() map[string]string {
return map[string]string{ return map[string]string{
CommandAccept: commandAcceptSummary, commandAccept: commandAcceptSummary,
CommandAdd: commandAddSummary, commandAdd: commandAddSummary,
CommandBlock: commandBlockSummary, commandBlock: commandBlockSummary,
CommandCreate: commandCreateSummary, commandCreate: commandCreateSummary,
CommandDelete: commandDeleteSummary, commandDelete: commandDeleteSummary,
CommandEdit: commandEditSummary, commandEdit: commandEditSummary,
CommandFollow: commandFollowSummary, commandFollow: commandFollowSummary,
CommandInit: commandInitSummary, commandInit: commandInitSummary,
CommandLogin: commandLoginSummary, commandLogin: commandLoginSummary,
CommandMute: commandMuteSummary, commandMute: commandMuteSummary,
CommandReject: commandRejectSummary, commandReject: commandRejectSummary,
CommandRemove: commandRemoveSummary, commandRemove: commandRemoveSummary,
CommandShow: commandShowSummary, commandShow: commandShowSummary,
CommandSwitch: commandSwitchSummary, commandSwitch: commandSwitchSummary,
CommandUnblock: commandUnblockSummary, commandUnblock: commandUnblockSummary,
CommandUnfollow: commandUnfollowSummary, commandUnfollow: commandUnfollowSummary,
CommandUnmute: commandUnmuteSummary, commandUnmute: commandUnmuteSummary,
CommandVersion: commandVersionSummary, commandVersion: commandVersionSummary,
CommandWhoami: commandWhoamiSummary, commandWhoami: commandWhoamiSummary,
} }
} }

View file

@ -0,0 +1,155 @@
package executor
import (
"fmt"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
)
func Execute(
command string,
args []string,
noColor bool,
configDir string,
) error {
var (
enbasConfig *config.Config
enbasPrinter *printer.Printer
err error
)
switch command {
case commandInit, commandVersion:
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
}
func execute(
command string,
args []string,
enbasPrinter *printer.Printer,
enbasConfig *config.Config,
configDir string,
) error {
executorMap := map[string]Executor{
commandAccept: NewAcceptExecutor(
enbasPrinter,
enbasConfig,
),
commandAdd: NewAddExecutor(
enbasPrinter,
enbasConfig,
),
commandBlock: NewBlockExecutor(
enbasPrinter,
enbasConfig,
),
commandCreate: NewCreateExecutor(
enbasPrinter,
enbasConfig,
),
commandDelete: NewDeleteExecutor(
enbasPrinter,
enbasConfig,
),
commandEdit: NewEditExecutor(
enbasPrinter,
enbasConfig,
),
commandFollow: NewFollowExecutor(
enbasPrinter,
enbasConfig,
),
commandInit: NewInitExecutor(
enbasPrinter,
configDir,
),
commandLogin: NewLoginExecutor(
enbasPrinter,
enbasConfig,
),
commandMute: NewMuteExecutor(
enbasPrinter,
enbasConfig,
),
commandReject: NewRejectExecutor(
enbasPrinter,
enbasConfig,
),
commandRemove: NewRemoveExecutor(
enbasPrinter,
enbasConfig,
),
commandSwitch: NewSwitchExecutor(
enbasPrinter,
enbasConfig,
),
commandUnfollow: NewUnfollowExecutor(
enbasPrinter,
enbasConfig,
),
commandUnmute: NewUnmuteExecutor(
enbasPrinter,
enbasConfig,
),
commandUnblock: NewUnblockExecutor(
enbasPrinter,
enbasConfig,
),
commandShow: NewShowExecutor(
enbasPrinter,
enbasConfig,
),
commandVersion: NewVersionExecutor(
enbasPrinter,
),
commandWhoami: NewWhoamiExecutor(
enbasPrinter,
enbasConfig,
),
}
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,21 +0,0 @@
package executor
import "fmt"
type Executor interface {
Name() string
Parse(args []string) error
Execute() error
}
func Execute(executor Executor, args []string) error {
if err := executor.Parse(args); err != nil {
return fmt.Errorf("flag parsing error: %w", err)
}
if err := executor.Execute(); err != nil {
return fmt.Errorf("execution error: %w", err)
}
return nil
}

View file

@ -13,6 +13,12 @@ import (
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
) )
type Executor interface {
Name() string
Parse(args []string) error
Execute() error
}
// AcceptExecutor is the executor for the accept command. // AcceptExecutor is the executor for the accept command.
type AcceptExecutor struct { type AcceptExecutor struct {
*flag.FlagSet *flag.FlagSet
@ -592,28 +598,16 @@ func NewUnmuteExecutor(
// VersionExecutor is the executor for the version command. // VersionExecutor is the executor for the version command.
type VersionExecutor struct { type VersionExecutor struct {
*flag.FlagSet *flag.FlagSet
printer *printer.Printer printer *printer.Printer
full bool full bool
binaryVersion string
buildTime string
goVersion string
gitCommit string
} }
func NewVersionExecutor( func NewVersionExecutor(
printer *printer.Printer, printer *printer.Printer,
binaryVersion string,
buildTime string,
goVersion string,
gitCommit string,
) *VersionExecutor { ) *VersionExecutor {
exe := VersionExecutor{ exe := VersionExecutor{
FlagSet: flag.NewFlagSet("version", flag.ExitOnError), FlagSet: flag.NewFlagSet("version", flag.ExitOnError),
printer: printer, printer: printer,
binaryVersion: binaryVersion,
buildTime: buildTime,
goVersion: goVersion,
gitCommit: gitCommit,
} }
exe.Usage = commandUsageFunc("version", "Prints the application's version and build information", exe.FlagSet) exe.Usage = commandUsageFunc("version", "Prints the application's version and build information", exe.FlagSet)

View file

@ -1,7 +1,7 @@
package executor package executor
func (v *VersionExecutor) Execute() error { func (v *VersionExecutor) Execute() error {
v.printer.PrintVersion(v.full, v.binaryVersion, v.buildTime, v.goVersion, v.gitCommit) v.printer.PrintVersion(v.full)
return nil return nil
} }

View file

@ -3,11 +3,13 @@ package printer
import ( import (
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"codeflow.dananglin.me.uk/apollo/enbas/internal/version"
) )
func (p Printer) PrintVersion(showFullVersion bool, binaryVersion, buildTime, goVersion, gitCommit string) { func (p Printer) PrintVersion(showFullVersion bool) {
if !showFullVersion { if !showFullVersion {
printToStdout("Enbas " + binaryVersion + "\n") printToStdout("Enbas " + version.BinaryVersion + "\n")
return return
} }
@ -18,10 +20,10 @@ func (p Printer) PrintVersion(showFullVersion bool, binaryVersion, buildTime, go
tableWriter := tabwriter.NewWriter(&builder, 0, 4, 1, ' ', 0) tableWriter := tabwriter.NewWriter(&builder, 0, 4, 1, ' ', 0)
_, _ = tableWriter.Write([]byte(p.fieldFormat("Version:") + "\t" + binaryVersion + "\n")) _, _ = tableWriter.Write([]byte(p.fieldFormat("Version:") + "\t" + version.BinaryVersion + "\n"))
_, _ = tableWriter.Write([]byte(p.fieldFormat("Git commit:") + "\t" + gitCommit + "\n")) _, _ = tableWriter.Write([]byte(p.fieldFormat("Git commit:") + "\t" + version.GitCommit + "\n"))
_, _ = tableWriter.Write([]byte(p.fieldFormat("Go version:") + "\t" + goVersion + "\n")) _, _ = tableWriter.Write([]byte(p.fieldFormat("Go version:") + "\t" + version.GoVersion + "\n"))
_, _ = tableWriter.Write([]byte(p.fieldFormat("Build date:") + "\t" + buildTime + "\n")) _, _ = tableWriter.Write([]byte(p.fieldFormat("Build date:") + "\t" + version.BuildTime + "\n"))
tableWriter.Flush() tableWriter.Flush()

View file

@ -0,0 +1,8 @@
package version
var (
BinaryVersion string //nolint:gochecknoglobals
BuildTime string //nolint:gochecknoglobals
GoVersion string //nolint:gochecknoglobals
GitCommit string //nolint:gochecknoglobals
)

View file

@ -110,10 +110,21 @@ func Clean() error {
// ldflags returns the build flags. // ldflags returns the build flags.
func ldflags() string { func ldflags() string {
ldflagsfmt := "-s -w -X main.binaryVersion=%s -X main.gitCommit=%s -X main.goVersion=%s -X main.buildTime=%s" versionPackage := "codeflow.dananglin.me.uk/apollo/enbas/internal/version"
binaryVersionVar := versionPackage + "." + "BinaryVersion"
gitCommitVar := versionPackage + "." + "GitCommit"
goVersionVar := versionPackage + "." + "GoVersion"
buildTimeVar := versionPackage + "." + "BuildTime"
ldflagsfmt := "-s -w -X %s=%s -X %s=%s -X %s=%s -X %s=%s"
buildTime := time.Now().UTC().Format(time.RFC3339) buildTime := time.Now().UTC().Format(time.RFC3339)
return fmt.Sprintf(ldflagsfmt, version(), gitCommit(), runtime.Version(), buildTime) return fmt.Sprintf(
ldflagsfmt,
binaryVersionVar, version(),
gitCommitVar, gitCommit(),
goVersionVar, runtime.Version(),
buildTimeVar, buildTime,
)
} }
// version returns the latest git tag using git describe. // version returns the latest git tag using git describe.

View file

@ -421,12 +421,7 @@
"usePrinter": true "usePrinter": true
}, },
"version": { "version": {
"additionalFields": [ "additionalFields": [],
{ "name": "binaryVersion", "type": "string"},
{ "name": "buildTime", "type": "string"},
{ "name": "goVersion", "type": "string"},
{ "name": "gitCommit", "type": "string"}
],
"flags": [ "flags": [
{ "flag": "full", "default": "false" } { "flag": "full", "default": "false" }
], ],