checkpoint: moved custom flag values under new internal package

This commit is contained in:
Dan Anglin 2024-08-11 16:13:35 +01:00
parent fe52a991db
commit f5f835020a
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
12 changed files with 204 additions and 190 deletions

View file

@ -40,7 +40,7 @@ func generateExecutors(schema enbasCLISchema, output string) error {
"flagFieldName": flagFieldName, "flagFieldName": flagFieldName,
"getFlagType": schema.Flags.getType, "getFlagType": schema.Flags.getType,
"getFlagDescription": schema.Flags.getDescription, "getFlagDescription": schema.Flags.getDescription,
"customFlagValueType": customFlagValueType, "internalFlagValue": internalFlagValue,
} }
tmpl := template.Must(template.New("executor-template").Funcs(funcMap).Parse(executorsFileTemplate)) tmpl := template.Must(template.New("executor-template").Funcs(funcMap).Parse(executorsFileTemplate))
@ -109,15 +109,15 @@ func convertFlagToMixedCaps(value string) string {
return builder.String() return builder.String()
} }
func customFlagValueType(flagType string) bool { func internalFlagValue(flagType string) bool {
customFlagValueTypes := map[string]struct{}{ internalFlagValues := map[string]struct{}{
"MultiStringFlagValue": {}, "StringSliceValue": {},
"MultiIntFlagValue": {}, "IntSliceValue": {},
"TimeDurationFlagValue": {}, "TimeDurationValue": {},
"BoolPtrFlagValue": {}, "BoolPtrValue": {},
} }
_, exists := customFlagValueTypes[flagType] _, exists := internalFlagValues[flagType]
return exists return exists
} }

View file

