diff --git a/cmd/enbas/create.go b/cmd/enbas/create.go index 51da691..d6a831c 100644 --- a/cmd/enbas/create.go +++ b/cmd/enbas/create.go @@ -1,7 +1,6 @@ package main import ( - "errors" "flag" "fmt" @@ -22,9 +21,9 @@ func newCreateCommand(name, summary string) *createCommand { FlagSet: flag.NewFlagSet(name, flag.ExitOnError), } - command.StringVar(&command.resourceType, "type", "", "specify the type of resource to create") - command.StringVar(&command.listTitle, "list-title", "", "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.resourceType, resourceTypeFlag, "", "specify the type of resource to create") + command.StringVar(&command.listTitle, listTitleFlag, "", "specify the title of the list") + 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) @@ -33,7 +32,7 @@ func newCreateCommand(name, summary string) *createCommand { func (c *createCommand) Execute() error { if c.resourceType == "" { - return errors.New("the type field is not set") + return flagNotSetError{flagText: resourceTypeFlag} } gtsClient, err := client.NewClientFromConfig() @@ -42,20 +41,20 @@ func (c *createCommand) Execute() error { } funcMap := map[string]func(*client.Client) error{ - "lists": c.createLists, + listResource: c.createList, } doFunc, ok := funcMap[c.resourceType] if !ok { - return fmt.Errorf("unsupported type %q", c.resourceType) + return unsupportedResourceTypeError{resourceType: c.resourceType} } return doFunc(gtsClient) } -func (c *createCommand) createLists(gtsClient *client.Client) error { +func (c *createCommand) createList(gtsClient *client.Client) error { if c.listTitle == "" { - return errors.New("the list-title flag is not set") + return flagNotSetError{flagText: listTitleFlag} } repliesPolicy, err := model.ParseListRepliesPolicy(c.listRepliesPolicy) diff --git a/cmd/enbas/delete.go b/cmd/enbas/delete.go index 4d2e156..e0fc0f7 100644 --- a/cmd/enbas/delete.go +++ b/cmd/enbas/delete.go @@ -1,7 +1,6 @@ package main import ( - "errors" "flag" "fmt" @@ -20,8 +19,8 @@ func newDeleteCommand(name, summary string) *deleteCommand { FlagSet: flag.NewFlagSet(name, flag.ExitOnError), } - command.StringVar(&command.resourceType, "type", "", "specify the type of resource to delete") - command.StringVar(&command.listID, "list-id", "", "specify the ID of the list to delete") + command.StringVar(&command.resourceType, resourceTypeFlag, "", "specify the type of resource to delete") + command.StringVar(&command.listID, listIDFlag, "", "specify the ID of the list to delete") command.Usage = commandUsageFunc(name, summary, command.FlagSet) @@ -30,7 +29,16 @@ func newDeleteCommand(name, summary string) *deleteCommand { func (c *deleteCommand) Execute() error { 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() @@ -38,21 +46,12 @@ func (c *deleteCommand) Execute() error { 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) } func (c *deleteCommand) deleteList(gtsClient *client.Client) error { 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 { diff --git a/cmd/enbas/errors.go b/cmd/enbas/errors.go new file mode 100644 index 0000000..9a0db60 --- /dev/null +++ b/cmd/enbas/errors.go @@ -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)" +} diff --git a/cmd/enbas/login.go b/cmd/enbas/login.go index 1fa5107..46cde0e 100644 --- a/cmd/enbas/login.go +++ b/cmd/enbas/login.go @@ -1,7 +1,6 @@ package main import ( - "errors" "flag" "fmt" "strings" @@ -16,15 +15,13 @@ type loginCommand struct { instance string } -var errInstanceNotSet = errors.New("the instance flag is not set") - func newLoginCommand(name, summary string) *loginCommand { command := loginCommand{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), 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) @@ -35,7 +32,7 @@ func (c *loginCommand) Execute() error { var err error if c.instance == "" { - return errInstanceNotSet + return flagNotSetError{flagText: instanceFlag} } instance := c.instance diff --git a/cmd/enbas/main.go b/cmd/enbas/main.go index a23d2a6..5430a0d 100644 --- a/cmd/enbas/main.go +++ b/cmd/enbas/main.go @@ -6,6 +6,29 @@ import ( "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 { Name() string Parse(args []string) error diff --git a/cmd/enbas/show.go b/cmd/enbas/show.go index b2ad365..ef015c6 100644 --- a/cmd/enbas/show.go +++ b/cmd/enbas/show.go @@ -1,7 +1,6 @@ package main import ( - "errors" "flag" "fmt" @@ -13,14 +12,14 @@ import ( type showCommand struct { *flag.FlagSet - myAccount bool - resourceType string - account string - statusID string - timelineType string - timelineListID string - timelineTagName string - timelineLimit int + myAccount bool + resourceType string + account string + statusID string + timelineCategory string + listID string + tag string + timelineLimit int } func newShowCommand(name, summary string) *showCommand { @@ -28,14 +27,15 @@ func newShowCommand(name, summary string) *showCommand { FlagSet: flag.NewFlagSet(name, flag.ExitOnError), } - command.BoolVar(&command.myAccount, "my-account", false, "set to true to lookup your account") - command.StringVar(&command.resourceType, "type", "", "specify the type of resource to display") - command.StringVar(&command.account, "account", "", "specify the account URI to lookup") - command.StringVar(&command.statusID, "status-id", "", "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.timelineListID, "timeline-list-id", "", "specify the ID of the list timeline to display") - command.StringVar(&command.timelineTagName, "timeline-tag-name", "", "specify the name of the tag timeline to display") - command.IntVar(&command.timelineLimit, "timeline-limit", 5, "specify the number of statuses to display") + command.BoolVar(&command.myAccount, myAccountFlag, false, "set to true to lookup your account") + command.StringVar(&command.resourceType, resourceTypeFlag, "", "specify the type of resource to display") + command.StringVar(&command.account, accountFlag, "", "specify the account URI to lookup") + command.StringVar(&command.statusID, statusIDFlag, "", "specify the ID of the status to display") + command.StringVar(&command.timelineCategory, timelineCategoryFlag, "home", "specify the type of timeline to display (valid values are home, public, list and tag)") + command.StringVar(&command.listID, listIDFlag, "", "specify the ID of the list to display") + command.StringVar(&command.tag, tagFlag, "", "specify the name of the tag to use") + command.IntVar(&command.timelineLimit, timelineLimitFlag, 5, "specify the number of statuses to display") + command.Usage = commandUsageFunc(name, summary, command.FlagSet) return &command @@ -43,7 +43,20 @@ func newShowCommand(name, summary string) *showCommand { func (c *showCommand) Execute() error { 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() @@ -51,19 +64,6 @@ func (c *showCommand) Execute() error { 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) } @@ -90,7 +90,7 @@ func (c *showCommand) showAccount(gts *client.Client) error { accountURI = authConfig.CurrentAccount } else { if c.account == "" { - return errors.New("the account flag is not set") + return flagNotSetError{flagText: accountFlag} } accountURI = c.account @@ -108,7 +108,7 @@ func (c *showCommand) showAccount(gts *client.Client) error { func (c *showCommand) showStatus(gts *client.Client) error { if c.statusID == "" { - return errors.New("the status-id flag is not set") + return flagNotSetError{flagText: statusIDFlag} } status, err := gts.GetStatus(c.statusID) @@ -127,29 +127,29 @@ func (c *showCommand) showTimeline(gts *client.Client) error { err error ) - switch c.timelineType { + switch c.timelineCategory { case "home": timeline, err = gts.GetHomeTimeline(c.timelineLimit) case "public": timeline, err = gts.GetPublicTimeline(c.timelineLimit) case "list": - if c.timelineListID == "" { - return errors.New("the timeline-list-id flag is not set") + if c.listID == "" { + return flagNotSetError{flagText: listIDFlag} } - timeline, err = gts.GetListTimeline(c.timelineListID, c.timelineLimit) + timeline, err = gts.GetListTimeline(c.listID, c.timelineLimit) case "tag": - if c.timelineTagName == "" { - return errors.New("the timeline-tag-name flag is not set") + if c.tag == "" { + return flagNotSetError{flagText: tagFlag} } - timeline, err = gts.GetTagTimeline(c.timelineTagName, c.timelineLimit) + timeline, err = gts.GetTagTimeline(c.tag, c.timelineLimit) default: - return fmt.Errorf("%q is not a valid type of timeline", c.timelineType) + return invalidTimelineCategoryError{category: c.timelineCategory} } 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 { diff --git a/cmd/enbas/switch.go b/cmd/enbas/switch.go index 19155e4..152f3f4 100644 --- a/cmd/enbas/switch.go +++ b/cmd/enbas/switch.go @@ -18,13 +18,18 @@ func newSwitchCommand(name, summary string) *switchCommand { 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) return &command } func (c *switchCommand) Execute() error { + if c.toAccount == "" { + return flagNotSetError{flagText: toAccountFlag} + } + if err := config.UpdateCurrentAccount(c.toAccount); err != nil { return fmt.Errorf("unable to switch accounts; %w", err) } diff --git a/cmd/enbas/update.go b/cmd/enbas/update.go index a4afdb4..c9740f7 100644 --- a/cmd/enbas/update.go +++ b/cmd/enbas/update.go @@ -1,7 +1,6 @@ package main import ( - "errors" "flag" "fmt" @@ -23,10 +22,10 @@ func newUpdateCommand(name, summary string) *updateCommand { FlagSet: flag.NewFlagSet(name, flag.ExitOnError), } - command.StringVar(&command.resourceType, "type", "", "specify the type of resource to update") - command.StringVar(&command.listID, "list-id", "", "specify the ID of the list to update") - command.StringVar(&command.listTitle, "list-title", "", "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.resourceType, resourceTypeFlag, "", "specify the type of resource to update") + command.StringVar(&command.listID, listIDFlag, "", "specify the ID of the list to update") + command.StringVar(&command.listTitle, listTitleFlag, "", "specify the title of the list") + 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) @@ -35,7 +34,16 @@ func newUpdateCommand(name, summary string) *updateCommand { func (c *updateCommand) Execute() error { 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() @@ -43,21 +51,12 @@ func (c *updateCommand) Execute() error { 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) } func (c *updateCommand) updateList(gtsClient *client.Client) error { if c.listID == "" { - return errors.New("the list-id flag is not set") + return flagNotSetError{flagText: listIDFlag} } list, err := gtsClient.GetList(c.listID)