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"
@ -17,9 +16,9 @@ type showCommand struct {
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
} }
@ -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)