fix: update FlagSet code

- Added constants for flag names and resource types
- Added an error type for when a required flag is not set
- Added an error type for when an unsupported resource type is specified
- Renamed timeline-type to timeline-category
This commit is contained in:
Dan Anglin 2024-02-28 19:35:18 +00:00
parent c507815ef6
commit 4f694465bf
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
8 changed files with 134 additions and 87 deletions

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
@ -22,9 +21,9 @@ func newCreateCommand(name, summary string) *createCommand {
FlagSet: flag.NewFlagSet(name, flag.ExitOnError), FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
} }
command.StringVar(&command.resourceType, "type", "", "specify the type of resource to create") command.StringVar(&command.resourceType, resourceTypeFlag, "", "specify the type of resource to create")
command.StringVar(&command.listTitle, "list-title", "", "specify the title of the list") command.StringVar(&command.listTitle, listTitleFlag, "", "specify the title of the list")
command.StringVar(&command.listRepliesPolicy, "list-replies-policy", "list", "specify the policy of the replies for this list (valid values are followed, list and none)") command.StringVar(&command.listRepliesPolicy, listRepliesPolicyFlag, "list", "specify the policy of the replies for this list (valid values are followed, list and none)")
command.Usage = commandUsageFunc(name, summary, command.FlagSet) command.Usage = commandUsageFunc(name, summary, command.FlagSet)
@ -33,7 +32,7 @@ func newCreateCommand(name, summary string) *createCommand {
func (c *createCommand) Execute() error { func (c *createCommand) Execute() error {
if c.resourceType == "" { if c.resourceType == "" {
return errors.New("the type field is not set") return flagNotSetError{flagText: resourceTypeFlag}
} }
gtsClient, err := client.NewClientFromConfig() gtsClient, err := client.NewClientFromConfig()
@ -42,20 +41,20 @@ func (c *createCommand) Execute() error {
} }
funcMap := map[string]func(*client.Client) error{ funcMap := map[string]func(*client.Client) error{
"lists": c.createLists, listResource: c.createList,
} }
doFunc, ok := funcMap[c.resourceType] doFunc, ok := funcMap[c.resourceType]
if !ok { if !ok {
return fmt.Errorf("unsupported type %q", c.resourceType) return unsupportedResourceTypeError{resourceType: c.resourceType}
} }
return doFunc(gtsClient) return doFunc(gtsClient)
} }
func (c *createCommand) createLists(gtsClient *client.Client) error { func (c *createCommand) createList(gtsClient *client.Client) error {
if c.listTitle == "" { if c.listTitle == "" {
return errors.New("the list-title flag is not set") return flagNotSetError{flagText: listTitleFlag}
} }
repliesPolicy, err := model.ParseListRepliesPolicy(c.listRepliesPolicy) repliesPolicy, err := model.ParseListRepliesPolicy(c.listRepliesPolicy)

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
@ -20,8 +19,8 @@ func newDeleteCommand(name, summary string) *deleteCommand {
FlagSet: flag.NewFlagSet(name, flag.ExitOnError), FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
} }
command.StringVar(&command.resourceType, "type", "", "specify the type of resource to delete") command.StringVar(&command.resourceType, resourceTypeFlag, "", "specify the type of resource to delete")
command.StringVar(&command.listID, "list-id", "", "specify the ID of the list to delete") command.StringVar(&command.listID, listIDFlag, "", "specify the ID of the list to delete")
command.Usage = commandUsageFunc(name, summary, command.FlagSet) command.Usage = commandUsageFunc(name, summary, command.FlagSet)
@ -30,7 +29,16 @@ func newDeleteCommand(name, summary string) *deleteCommand {
func (c *deleteCommand) Execute() error { func (c *deleteCommand) Execute() error {
if c.resourceType == "" { if c.resourceType == "" {
return errors.New("the type field is not set") return flagNotSetError{flagText: resourceTypeFlag}
}
funcMap := map[string]func(*client.Client) error{
listResource: c.deleteList,
}
doFunc, ok := funcMap[c.resourceType]
if !ok {
return unsupportedResourceTypeError{resourceType: c.resourceType}
} }
gtsClient, err := client.NewClientFromConfig() gtsClient, err := client.NewClientFromConfig()
@ -38,21 +46,12 @@ func (c *deleteCommand) Execute() error {
return fmt.Errorf("unable to create the GoToSocial client; %w", err) return fmt.Errorf("unable to create the GoToSocial client; %w", err)
} }
funcMap := map[string]func(*client.Client) error{
"lists": c.deleteList,
}
doFunc, ok := funcMap[c.resourceType]
if !ok {
return fmt.Errorf("unsupported resource type %q", c.resourceType)
}
return doFunc(gtsClient) return doFunc(gtsClient)
} }
func (c *deleteCommand) deleteList(gtsClient *client.Client) error { func (c *deleteCommand) deleteList(gtsClient *client.Client) error {
if c.listID == "" { if c.listID == "" {
return errors.New("the list-id flag is not set") return flagNotSetError{flagText: listIDFlag}
} }
if err := gtsClient.DeleteList(c.listID); err != nil { if err := gtsClient.DeleteList(c.listID); err != nil {

25
cmd/enbas/errors.go Normal file
View file

@ -0,0 +1,25 @@
package main
type flagNotSetError struct {
flagText string
}
func (e flagNotSetError) Error() string {
return "the flag '" + e.flagText + "' is not set"
}
type unsupportedResourceTypeError struct {
resourceType string
}
func (e unsupportedResourceTypeError) Error() string {
return "unsupported resource type '" + e.resourceType + "'"
}
type invalidTimelineCategoryError struct {
category string
}
func (e invalidTimelineCategoryError) Error() string {
return "'" + e.category + "' is not a valid timeline category (please choose home, public, tag or list)"
}

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
"strings" "strings"
@ -16,15 +15,13 @@ type loginCommand struct {
instance string instance string
} }
var errInstanceNotSet = errors.New("the instance flag is not set")
func newLoginCommand(name, summary string) *loginCommand { func newLoginCommand(name, summary string) *loginCommand {
command := loginCommand{ command := loginCommand{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError), FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
instance: "", instance: "",
} }
command.StringVar(&command.instance, "instance", "", "specify the instance that you want to login to.") command.StringVar(&command.instance, instanceFlag, "", "specify the instance that you want to login to.")
command.Usage = commandUsageFunc(name, summary, command.FlagSet) command.Usage = commandUsageFunc(name, summary, command.FlagSet)
@ -35,7 +32,7 @@ func (c *loginCommand) Execute() error {
var err error var err error
if c.instance == "" { if c.instance == "" {
return errInstanceNotSet return flagNotSetError{flagText: instanceFlag}
} }
instance := c.instance instance := c.instance

View file

@ -6,6 +6,29 @@ import (
"os" "os"
) )
const (
accountFlag = "account"
instanceFlag = "instance"
listIDFlag = "list-id"
listTitleFlag = "list-title"
listRepliesPolicyFlag = "list-replies-policy"
myAccountFlag = "my-account"
resourceTypeFlag = "type"
statusIDFlag = "status-id"
tagFlag = "tag"
timelineCategoryFlag = "timeline-category"
timelineLimitFlag = "timeline-limit"
toAccountFlag = "to-account"
)
const (
accountResource = "account"
instanceResource = "instance"
listResource = "list"
statusResource = "status"
timelineResource = "timeline"
)
type Executor interface { type Executor interface {
Name() string Name() string
Parse(args []string) error Parse(args []string) error

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
@ -13,14 +12,14 @@ import (
type showCommand struct { type showCommand struct {
*flag.FlagSet *flag.FlagSet
myAccount bool myAccount bool
resourceType string resourceType string
account string account string
statusID string statusID string
timelineType string timelineCategory string
timelineListID string listID string
timelineTagName string tag string
timelineLimit int timelineLimit int
} }
func newShowCommand(name, summary string) *showCommand { func newShowCommand(name, summary string) *showCommand {
@ -28,14 +27,15 @@ func newShowCommand(name, summary string) *showCommand {
FlagSet: flag.NewFlagSet(name, flag.ExitOnError), FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
} }
command.BoolVar(&command.myAccount, "my-account", false, "set to true to lookup your account") command.BoolVar(&command.myAccount, myAccountFlag, false, "set to true to lookup your account")
command.StringVar(&command.resourceType, "type", "", "specify the type of resource to display") command.StringVar(&command.resourceType, resourceTypeFlag, "", "specify the type of resource to display")
command.StringVar(&command.account, "account", "", "specify the account URI to lookup") command.StringVar(&command.account, accountFlag, "", "specify the account URI to lookup")
command.StringVar(&command.statusID, "status-id", "", "specify the ID of the status to display") command.StringVar(&command.statusID, statusIDFlag, "", "specify the ID of the status to display")
command.StringVar(&command.timelineType, "timeline-type", "home", "specify the type of timeline to display (valid values are home, public, list and tag)") command.StringVar(&command.timelineCategory, timelineCategoryFlag, "home", "specify the type of timeline to display (valid values are home, public, list and tag)")
command.StringVar(&command.timelineListID, "timeline-list-id", "", "specify the ID of the list timeline to display") command.StringVar(&command.listID, listIDFlag, "", "specify the ID of the list to display")
command.StringVar(&command.timelineTagName, "timeline-tag-name", "", "specify the name of the tag timeline to display") command.StringVar(&command.tag, tagFlag, "", "specify the name of the tag to use")
command.IntVar(&command.timelineLimit, "timeline-limit", 5, "specify the number of statuses to display") command.IntVar(&command.timelineLimit, timelineLimitFlag, 5, "specify the number of statuses to display")
command.Usage = commandUsageFunc(name, summary, command.FlagSet) command.Usage = commandUsageFunc(name, summary, command.FlagSet)
return &command return &command
@ -43,7 +43,20 @@ func newShowCommand(name, summary string) *showCommand {
func (c *showCommand) Execute() error { func (c *showCommand) Execute() error {
if c.resourceType == "" { if c.resourceType == "" {
return errors.New("the type field is not set") return flagNotSetError{flagText: resourceTypeFlag}
}
funcMap := map[string]func(*client.Client) error{
instanceResource: c.showInstance,
accountResource: c.showAccount,
statusResource: c.showStatus,
timelineResource: c.showTimeline,
listResource: c.showLists,
}
doFunc, ok := funcMap[c.resourceType]
if !ok {
return unsupportedResourceTypeError{resourceType: c.resourceType}
} }
gtsClient, err := client.NewClientFromConfig() gtsClient, err := client.NewClientFromConfig()
@ -51,19 +64,6 @@ func (c *showCommand) Execute() error {
return fmt.Errorf("unable to create the GoToSocial client; %w", err) return fmt.Errorf("unable to create the GoToSocial client; %w", err)
} }
funcMap := map[string]func(*client.Client) error{
"instance": c.showInstance,
"account": c.showAccount,
"status": c.showStatus,
"timeline": c.showTimeline,
"lists": c.showLists,
}
doFunc, ok := funcMap[c.resourceType]
if !ok {
return fmt.Errorf("unsupported resource type %q", c.resourceType)
}
return doFunc(gtsClient) return doFunc(gtsClient)
} }
@ -90,7 +90,7 @@ func (c *showCommand) showAccount(gts *client.Client) error {
accountURI = authConfig.CurrentAccount accountURI = authConfig.CurrentAccount
} else { } else {
if c.account == "" { if c.account == "" {
return errors.New("the account flag is not set") return flagNotSetError{flagText: accountFlag}
} }
accountURI = c.account accountURI = c.account
@ -108,7 +108,7 @@ func (c *showCommand) showAccount(gts *client.Client) error {
func (c *showCommand) showStatus(gts *client.Client) error { func (c *showCommand) showStatus(gts *client.Client) error {
if c.statusID == "" { if c.statusID == "" {
return errors.New("the status-id flag is not set") return flagNotSetError{flagText: statusIDFlag}
} }
status, err := gts.GetStatus(c.statusID) status, err := gts.GetStatus(c.statusID)
@ -127,29 +127,29 @@ func (c *showCommand) showTimeline(gts *client.Client) error {
err error err error
) )
switch c.timelineType { switch c.timelineCategory {
case "home": case "home":
timeline, err = gts.GetHomeTimeline(c.timelineLimit) timeline, err = gts.GetHomeTimeline(c.timelineLimit)
case "public": case "public":
timeline, err = gts.GetPublicTimeline(c.timelineLimit) timeline, err = gts.GetPublicTimeline(c.timelineLimit)
case "list": case "list":
if c.timelineListID == "" { if c.listID == "" {
return errors.New("the timeline-list-id flag is not set") return flagNotSetError{flagText: listIDFlag}
} }
timeline, err = gts.GetListTimeline(c.timelineListID, c.timelineLimit) timeline, err = gts.GetListTimeline(c.listID, c.timelineLimit)
case "tag": case "tag":
if c.timelineTagName == "" { if c.tag == "" {
return errors.New("the timeline-tag-name flag is not set") return flagNotSetError{flagText: tagFlag}
} }
timeline, err = gts.GetTagTimeline(c.timelineTagName, c.timelineLimit) timeline, err = gts.GetTagTimeline(c.tag, c.timelineLimit)
default: default:
return fmt.Errorf("%q is not a valid type of timeline", c.timelineType) return invalidTimelineCategoryError{category: c.timelineCategory}
} }
if err != nil { if err != nil {
return fmt.Errorf("unable to retrieve the %s timeline; %w", c.timelineType, err) return fmt.Errorf("unable to retrieve the %s timeline; %w", c.timelineCategory, err)
} }
if len(timeline.Statuses) == 0 { if len(timeline.Statuses) == 0 {

View file

@ -18,13 +18,18 @@ func newSwitchCommand(name, summary string) *switchCommand {
toAccount: "", toAccount: "",
} }
command.StringVar(&command.toAccount, "to-account", "", "the account to switch to") command.StringVar(&command.toAccount, toAccountFlag, "", "the account to switch to")
command.Usage = commandUsageFunc(name, summary, command.FlagSet) command.Usage = commandUsageFunc(name, summary, command.FlagSet)
return &command return &command
} }
func (c *switchCommand) Execute() error { func (c *switchCommand) Execute() error {
if c.toAccount == "" {
return flagNotSetError{flagText: toAccountFlag}
}
if err := config.UpdateCurrentAccount(c.toAccount); err != nil { if err := config.UpdateCurrentAccount(c.toAccount); err != nil {
return fmt.Errorf("unable to switch accounts; %w", err) return fmt.Errorf("unable to switch accounts; %w", err)
} }

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
@ -23,10 +22,10 @@ func newUpdateCommand(name, summary string) *updateCommand {
FlagSet: flag.NewFlagSet(name, flag.ExitOnError), FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
} }
command.StringVar(&command.resourceType, "type", "", "specify the type of resource to update") command.StringVar(&command.resourceType, resourceTypeFlag, "", "specify the type of resource to update")
command.StringVar(&command.listID, "list-id", "", "specify the ID of the list to update") command.StringVar(&command.listID, listIDFlag, "", "specify the ID of the list to update")
command.StringVar(&command.listTitle, "list-title", "", "specify the title of the list") command.StringVar(&command.listTitle, listTitleFlag, "", "specify the title of the list")
command.StringVar(&command.listRepliesPolicy, "list-replies-policy", "", "specify the policy of the replies for this list (valid values are followed, list and none)") command.StringVar(&command.listRepliesPolicy, listRepliesPolicyFlag, "", "specify the policy of the replies for this list (valid values are followed, list and none)")
command.Usage = commandUsageFunc(name, summary, command.FlagSet) command.Usage = commandUsageFunc(name, summary, command.FlagSet)
@ -35,7 +34,16 @@ func newUpdateCommand(name, summary string) *updateCommand {
func (c *updateCommand) Execute() error { func (c *updateCommand) Execute() error {
if c.resourceType == "" { if c.resourceType == "" {
return errors.New("the type field is not set") return flagNotSetError{flagText: resourceTypeFlag}
}
funcMap := map[string]func(*client.Client) error{
listResource: c.updateList,
}
doFunc, ok := funcMap[c.resourceType]
if !ok {
return unsupportedResourceTypeError{resourceType: c.resourceType}
} }
gtsClient, err := client.NewClientFromConfig() gtsClient, err := client.NewClientFromConfig()
@ -43,21 +51,12 @@ func (c *updateCommand) Execute() error {
return fmt.Errorf("unable to create the GoToSocial client; %w", err) return fmt.Errorf("unable to create the GoToSocial client; %w", err)
} }
funcMap := map[string]func(*client.Client) error{
"lists": c.updateList,
}
doFunc, ok := funcMap[c.resourceType]
if !ok {
return fmt.Errorf("unsupported resource type %q", c.resourceType)
}
return doFunc(gtsClient) return doFunc(gtsClient)
} }
func (c *updateCommand) updateList(gtsClient *client.Client) error { func (c *updateCommand) updateList(gtsClient *client.Client) error {
if c.listID == "" { if c.listID == "" {
return errors.New("the list-id flag is not set") return flagNotSetError{flagText: listIDFlag}
} }
list, err := gtsClient.GetList(c.listID) list, err := gtsClient.GetList(c.listID)