Skip to content

Commit

Permalink
Add max-retry option for info command
Browse files Browse the repository at this point in the history
  • Loading branch information
yasuoza committed Nov 25, 2020
1 parent 4620f07 commit fe70bd7
Showing 1 changed file with 53 additions and 26 deletions.
79 changes: 53 additions & 26 deletions cmd/switchbot/command/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/mitchellh/cli"
"github.com/olekukonko/tablewriter"
"github.com/yasuoza/switchbot"
Expand All @@ -22,30 +23,25 @@ type InfoCommand struct {
type infoCfg struct {
Addr string
Format string
MaxRetry int
TimeoutSec int
}

// Run executes parse args and pass args to RunContext.
func (c *InfoCommand) Run(args []string) int {
arg, parseStatus := c.parseArgs(args)
cfg, parseStatus := c.parseArgs(args)

if parseStatus != 0 {
return parseStatus
}

return c.RunContext(context.Background(), arg)
}

// RunContext executes Info function.
func (c *InfoCommand) RunContext(ctx context.Context, cfg *infoCfg) int {
bot, err := switchbot.Connect(ctx, cfg.Addr, time.Duration(cfg.TimeoutSec)*time.Second)
info, err := c.runWithRetry(context.Background(), cfg)
if err != nil {
c.UI.Error("Failed to connect SwitchBot")
msg := fmt.Sprintf("Failed to retreive info from SwitchBot: %s", err.Error())
c.UI.Error(msg)
return 1
}
defer bot.Disconnect()

info, err := bot.GetInfo()
if err != nil {
c.UI.Error("Failed to retreive info from SwitchBot")
return 1
Expand All @@ -54,34 +50,31 @@ func (c *InfoCommand) RunContext(ctx context.Context, cfg *infoCfg) int {
if cfg.Format == "json" {
err := printAsJson(info)
if err != nil {
c.UI.Error("Failed to retreive info from SwitchBot")
msg := fmt.Sprintf("Failed to retreive info from SwitchBot: %s", err.Error())
c.UI.Error(msg)
return 1
}
} else {
printAsTable(info, c.UI.Writer)
}

return 0

}

func (c *InfoCommand) parseArgs(args []string) (*infoCfg, int) {
cfg := &infoCfg{}
flags := flag.NewFlagSet("info", flag.ContinueOnError)
flags.IntVar(&cfg.TimeoutSec, "timeout", 10, "")
flags.StringVar(&cfg.Format, "format", "table", "")
flags.Usage = func() {
c.UI.Info(c.Help())
// ConnectAndGetInfo connect and get info.
func (c *InfoCommand) ConnectAndGetInfo(ctx context.Context, cfg *infoCfg) (*switchbot.BotInfo, error) {
bot, err := switchbot.Connect(ctx, cfg.Addr, time.Duration(cfg.TimeoutSec)*time.Second)
if err != nil {
return nil, err
}
flags.Parse(args)
defer bot.Disconnect()

args = flags.Args()
if len(args) != 1 || (cfg.Format != "table" && cfg.Format != "json") {
flags.Usage()
return cfg, 127
info, err := bot.GetInfo()
if err != nil {
return nil, err
}

cfg.Addr = args[0]
return cfg, 0
return info, nil
}

// Help represents help message for press command.
Expand All @@ -92,6 +85,7 @@ Usage: switchbot info [options] ADDRESS
Options:
-format=table Output format. 'table' and 'json' are available.
-max-retry=0 Maximum retry count. (Default 0)
-timeout=10 Connection timeout seconds. (Default 10)
`

Expand All @@ -103,6 +97,27 @@ func (c *InfoCommand) Synopsis() string {
return "Show current SwitchBot information"
}

func (c *InfoCommand) parseArgs(args []string) (*infoCfg, int) {
cfg := &infoCfg{}
flags := flag.NewFlagSet("info", flag.ContinueOnError)
flags.StringVar(&cfg.Format, "format", "table", "")
flags.IntVar(&cfg.MaxRetry, "max-retry", 0, "")
flags.IntVar(&cfg.TimeoutSec, "timeout", 10, "")
flags.Usage = func() {
c.UI.Info(c.Help())
}
flags.Parse(args)

args = flags.Args()
if len(args) != 1 || (cfg.Format != "table" && cfg.Format != "json") {
flags.Usage()
return cfg, 127
}

cfg.Addr = args[0]
return cfg, 0
}

func printAsJson(i *switchbot.BotInfo) error {
data, err := json.MarshalIndent(i, "", " ")
if err != nil {
Expand Down Expand Up @@ -143,3 +158,15 @@ func printAsTable(i *switchbot.BotInfo, writer io.Writer) {
table.Append(data)
table.Render()
}

func (c *InfoCommand) runWithRetry(ctx context.Context, cfg *infoCfg) (*switchbot.BotInfo, error) {
var info *switchbot.BotInfo
f := func() error {
var err error
info, err = c.ConnectAndGetInfo(ctx, cfg)
return err
}
bo := backoff.NewExponentialBackOff()
bw := backoff.WithMaxRetries(bo, uint64(cfg.MaxRetry))
return info, backoff.Retry(f, bw)
}

0 comments on commit fe70bd7

Please sign in to comment.