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
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)

View file

@ -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 {

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
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

View file

@ -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

View file

@ -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 {

View file

@ -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)
}

View file

@ -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)