@ -1,11 +1,14 @@
package main package main
var executorsFileTemplate = `package executor var executorsFileTemplate = `/*
{{ print "" }}
/*
This file is generated by ./cmd/enbas-cli-generators This file is generated by ./cmd/enbas-cli-generators
DO NOT EDIT. DO NOT EDIT.
*/ */
{{ print "" }}
package executor
{{ print "" }}
{{ print "" }}
import internalFlag "codeflow.dananglin.me.uk/apollo/enbas/internal/flag"
{{ 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" -}}
@ -20,8 +23,14 @@ type {{ $struct_name }} struct {
config *config.Config config *config.Config
{{- end }} {{- end }}
{{- range $flag := $command.Flags -}} {{- range $flag := $command.Flags -}}
{{- $flag_type := getFlagType $flag.Flag -}}
{{- if internalFlagValue $flag_type -}}
{{ print "" }} {{ print "" }}
{{ flagFieldName $flag }} {{ getFlagType $flag.Flag }} {{ flagFieldName $flag }} internalFlag.{{ $flag_type }}
{{- else -}}
{{ print "" }}
{{ flagFieldName $flag }} {{ $flag_type }}
{{- end -}}
{{- end -}} {{- end -}}
{{- range $field := $command.AdditionalFields -}} {{- range $field := $command.AdditionalFields -}}
{{ print "" }} {{ print "" }}
@ -53,9 +62,9 @@ func {{ $new_executor_function_name }}(
{{- end }} {{- end }}
{{- range $flag := $command.Flags -}} {{- range $flag := $command.Flags -}}
{{- $flag_type := getFlagType $flag.Flag -}} {{- $flag_type := getFlagType $flag.Flag -}}
{{- if customFlagValueType $flag_type -}} {{- if internalFlagValue $flag_type -}}
{{ print "" }} {{ print "" }}
{{ flagFieldName $flag }}: New{{ $flag_type }}(), {{ flagFieldName $flag }}: internalFlag.New{{ $flag_type }}(),
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- range $field := $command.AdditionalFields -}} {{- range $field := $command.AdditionalFields -}}
@ -78,7 +87,7 @@ func {{ $new_executor_function_name }}(
{{- else if eq $flag_type "int" -}} {{- else if eq $flag_type "int" -}}
{{ print "" }} {{ print "" }}
exe.IntVar(&exe.{{ flagFieldName $flag }}, {{ printf "%q" $flag.Flag }}, {{ $flag.Default }}, {{ getFlagDescription $flag.Flag | printf "%q" }}) exe.IntVar(&exe.{{ flagFieldName $flag }}, {{ printf "%q" $flag.Flag }}, {{ $flag.Default }}, {{ getFlagDescription $flag.Flag | printf "%q" }})
{{- else if customFlagValueType $flag_type -}} {{- else if internalFlagValue $flag_type -}}
{{ print "" }} {{ print "" }}
exe.Var(&exe.{{ flagFieldName $flag }}, {{ printf "%q" $flag.Flag }}, {{ getFlagDescription $flag.Flag | printf "%q" }}) exe.Var(&exe.{{ flagFieldName $flag }}, {{ printf "%q" $flag.Flag }}, {{ getFlagDescription $flag.Flag | printf "%q" }})
{{- end -}} {{- end -}}

View file

@ -2,12 +2,11 @@ package main
import ( import (
"flag" "flag"
"fmt"
"os" "os"
"strconv"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config" "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"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
) )
@ -27,21 +26,11 @@ func main() {
func run() error { func run() error {
var ( var (
configDir string configDir string
noColor *bool noColorFlag internalFlag.BoolPtrValue
) )
flag.StringVar(&configDir, "config-dir", "", "Specify your config directory") flag.StringVar(&configDir, "config-dir", "", "Specify your config directory")
flag.BoolFunc("no-color", "Disable ANSI colour output when displaying text on screen", func(value string) error { flag.Var(&noColorFlag, "no-color", "Disable ANSI colour output when displaying text on screen")
boolVal, err := strconv.ParseBool(value)
if err != nil {
return fmt.Errorf("unable to parse %q as a boolean: %w", value, err)
}
noColor = new(bool)
*noColor = boolVal
return nil
})
flag.Usage = usageFunc(executor.CommandSummaryMap()) flag.Usage = usageFunc(executor.CommandSummaryMap())
@ -53,15 +42,12 @@ func run() error {
return nil return nil
} }
// If NoColor is still unspecified, var noColor bool
// check to see if the NO_COLOR environment variable is set
if noColor == nil { if noColorFlag.Value != nil {
noColor = new(bool) noColor = *noColorFlag.Value
if os.Getenv("NO_COLOR") != "" { } else if os.Getenv("NO_COLOR") != "" {
*noColor = true noColor = true
} else {
*noColor = false
}
} }
command := flag.Arg(0) command := flag.Arg(0)
@ -75,17 +61,21 @@ func run() error {
switch command { switch command {
case executor.CommandInit, executor.CommandVersion: case executor.CommandInit, executor.CommandVersion:
enbasPrinter = printer.NewPrinter(*noColor, "", 0) enbasPrinter = printer.NewPrinter(noColor, "", 0)
default: default:
enbasConfig, err = config.NewConfigFromFile(configDir) enbasConfig, err = config.NewConfigFromFile(configDir)
if err != nil { if err != nil {
enbasPrinter = printer.NewPrinter(*noColor, "", 0) enbasPrinter = printer.NewPrinter(noColor, "", 0)
enbasPrinter.PrintFailure("unable to load the configuration: " + err.Error() + ".") enbasPrinter.PrintFailure("unable to load the configuration: " + err.Error() + ".")
return err return err
} }
enbasPrinter = printer.NewPrinter(*noColor, enbasConfig.Integrations.Pager, enbasConfig.LineWrapMaxWidth) enbasPrinter = printer.NewPrinter(
noColor,
enbasConfig.Integrations.Pager,
enbasConfig.LineWrapMaxWidth,
)
} }
executorMap := map[string]executor.Executor{ executorMap := map[string]executor.Executor{

View file

@ -7,6 +7,7 @@ import (
"codeflow.dananglin.me.uk/apollo/enbas/internal/client" "codeflow.dananglin.me.uk/apollo/enbas/internal/client"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/config"
internalFlag "codeflow.dananglin.me.uk/apollo/enbas/internal/flag"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
) )
@ -20,20 +21,18 @@ type AddExecutor struct {
listID string listID string
statusID string statusID string
pollID string pollID string
choices MultiIntFlagValue choices internalFlag.IntSliceValue
accountNames MultiStringFlagValue accountNames internalFlag.StringSliceValue
content string content string
} }
func NewAddExecutor(printer *printer.Printer, config *config.Config, name, summary string) *AddExecutor { func NewAddExecutor(printer *printer.Printer, config *config.Config, name, summary string) *AddExecutor {
emptyArr := make([]string, 0, 3)
addExe := AddExecutor{ addExe := AddExecutor{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError), FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
printer: printer, printer: printer,
config: config, config: config,
accountNames: MultiStringFlagValue(emptyArr), accountNames: internalFlag.NewStringSliceValue(),
} }
addExe.StringVar(&addExe.resourceType, flagType, "", "Specify the resource type to add (e.g. account, note)") addExe.StringVar(&addExe.resourceType, flagType, "", "Specify the resource type to add (e.g. account, note)")

View file

@ -1,17 +1,18 @@
/*
This file is generated by ./cmd/enbas-cli-generators
DO NOT EDIT.
*/
package executor package executor
import ( import (
"flag" "flag"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/config"
internalFlag "codeflow.dananglin.me.uk/apollo/enbas/internal/flag"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
) )
/*
This file is generated by ./cmd/enbas-cli-generators
DO NOT EDIT.
*/
// 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
@ -84,10 +85,10 @@ type CreateExecutor struct {
listRepliesPolicy string listRepliesPolicy string
listTitle string listTitle string
pollAllowsMultipleChoices bool pollAllowsMultipleChoices bool
pollExpiresIn TimeDurationFlagValue pollExpiresIn internalFlag.TimeDurationValue
pollHidesVoteCounts bool pollHidesVoteCounts bool
pollOptions MultiStringFlagValue pollOptions internalFlag.StringSliceValue
sensitive BoolPtrFlagValue sensitive internalFlag.BoolPtrValue
spoilerText string spoilerText string
resourceType string resourceType string
visibility string visibility string
@ -101,9 +102,9 @@ func NewCreateExecutor(
FlagSet: flag.NewFlagSet("create", flag.ExitOnError), FlagSet: flag.NewFlagSet("create", flag.ExitOnError),
printer: printer, printer: printer,
config: config, config: config,
pollExpiresIn: NewTimeDurationFlagValue(), pollExpiresIn: internalFlag.NewTimeDurationValue(),
pollOptions: NewMultiStringFlagValue(), pollOptions: internalFlag.NewStringSliceValue(),
sensitive: NewBoolPtrFlagValue(), sensitive: internalFlag.NewBoolPtrValue(),
} }
exe.Usage = commandUsageFunc("create", "Creates a specific resource", exe.FlagSet) exe.Usage = commandUsageFunc("create", "Creates a specific resource", exe.FlagSet)
@ -274,7 +275,7 @@ type MuteExecutor struct {
printer *printer.Printer printer *printer.Printer
config *config.Config config *config.Config
accountName string accountName string
muteDuration TimeDurationFlagValue muteDuration internalFlag.TimeDurationValue
muteNotifications bool muteNotifications bool
resourceType string resourceType string
} }
@ -287,7 +288,7 @@ func NewMuteExecutor(
FlagSet: flag.NewFlagSet("mute", flag.ExitOnError), FlagSet: flag.NewFlagSet("mute", flag.ExitOnError),
printer: printer, printer: printer,
config: config, config: config,
muteDuration: NewTimeDurationFlagValue(), muteDuration: internalFlag.NewTimeDurationValue(),
} }
exe.Usage = commandUsageFunc("mute", "Mutes a specific resource (e.g. an account)", exe.FlagSet) exe.Usage = commandUsageFunc("mute", "Mutes a specific resource (e.g. an account)", exe.FlagSet)
@ -335,7 +336,7 @@ type ShowExecutor struct {
accountName string accountName string
getAllImages bool getAllImages bool
getAllVideos bool getAllVideos bool
attachmentIDs MultiStringFlagValue attachmentIDs internalFlag.StringSliceValue
showInBrowser bool showInBrowser bool
excludeBoosts bool excludeBoosts bool
excludeReplies bool excludeReplies bool
@ -364,7 +365,7 @@ func NewShowExecutor(
FlagSet: flag.NewFlagSet("show", flag.ExitOnError), FlagSet: flag.NewFlagSet("show", flag.ExitOnError),
printer: printer, printer: printer,
config: config, config: config,
attachmentIDs: NewMultiStringFlagValue(), attachmentIDs: internalFlag.NewStringSliceValue(),
} }
exe.Usage = commandUsageFunc("show", "Shows details about a specified resource", exe.FlagSet) exe.Usage = commandUsageFunc("show", "Shows details about a specified resource", exe.FlagSet)

View file

@ -1,12 +1,5 @@
package executor package executor
import (
"fmt"
"strconv"
"strings"
"time"
)
const ( const (
flagAccountName = "account-name" flagAccountName = "account-name"
flagAttachmentID = "attachment-id" flagAttachmentID = "attachment-id"
@ -24,111 +17,3 @@ const (
flagType = "type" flagType = "type"
flagVote = "vote" flagVote = "vote"
) )
type MultiStringFlagValue []string
func NewMultiStringFlagValue() MultiStringFlagValue {
arr := make([]string, 0, 3)
return MultiStringFlagValue(arr)
}
func (v MultiStringFlagValue) String() string {
return strings.Join(v, ", ")
}
func (v *MultiStringFlagValue) Set(value string) error {
if len(value) > 0 {
*v = append(*v, value)
}
return nil
}
type MultiIntFlagValue []int
func NewMultiIntFlagValue() MultiIntFlagValue {
arr := make([]int, 0, 3)
return MultiIntFlagValue(arr)
}
func (v MultiIntFlagValue) String() string {
value := "Choices: "
for ind, vote := range v {
if ind == len(v)-1 {
value += strconv.Itoa(vote)
} else {
value += strconv.Itoa(vote) + ", "
}
}
return value
}
func (v *MultiIntFlagValue) Set(text string) error {
value, err := strconv.Atoi(text)
if err != nil {
return fmt.Errorf("unable to parse the value to an integer: %w", err)
}
*v = append(*v, value)
return nil
}
type TimeDurationFlagValue struct {
Duration time.Duration
}
func NewTimeDurationFlagValue() TimeDurationFlagValue {
return TimeDurationFlagValue{
Duration: 0 * time.Second,
}
}
func (v TimeDurationFlagValue) String() string {
return "Time duration: " + v.Duration.String()
}
func (v *TimeDurationFlagValue) Set(text string) error {
duration, err := time.ParseDuration(text)
if err != nil {
return fmt.Errorf("unable to parse the value as time duration: %w", err)
}
v.Duration = duration
return nil
}
type BoolPtrFlagValue struct {
Value *bool
}
func NewBoolPtrFlagValue() BoolPtrFlagValue {
return BoolPtrFlagValue{
Value: nil,
}
}
func (b BoolPtrFlagValue) String() string {
if b.Value == nil {
return "NOT SET"
}
return strconv.FormatBool(*b.Value)
}
func (b *BoolPtrFlagValue) Set(value string) error {
boolVar, err := strconv.ParseBool(value)
if err != nil {
return fmt.Errorf("unable to parse %q as a boolean value: %w", value, err)
}
b.Value = new(bool)
*b.Value = boolVar
return nil
}

View file

@ -6,6 +6,7 @@ import (
"codeflow.dananglin.me.uk/apollo/enbas/internal/client" "codeflow.dananglin.me.uk/apollo/enbas/internal/client"
"codeflow.dananglin.me.uk/apollo/enbas/internal/config" "codeflow.dananglin.me.uk/apollo/enbas/internal/config"
internalFlag "codeflow.dananglin.me.uk/apollo/enbas/internal/flag"
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer" "codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
) )
@ -18,18 +19,16 @@ type RemoveExecutor struct {
fromResourceType string fromResourceType string
listID string listID string
statusID string statusID string
accountNames MultiStringFlagValue accountNames internalFlag.StringSliceValue
} }
func NewRemoveExecutor(printer *printer.Printer, config *config.Config, name, summary string) *RemoveExecutor { func NewRemoveExecutor(printer *printer.Printer, config *config.Config, name, summary string) *RemoveExecutor {
emptyArr := make([]string, 0, 3)
removeExe := RemoveExecutor{ removeExe := RemoveExecutor{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError), FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
printer: printer, printer: printer,
config: config, config: config,
accountNames: MultiStringFlagValue(emptyArr), accountNames: internalFlag.NewStringSliceValue(),
} }
removeExe.StringVar(&removeExe.resourceType, flagType, "", "Specify the resource type to remove (e.g. account, note)") removeExe.StringVar(&removeExe.resourceType, flagType, "", "Specify the resource type to remove (e.g. account, note)")

View file

@ -0,0 +1,36 @@
package flag
import (
"fmt"
"strconv"
)
type BoolPtrValue struct {
Value *bool
}
func NewBoolPtrValue() BoolPtrValue {
return BoolPtrValue{
Value: nil,
}
}
func (b BoolPtrValue) String() string {
if b.Value == nil {
return "NOT SET"
}
return strconv.FormatBool(*b.Value)
}
func (b *BoolPtrValue) Set(value string) error {
boolVar, err := strconv.ParseBool(value)
if err != nil {
return fmt.Errorf("unable to parse %q as a boolean value: %w", value, err)
}
b.Value = new(bool)
*b.Value = boolVar
return nil
}

41
internal/flag/intslice.go Normal file
View file

@ -0,0 +1,41 @@
package flag
import (
"fmt"
"strconv"
"strings"
)
type IntSliceValue []int
func NewIntSliceValue() IntSliceValue {
arr := make([]int, 0, 3)
return IntSliceValue(arr)
}
func (v IntSliceValue) String() string {
var builder strings.Builder
for ind, value := range v {
if ind == len(v)-1 {
builder.WriteString(strconv.Itoa(value))
} else {
builder.WriteString(strconv.Itoa(value))
builder.WriteString(", ")
}
}
return builder.String()
}
func (v *IntSliceValue) Set(text string) error {
value, err := strconv.Atoi(text)
if err != nil {
return fmt.Errorf("unable to parse the value to an integer: %w", err)
}
*v = append(*v, value)
return nil
}

View file

@ -0,0 +1,23 @@
package flag
import "strings"
type StringSliceValue []string
func NewStringSliceValue() StringSliceValue {
arr := make([]string, 0, 3)
return StringSliceValue(arr)
}
func (v StringSliceValue) String() string {
return strings.Join(v, ", ")
}
func (v *StringSliceValue) Set(value string) error {
if len(value) > 0 {
*v = append(*v, value)
}
return nil
}

View file

@ -0,0 +1,31 @@
package flag
import (
"fmt"
"time"
)
type TimeDurationValue struct {
Duration time.Duration
}
func NewTimeDurationValue() TimeDurationValue {
return TimeDurationValue{
Duration: 0 * time.Second,
}
}
func (v TimeDurationValue) String() string {
return v.Duration.String()
}
func (v *TimeDurationValue) Set(text string) error {
duration, err := time.ParseDuration(text)
if err != nil {
return fmt.Errorf("unable to parse the value as time duration: %w", err)
}
v.Duration = duration
return nil
}

View file

@ -13,7 +13,7 @@
"description": "Set to true to show all videos from a status" "description": "Set to true to show all videos from a status"
}, },
"attachment-id": { "attachment-id": {
"type": "MultiStringFlagValue", "type": "StringSliceValue",
"description": "The ID of the media attachment" "description": "The ID of the media attachment"
}, },
"add-poll": { "add-poll": {
@ -97,7 +97,7 @@
"description": "The replies policy of the list" "description": "The replies policy of the list"
}, },
"mute-duration": { "mute-duration": {
"type": "TimeDurationFlagValue", "type": "TimeDurationValue",
"description": "Specify how long the mute should last for. To mute indefinitely, set this to 0s" "description": "Specify how long the mute should last for. To mute indefinitely, set this to 0s"
}, },
"mute-notifications": { "mute-notifications": {
@ -129,7 +129,7 @@
"description": "Set to true to allow viewers to make multiple choices in the poll" "description": "Set to true to allow viewers to make multiple choices in the poll"
}, },
"poll-expires-in": { "poll-expires-in": {
"type": "TimeDurationFlagValue", "type": "TimeDurationValue",
"description": "The duration in which the poll is open for" "description": "The duration in which the poll is open for"
}, },
"poll-hides-vote-counts": { "poll-hides-vote-counts": {
@ -141,11 +141,11 @@
"description": "The ID of the poll" "description": "The ID of the poll"
}, },
"poll-option": { "poll-option": {
"type": "MultiStringFlagValue", "type": "StringSliceValue",
"description": "A poll option. Use this multiple times to set multiple options" "description": "A poll option. Use this multiple times to set multiple options"
}, },
"sensitive": { "sensitive": {
"type": "BoolPtrFlagValue", "type": "BoolPtrValue",
"description": "Set to true if the status should be marked as sensitive" "description": "Set to true if the status should be marked as sensitive"
}, },
"show-preferences": { "show-preferences": {