diff --git a/cli/action.go b/cli/action.go index ef4b2056..bfd6cc7b 100644 --- a/cli/action.go +++ b/cli/action.go @@ -3,7 +3,7 @@ package cli import ( "fmt" - "github.com/odpf/salt/term" //nolint + "github.com/odpf/salt/term" // nolint entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" "google.golang.org/protobuf/types/known/structpb" @@ -26,7 +26,7 @@ func cmdAction() *cobra.Command { "group:core": "true", }, Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { + RunE: handleErr(func(cmd *cobra.Command, args []string) error { spinner := printer.Spin("") defer spinner.Stop() cs := term.NewColorScheme() @@ -69,7 +69,7 @@ func cmdAction() *cobra.Command { } return nil - }, + }), } cmd.Flags().StringVarP(&urn, "urn", "u", "", "urn of the resource") diff --git a/cli/config.go b/cli/config.go index 94516cc2..617bf186 100644 --- a/cli/config.go +++ b/cli/config.go @@ -1,7 +1,6 @@ package cli import ( - "fmt" "os" "time" @@ -37,14 +36,13 @@ func cmdShowConfigs() *cobra.Command { return &cobra.Command{ Use: "configs", Short: "Display configurations currently loaded", - Run: func(cmd *cobra.Command, args []string) { + RunE: handleErr(func(cmd *cobra.Command, args []string) error { cfg, err := loadConfig(cmd) if err != nil { - fmt.Printf("failed to read configs: %v\n", err) // nolint - os.Exit(1) + fatalExitf("failed to read configs: %v", err) } - _ = yaml.NewEncoder(os.Stdout).Encode(cfg) - }, + return yaml.NewEncoder(os.Stdout).Encode(cfg) + }), } } diff --git a/cli/logs.go b/cli/logs.go index 961e66d9..6327fdce 100644 --- a/cli/logs.go +++ b/cli/logs.go @@ -2,11 +2,12 @@ package cli import ( "errors" + "fmt" "io" "log" "strings" - "github.com/odpf/salt/term" //nolint + "github.com/odpf/salt/term" // nolint entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" "github.com/MakeNowJust/heredoc" @@ -28,7 +29,7 @@ func cmdLogs() *cobra.Command { "group:core": "true", }, Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { + RunE: handleErr(func(cmd *cobra.Command, args []string) error { spinner := printer.Spin("") defer spinner.Stop() cs := term.NewColorScheme() @@ -44,7 +45,6 @@ func cmdLogs() *cobra.Command { keyValue := strings.Split(f, "=") filters[keyValue[0]] = keyValue[1] } - reqBody.Filter = filters reqBody.Urn = args[0] @@ -61,21 +61,21 @@ func cmdLogs() *cobra.Command { for { resp, err := stream.Recv() - if errors.Is(err, io.EOF) { - break - } if err != nil { - log.Fatalf("cannot receive %v", err) + if errors.Is(err, io.EOF) { + break + } + return fmt.Errorf("failed to read stream: %w", err) } + log.SetFlags(0) - log.Printf(cs.Bluef("%s", resp.GetChunk().GetData())) //nolint + log.Printf(cs.Bluef("%s", resp.GetChunk().GetData())) // nolint } return nil - }, + }), } cmd.Flags().StringArrayVarP(&filter, "filter", "f", nil, "Use filters. Example: --filter=\"key=value\"") - return cmd } diff --git a/cli/migrate.go b/cli/migrate.go index 9b2fa739..60b120e1 100644 --- a/cli/migrate.go +++ b/cli/migrate.go @@ -18,7 +18,7 @@ func cmdMigrate() *cobra.Command { }, } - cmd.RunE = func(cmd *cobra.Command, args []string) error { + cmd.RunE = handleErr(func(cmd *cobra.Command, args []string) error { cfg, err := loadConfig(cmd) if err != nil { return err @@ -30,7 +30,7 @@ func cmdMigrate() *cobra.Command { } return runMigrations(cmd.Context(), zapLog, cfg) - } + }) return cmd } diff --git a/cli/resource.go b/cli/resource.go index 700cc294..3cc7c413 100644 --- a/cli/resource.go +++ b/cli/resource.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - "github.com/odpf/salt/term" //nolint + "github.com/odpf/salt/term" // nolint entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" "github.com/MakeNowJust/heredoc" @@ -51,7 +51,7 @@ func createResourceCommand() *cobra.Command { Annotations: map[string]string{ "action:core": "true", }, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: handleErr(func(cmd *cobra.Command, args []string) error { spinner := printer.Spin("") defer spinner.Stop() cs := term.NewColorScheme() @@ -59,9 +59,7 @@ func createResourceCommand() *cobra.Command { var reqBody entropyv1beta1.CreateResourceRequest if err := parseFile(file, &reqBody); err != nil { return err - } - err := reqBody.ValidateAll() - if err != nil { + } else if err := reqBody.ValidateAll(); err != nil { return err } @@ -85,8 +83,9 @@ func createResourceCommand() *cobra.Command { } fmt.Println(cs.Bluef(formattedOutput)) } + return nil - }, + }), } cmd.Flags().StringVarP(&file, "file", "f", "", "path to body of resource") @@ -106,7 +105,7 @@ func listAllResourcesCommand() *cobra.Command { Annotations: map[string]string{ "action:core": "true", }, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: handleErr(func(cmd *cobra.Command, args []string) error { spinner := printer.Spin("") defer spinner.Stop() cs := term.NewColorScheme() @@ -149,7 +148,7 @@ func listAllResourcesCommand() *cobra.Command { fmt.Println(cs.Cyanf("To view all the data in JSON/YAML format, use flag `-o json | yaml`")) } return nil - }, + }), } cmd.Flags().StringVarP(&output, "out", "o", "", "output format, `-o json | yaml`") @@ -171,7 +170,7 @@ func viewResourceCommand() *cobra.Command { "action:core": "true", }, Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { + RunE: handleErr(func(cmd *cobra.Command, args []string) error { spinner := printer.Spin("") defer spinner.Stop() cs := term.NewColorScheme() @@ -184,6 +183,7 @@ func viewResourceCommand() *cobra.Command { return err } defer cancel() + res, err := client.GetResource(cmd.Context(), &reqBody) if err != nil { return err @@ -197,17 +197,17 @@ func viewResourceCommand() *cobra.Command { } fmt.Println(cs.Bluef(formattedOutput)) } else { - report := [][]string{} - report = append(report, []string{"URN", "NAME", "KIND", "PROJECT", "STATUS"}) r := res.GetResource() - report = append(report, []string{r.Urn, r.Name, r.Kind, r.Project, r.State.Status.String()}) - printer.Table(os.Stdout, report) + printer.Table(os.Stdout, [][]string{ + {"URN", "NAME", "KIND", "PROJECT", "STATUS"}, + {r.Urn, r.Name, r.Kind, r.Project, r.State.Status.String()}, + }) fmt.Println(cs.Cyanf("\nTo view all the data in JSON/YAML format, use flag `-o json | yaml`")) } return nil - }, + }), } cmd.Flags().StringVarP(&output, "out", "o", "", "output format, `-o json | yaml`") @@ -227,7 +227,7 @@ func editResourceCommand() *cobra.Command { "action:core": "true", }, Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { + RunE: handleErr(func(cmd *cobra.Command, args []string) error { spinner := printer.Spin("") defer spinner.Stop() cs := term.NewColorScheme() @@ -235,17 +235,14 @@ func editResourceCommand() *cobra.Command { var newSpec entropyv1beta1.ResourceSpec if err := parseFile(file, &newSpec); err != nil { return err - } - err := newSpec.ValidateAll() - if err != nil { + } else if err := newSpec.ValidateAll(); err != nil { return err } var reqBody entropyv1beta1.UpdateResourceRequest reqBody.NewSpec = &newSpec reqBody.Urn = args[0] - err = reqBody.ValidateAll() - if err != nil { + if err := reqBody.ValidateAll(); err != nil { return err } @@ -263,7 +260,7 @@ func editResourceCommand() *cobra.Command { fmt.Println(cs.Greenf("Successfully updated")) return nil - }, + }), } cmd.Flags().StringVarP(&file, "file", "f", "", "path to the updated spec of resource") @@ -282,7 +279,7 @@ func deleteResourceCommand() *cobra.Command { "action:core": "true", }, Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { + RunE: handleErr(func(cmd *cobra.Command, args []string) error { spinner := printer.Spin("") defer spinner.Stop() cs := term.NewColorScheme() @@ -304,7 +301,7 @@ func deleteResourceCommand() *cobra.Command { fmt.Println(cs.Greenf("Successfully deleted")) return nil - }, + }), } return cmd } diff --git a/cli/serve.go b/cli/serve.go index 687520b5..e838dce9 100644 --- a/cli/serve.go +++ b/cli/serve.go @@ -34,7 +34,7 @@ func cmdServe() *cobra.Command { cmd.Flags().BoolVar(&migrate, "migrate", false, "Run migrations before starting") cmd.Flags().BoolVar(&spawnWorker, "worker", false, "Run worker threads as well") - cmd.RunE = func(cmd *cobra.Command, args []string) error { + cmd.RunE = handleErr(func(cmd *cobra.Command, args []string) error { cfg, err := loadConfig(cmd) if err != nil { return err @@ -62,7 +62,8 @@ func cmdServe() *cobra.Command { } return runServer(cmd.Context(), zapLog, cfg, asyncWorker) - } + }) + return cmd } diff --git a/cli/utils.go b/cli/utils.go index fabafe8e..556fd85e 100644 --- a/cli/utils.go +++ b/cli/utils.go @@ -5,9 +5,11 @@ import ( "errors" "fmt" "io/ioutil" + "os" "path/filepath" "github.com/ghodss/yaml" + "github.com/spf13/cobra" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -18,6 +20,8 @@ const ( outputYML = "yml" ) +type RunEFunc func(cmd *cobra.Command, args []string) error + func parseFile(filePath string, v protoreflect.ProtoMessage) error { b, err := ioutil.ReadFile(filePath) if err != nil { @@ -29,12 +33,14 @@ func parseFile(filePath string, v protoreflect.ProtoMessage) error { if err := json.Unmarshal(b, v); err != nil { return fmt.Errorf("invalid json: %w", err) } + case ".yaml", ".yml": if err := yaml.Unmarshal(b, v); err != nil { return fmt.Errorf("invalid yaml: %w", err) } + default: - return errors.New("unsupported file type") //nolint + return errors.New("unsupported file type") // nolint } return nil @@ -54,6 +60,7 @@ func formatOutput(i protoreflect.ProtoMessage, format string) (string, error) { switch format { case outputJSON: return string(b), nil + case outputYAML, outputYML: y, e := yaml.JSONToYAML(b) if e != nil { @@ -61,6 +68,20 @@ func formatOutput(i protoreflect.ProtoMessage, format string) (string, error) { } return string(y), nil default: - return "", errors.New("unsupported format") //nolint + return "", errors.New("unsupported format") // nolint + } +} + +func fatalExitf(format string, args ...interface{}) { + fmt.Printf(format+"\n", args...) + os.Exit(1) +} + +func handleErr(fn RunEFunc) RunEFunc { + return func(cmd *cobra.Command, args []string) error { + if err := fn(cmd, args); err != nil { + fatalExitf(err.Error()) + } + return nil } }