From 95d9a7672a683e0bbd9ffac14529e27eb90bb3b0 Mon Sep 17 00:00:00 2001 From: Mark McDonnell Date: Mon, 13 Feb 2023 13:49:09 +0000 Subject: [PATCH] fix(compute/build): ensure build output doesn't show unless --verbose flag is set (#815) --- pkg/commands/compute/build.go | 5 --- pkg/commands/compute/language_toolchain.go | 46 ++++++++++++---------- pkg/exec/exec.go | 19 ++++++++- 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/pkg/commands/compute/build.go b/pkg/commands/compute/build.go index d26558f05..5870fa4af 100644 --- a/pkg/commands/compute/build.go +++ b/pkg/commands/compute/build.go @@ -113,11 +113,6 @@ func (c *BuildCommand) Exec(in io.Reader, out io.Writer) (err error) { // NOTE: We set the progress indicator to Done() so that any output we now // print doesn't get hidden by the progress status. progress.Done() - - if c.Globals.Verbose() { - text.Break(out) - } - progress = text.ResetProgress(out, c.Globals.Verbose()) postBuildCallback := func() error { diff --git a/pkg/commands/compute/language_toolchain.go b/pkg/commands/compute/language_toolchain.go index 809b765f8..7da00701a 100644 --- a/pkg/commands/compute/language_toolchain.go +++ b/pkg/commands/compute/language_toolchain.go @@ -1,6 +1,7 @@ package compute import ( + "fmt" "io" "os" "time" @@ -12,18 +13,19 @@ import ( // DefaultBuildErrorRemediation is the message returned to a user when there is // a build error. -const DefaultBuildErrorRemediation = `There was an error building your project. +var DefaultBuildErrorRemediation = func() string { + return fmt.Sprintf(`%s: -Here are some steps you can follow to debug the issue: - -- Re-run the fastly subcommand with the --verbose flag to see more information. +- Re-run the fastly command with the --verbose flag to see more information. - Is the required language toolchain (node/npm, rust/cargo etc) installed correctly? - Is the required version (if any) of the language toolchain installed/activated? - Were the required dependencies (package.json, Cargo.toml etc) installed? - Did the build script (see fastly.toml [scripts.build]) produce a ./bin/main.wasm binary file? - Was there a configured [scripts.post_build] step that needs to be double-checked? -For more information on fastly.toml configuration settings, refer to https://developer.fastly.com/reference/compute/fastly-toml/` +For more information on fastly.toml configuration settings, refer to https://developer.fastly.com/reference/compute/fastly-toml/`, + text.BoldYellow("Here are some steps you can follow to debug the issue")) +}() // Toolchain abstracts a Compute@Edge source language toolchain. type Toolchain interface { @@ -49,10 +51,7 @@ type BuildToolchain struct { func (bt BuildToolchain) Build() error { err := bt.execCommand(bt.buildScript) if err != nil { - return fsterr.RemediationError{ - Inner: err, - Remediation: DefaultBuildErrorRemediation, - } + return bt.handleError(err) } // NOTE: internalPostBuildCallback is only used by Rust currently. @@ -62,10 +61,7 @@ func (bt BuildToolchain) Build() error { if bt.internalPostBuildCallback != nil { err := bt.internalPostBuildCallback() if err != nil { - return fsterr.RemediationError{ - Inner: err, - Remediation: DefaultBuildErrorRemediation, - } + return bt.handleError(err) } } @@ -73,10 +69,7 @@ func (bt BuildToolchain) Build() error { // This is because for Rust it needs to move the binary first. _, err = os.Stat("./bin/main.wasm") if err != nil { - return fsterr.RemediationError{ - Inner: err, - Remediation: DefaultBuildErrorRemediation, - } + return bt.handleError(err) } // NOTE: We set the progress indicator to Done() so that any output we now @@ -88,10 +81,7 @@ func (bt BuildToolchain) Build() error { if err = bt.postBuildCallback(); err == nil { err := bt.execCommand(bt.postBuild) if err != nil { - return fsterr.RemediationError{ - Inner: err, - Remediation: DefaultBuildErrorRemediation, - } + return bt.handleError(err) } } } @@ -99,6 +89,20 @@ func (bt BuildToolchain) Build() error { return nil } +func (bt BuildToolchain) handleError(err error) error { + if !bt.verbose { + // We'll use a generic error message if no --verbose flag + err = fmt.Errorf("failed to build project") + } + if bt.verbose { + text.Break(bt.out) + } + return fsterr.RemediationError{ + Inner: err, + Remediation: DefaultBuildErrorRemediation, + } +} + // execCommand opens a sub shell to execute the language build script. func (bt BuildToolchain) execCommand(script string) error { cmd, args := bt.buildFn(script) diff --git a/pkg/exec/exec.go b/pkg/exec/exec.go index 50f44b578..8cc47e59f 100644 --- a/pkg/exec/exec.go +++ b/pkg/exec/exec.go @@ -15,6 +15,9 @@ import ( "github.com/fastly/cli/pkg/threadsafe" ) +// divider is used as separator lines around shell output. +const divider = "--------------------------------------------------------------------------------" + // Streaming models a generic command execution that consumers can use to // execute commands and stream their output to an io.Writer. For example // compute commands can use this to standardize the flow control for each @@ -63,7 +66,7 @@ func (s *Streaming) MonitorSignalsAsync() { func (s *Streaming) Exec() error { if s.Verbose { text.Break(s.Output) - text.Description(s.Output, "Process command", fmt.Sprintf("%s %s", s.Command, strings.Join(s.Args, " "))) + text.Description(s.Output, "Executing command", fmt.Sprintf("%s %s", s.Command, strings.Join(s.Args, " "))) } // Construct the command with given arguments and environment. @@ -109,12 +112,18 @@ func (s *Streaming) Exec() error { } if s.Verbose { output = s.Output + text.Info(output, "Command output:") + text.Output(output, divider) } cmd.Stdout = io.MultiWriter(output, &stdoutBuf) cmd.Stderr = io.MultiWriter(output, &stderrBuf) if err := cmd.Start(); err != nil { + if s.Verbose { + text.Break(output) + text.Output(output, divider) + } return err } @@ -145,9 +154,17 @@ func (s *Streaming) Exec() error { } ctx = fmt.Sprintf(":%s\n\n%s", cmdOutput, err) } + if s.Verbose { + text.Break(output) + text.Output(output, divider) + } return fmt.Errorf("error during execution process%s", ctx) } + if s.Verbose { + text.Break(output) + text.Output(output, divider) + } return nil }