From c15ffeab6fc36d790820607bedcdf057cd628026 Mon Sep 17 00:00:00 2001 From: "kayos@tcp.direct" Date: Wed, 25 Jan 2023 13:16:10 -0800 Subject: [PATCH] Enhance CLI history, improve error handling, improve testing --- internal/cli/cli.go | 59 +++++++++++++++++++++++------------ internal/cli/set.go | 12 +++---- internal/system/stats_test.go | 6 +++- 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 1428a40..869319e 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -29,11 +29,12 @@ var noHist = map[string]bool{"clear": true, "exit": true, "quit": true} // Interpret is where we will actuall define our Commands func executor(cmd string) { + var status = 0 defer func() { if r := recover(); r != nil { log.Error().Msgf("PANIC: %s", r) } - if _, ok := noHist[cmd]; !ok { + if _, ok := noHist[cmd]; !ok && status == 0 { history = append(history, cmd) go saveHist() } @@ -54,12 +55,15 @@ func executor(cmd string) { println("use: use ") return } - if br, ok := ziggy.Lucifer.Bridges[args[1]]; !ok { - println("invalid bridge: " + args[1]) - } else { - sel.Bridge = args[1] - log.Info().Str("host", br.Host).Int("lights", len(br.HueLights)).Msg("switched to bridge: " + sel.Bridge) + br, ok := ziggy.Lucifer.Bridges[args[1]] + if !ok { + log.Error().Msg("invalid bridge: " + args[1]) + status = 1 + return } + sel.Bridge = args[1] + log.Info().Str("host", br.Host).Int("lights", len(br.HueLights)).Msg("switched to bridge: " + sel.Bridge) + case "debug": levelsdebug := map[string]zerolog.Level{"info": zerolog.InfoLevel, "debug": zerolog.DebugLevel, "trace": zerolog.TraceLevel} debuglevels := map[zerolog.Level]string{zerolog.InfoLevel: "info", zerolog.DebugLevel: "debug", zerolog.TraceLevel: "trace"} @@ -94,6 +98,7 @@ func executor(cmd string) { bcmd, ok := Commands[args[0]] if !ok { log.Error().Msg("invalid command: " + args[0]) + status = 1 return } br, ok := ziggy.Lucifer.Bridges[sel.Bridge] @@ -115,11 +120,13 @@ func executor(cmd string) { } }(br) } - } else { - err := bcmd.reactor(br, args[1:]) - if err != nil { - log.Error().Err(err).Msg("error executing command") - } + return + } + + err := bcmd.reactor(br, args[1:]) + if err != nil { + log.Error().Err(err).Msg("error executing command") + status = 1 } } } @@ -165,17 +172,29 @@ var ( histLoaded bool ) +func loadHist() { + var histMap = make(map[string]bool) + pth, _ := filepath.Split(config.Filename) + rb, _ := os.OpenFile(filepath.Join(pth, ".ziggs_history"), os.O_RDONLY, 0644) + xerox := bufio.NewScanner(rb) + for xerox.Scan() { + _, ok := histMap[strings.TrimSpace(xerox.Text())] + switch { + case strings.TrimSpace(xerox.Text()) == "": + continue + case ok: + continue + default: + histMap[strings.TrimSpace(xerox.Text())] = true + history = append(history, xerox.Text()) + } + } + histLoaded = true +} + func getHist() []string { if !histLoaded { - pth, _ := filepath.Split(config.Filename) - rb, _ := os.OpenFile(filepath.Join(pth, ".ziggs_history"), os.O_RDONLY, 0644) - xerox := bufio.NewScanner(rb) - for xerox.Scan() { - if strings.TrimSpace(xerox.Text()) != "" { - history = append(history, xerox.Text()) - } - } - histLoaded = true + loadHist() } return history } diff --git a/internal/cli/set.go b/internal/cli/set.go index 382a6b1..884e226 100644 --- a/internal/cli/set.go +++ b/internal/cli/set.go @@ -143,7 +143,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error { return errors.New("not enough arguments") } argHead++ - newHue, numErr := strconv.Atoi(args[argHead]) + newHue, numErr := strconv.Atoi(strings.TrimSpace(args[argHead])) if numErr != nil || newHue > 65535 || newHue < 0 { return fmt.Errorf("given hue is not a valid number: %w", numErr) } @@ -159,9 +159,9 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error { return errors.New("not enough arguments") } argHead++ - newSat, numErr := strconv.Atoi(args[argHead]) - if numErr != nil || newSat > 255 || newSat < 0 { - return fmt.Errorf("given saturation is not a valid number: %w", numErr) + newSat, numErr := strconv.Atoi(strings.TrimSpace(args[argHead])) + if numErr != nil { + return fmt.Errorf("given saturation is not a valid number: %v", numErr) } actions = append(actions, func() error { err := target.Sat(uint8(newSat)) @@ -175,7 +175,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error { return errors.New("not enough arguments") } argHead++ - newTemp, numErr := strconv.Atoi(args[argHead]) + newTemp, numErr := strconv.Atoi(strings.TrimSpace(args[argHead])) if numErr != nil || newTemp > 500 || newTemp < 153 { terr := fmt.Errorf("given temperature is not a valid number: %w", numErr) if numErr == nil { @@ -214,7 +214,7 @@ func cmdSet(bridge *ziggy.Bridge, args []string) error { if argHead > len(args)-1 { return errors.New("not enough arguments") } - targetScene := args[argHead] + targetScene := strings.TrimSpace(args[argHead]) actions = append(actions, func() error { err := target.Scene(targetScene) if err != nil { diff --git a/internal/system/stats_test.go b/internal/system/stats_test.go index 8a7ded7..1dc81b7 100644 --- a/internal/system/stats_test.go +++ b/internal/system/stats_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "os" "strings" "sync" "sync/atomic" @@ -44,6 +45,9 @@ func grind(ctx context.Context) { var once = &sync.Once{} func TestCPULoadGradient(t *testing.T) { + if os.Getenv("ZIGGS_TEST_CPU_LOAD") == "" { + t.Skip("skipping CPU load test") + } ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second)) defer cancel() grad, err := CPULoadGradient(ctx, "deepskyblue", "deeppink") @@ -72,7 +76,7 @@ func TestCPULoadGradient(t *testing.T) { } func TestCoreLoadHue(t *testing.T) { - ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(20*time.Second)) + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second)) defer cancel() huint, err := CoreLoadHue(ctx) if err != nil {