diff --git a/cmd/config.go b/cmd/config.go index ea151940..84b76f00 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -220,11 +220,7 @@ var configDeleteCmd = &cobra.Command{ os.Exit(1) } if yesNo(fmt.Sprintf("You are attempting to delete config for lagoon '%s', are you sure?", lagoonConfig.Lagoon)) { - err := removeConfig(lagoonConfig.Lagoon) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } + removeConfig(lagoonConfig.Lagoon) } }, } @@ -247,19 +243,14 @@ var configFeatureSwitch = &cobra.Command{ lagoonCLIConfig.EnvironmentFromDirectory = false } strictHostKeyChecking, err := cmd.Flags().GetString("strict-host-key-checking") - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } + handleError(err) strictHostKeyCheckingProvided := cmd.Flags().Lookup("strict-host-key-checking").Changed if strictHostKeyCheckingProvided { lagoonCLIConfig.StrictHostKeyChecking = strictHostKeyChecking } - if err := writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)); err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } + err = writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)) + handleError(err) }, } @@ -399,11 +390,8 @@ func writeLagoonConfig(lc *config.Config, file string) error { return nil } -func removeConfig(key string) error { +func removeConfig(key string) { delete(lagoonCLIConfig.Lagoons, key) - if err := writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)); err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } - return nil + err := writeLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)) + handleError(err) } diff --git a/cmd/root.go b/cmd/root.go index 76f30b3a..759a7bae 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -96,10 +96,7 @@ var rootCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { if docsFlag { err := doc.GenMarkdownTree(cmd, "docs/commands") - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } + handleError(err) fmt.Println("Documentation updated") return } @@ -114,10 +111,8 @@ var rootCmd = &cobra.Command{ // Execute the root command. func Execute() { - if err := rootCmd.Execute(); err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } + err := rootCmd.Execute() + handleError(err) } // IsInternetActive() checks to see if we have a viable @@ -226,28 +221,18 @@ func initConfig() { // Find home directory. userPath, err = os.UserHomeDir() if err != nil { - output.RenderError(fmt.Errorf("couldn't get $HOME: %v", err).Error(), outputOptions) - os.Exit(1) + handleError(fmt.Errorf("couldn't get $HOME: %v", err)) } configFilePath = userPath // check if we are being given a path to a different config file err = getLagoonConfigFile(&configFilePath, &configName, &configExtension, createConfig, rootCmd) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } + handleError(err) err = readLagoonConfig(&lagoonCLIConfig, filepath.Join(configFilePath, configName+configExtension)) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } + handleError(err) err = getLagoonContext(&lagoonCLIConfig, &cmdLagoon, rootCmd) - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } + handleError(err) // if the directory or repository you're in has a valid .lagoon.yml and docker-compose.yml with x-lagoon-project in it // we can use that inplaces where projects already exist so you don't have to type it out @@ -271,10 +256,7 @@ func yesNo(message string) bool { Items: []string{"No", "Yes"}, } _, result, err := prompt.Run() - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } + handleError(err) return result == "Yes" } return true diff --git a/cmd/ssh.go b/cmd/ssh.go index d8aa5e37..d41e1907 100644 --- a/cmd/ssh.go +++ b/cmd/ssh.go @@ -6,7 +6,6 @@ import ( "github.com/spf13/cobra" lagoonssh "github.com/uselagoon/lagoon-cli/pkg/lagoon/ssh" - "github.com/uselagoon/lagoon-cli/pkg/output" "golang.org/x/crypto/ssh" ) @@ -87,10 +86,7 @@ var sshEnvCmd = &cobra.Command{ } else { err = lagoonssh.InteractiveSSH(sshConfig, sshService, sshContainer, config) } - if err != nil { - output.RenderError(err.Error(), outputOptions) - os.Exit(1) - } + handleError(err) } return nil }, diff --git a/cmd/users.go b/cmd/users.go index 54b71e3d..b83707ba 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -311,8 +311,7 @@ var updateUserCmd = &cobra.Command{ return err } if firstName == "" && lastName == "" && emailAddress == "" { - output.RenderError("Missing arguments: Nothing to update, please provide a field to update", outputOptions) - return nil + return fmt.Errorf("missing arguments: Nothing to update, please provide a field to update") } current := lagoonCLIConfig.Current diff --git a/cmd/web.go b/cmd/web.go index 0e61338a..d90d9022 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -7,7 +7,6 @@ import ( "github.com/pkg/browser" "github.com/spf13/cobra" - "github.com/uselagoon/lagoon-cli/pkg/output" ) var webCmd = &cobra.Command{ @@ -26,8 +25,7 @@ var webCmd = &cobra.Command{ if lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].UI != "" { urlBuilder.WriteString(fmt.Sprintf("/projects/%s", cmdProjectName)) } else { - output.RenderError("unable to determine url for ui, is one set?", outputOptions) - os.Exit(1) + handleError(fmt.Errorf("unable to determine url for ui, is one set?")) } url := urlBuilder.String() @@ -44,8 +42,7 @@ var kibanaCmd = &cobra.Command{ urlBuilder := strings.Builder{} urlBuilder.WriteString(lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].Kibana) if lagoonCLIConfig.Lagoons[lagoonCLIConfig.Current].Kibana == "" { - output.RenderError("unable to determine url for kibana, is one set?", outputOptions) - os.Exit(1) + handleError(fmt.Errorf("unable to determine url for kibana, is one set?")) } url := urlBuilder.String() diff --git a/pkg/output/main.go b/pkg/output/main.go index a0b20752..48213d44 100644 --- a/pkg/output/main.go +++ b/pkg/output/main.go @@ -63,7 +63,7 @@ func RenderError(errorMsg string, opts Options) { jsonData := Result{ Error: trimQuotes(errorMsg), } - RenderJSON(jsonData, opts) + fmt.Fprintf(os.Stderr, "%s", RenderJSON(jsonData, opts)) } else { fmt.Fprintf(os.Stderr, "Error: %s", trimQuotes(errorMsg)) } @@ -75,7 +75,7 @@ func RenderInfo(infoMsg string, opts Options) { jsonData := Result{ Info: trimQuotes(infoMsg), } - RenderJSON(jsonData, opts) + fmt.Fprintf(os.Stderr, "%s", RenderJSON(jsonData, opts)) } else { fmt.Fprintf(os.Stderr, "Info: %s", trimQuotes(infoMsg)) } diff --git a/pkg/output/main_test.go b/pkg/output/main_test.go index dfc0ec61..6465552f 100644 --- a/pkg/output/main_test.go +++ b/pkg/output/main_test.go @@ -52,19 +52,17 @@ func TestRenderError(t *testing.T) { Pretty: false, } - rescueStdout := os.Stderr - r, w, _ := os.Pipe() - defer func() { - os.Stderr = rescueStdout - }() - os.Stderr = w - RenderError(testData, outputOptions) - w.Close() - var out bytes.Buffer - _, _ = io.Copy(&out, r) - if out.String() != testSuccess { - checkEqual(t, out.String(), testSuccess, " render error stdout processing failed") - } + out := captureStderr(func() { + RenderError(testData, outputOptions) + }) + checkEqual(t, out, testSuccess, " render error stdout processing failed") + + var testJson = `{"error":"Error Message"}` + outputOptions.JSON = true + out = captureStderr(func() { + RenderError(testData, outputOptions) + }) + checkEqual(t, out, testJson, " render error stdout processing failed") } func TestRenderInfo(t *testing.T) { @@ -78,19 +76,17 @@ func TestRenderInfo(t *testing.T) { Pretty: false, } - rescueStdout := os.Stderr - r, w, _ := os.Pipe() - defer func() { - os.Stderr = rescueStdout - }() - os.Stderr = w - RenderInfo(testData, outputOptions) - w.Close() - var out bytes.Buffer - _, _ = io.Copy(&out, r) - if out.String() != testSuccess1 { - checkEqual(t, out.String(), testSuccess1, " render info stdout processing failed") - } + out := captureStderr(func() { + RenderInfo(testData, outputOptions) + }) + checkEqual(t, out, testSuccess1, " render info stdout processing failed") + + var testJson = `{"info":"Info Message"}` + outputOptions.JSON = true + out = captureStderr(func() { + RenderInfo(testData, outputOptions) + }) + checkEqual(t, out, testJson, " render error stdout processing failed") } func TestRenderOutput(t *testing.T) { @@ -143,3 +139,18 @@ func TestRenderString(t *testing.T) { output = RenderString(testData, outputOptions) checkEqual(t, output, testSuccess2, " render string json processing failed") } + +func captureStderr(fn func()) string { + var out bytes.Buffer + rescueStderr := os.Stderr + r, w, _ := os.Pipe() + os.Stderr = w + + fn() + + w.Close() + os.Stderr = rescueStderr + + _, _ = io.Copy(&out, r) + return out.String() +}