Skip to content

Commit

Permalink
Skip exit code 1 for 'help' output (#689)
Browse files Browse the repository at this point in the history
* skip help error output

* rename error type
  • Loading branch information
Integralist authored Oct 20, 2022
1 parent 8bbc210 commit 3c5384c
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 8 deletions.
13 changes: 11 additions & 2 deletions cmd/fastly/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package main

import (
"errors"
"io"
"log"
"net/http"
Expand Down Expand Up @@ -142,12 +143,20 @@ func main() {
}

if err != nil {
fsterr.Deduce(err).Print(color.Error)

// NOTE: os.Exit doesn't honour any deferred calls so we have to manually
// flush the Sentry buffer here (as well as the deferred call at the top of
// the main function).
sentry.Flush(sentryTimeout)

fsterr.Deduce(err).Print(color.Error)

exitError := fsterr.SkipExitError{}
if errors.As(err, &exitError) {
if exitError.Skip {
return // skip returning an error for 'help' output
}
}

os.Exit(1)
}
}
Expand Down
24 changes: 19 additions & 5 deletions pkg/app/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,10 @@ func processCommandInput(
var vars map[string]any

if cmd.IsHelpFlagOnly(opts.Args) && len(opts.Args) == 1 {
return command, cmdName, help(vars, nil)
return command, cmdName, fsterr.SkipExitError{
Skip: true,
Err: help(vars, nil),
}
}

// NOTE: We call two similar methods below: ParseContext() and Parse().
Expand Down Expand Up @@ -299,7 +302,10 @@ func processCommandInput(
}

if cmd.ContextHasHelpFlag(ctx) && !cmd.IsHelpFlagOnly(opts.Args) {
return command, cmdName, help(vars, nil)
return command, cmdName, fsterr.SkipExitError{
Skip: true,
Err: help(vars, nil),
}
}

// NOTE: app.Parse() resets the default values for app.Writers() from
Expand Down Expand Up @@ -348,7 +354,7 @@ func processCommandInput(
if cmdName == "help" {
var buf bytes.Buffer
app.Writers(&buf, io.Discard)
app.Parse(opts.Args)
_, _ = app.Parse(opts.Args)
app.Writers(opts.Stdout, io.Discard)

// The full-fat output of `fastly help` should have a hint at the bottom
Expand All @@ -362,13 +368,21 @@ func processCommandInput(
fmt.Fprintln(&buf, "")
}

return command, cmdName, fsterr.RemediationError{Prefix: buf.String()}
return command, cmdName, fsterr.SkipExitError{
Skip: true,
Err: fsterr.RemediationError{
Prefix: buf.String(),
},
}
}

// Catch scenario where user wants to view help with the following format:
// fastly --help <command>
if cmd.IsHelpFlagOnly(opts.Args) {
return command, cmdName, help(vars, nil)
return command, cmdName, fsterr.SkipExitError{
Skip: true,
Err: help(vars, nil),
}
}

return command, cmdName, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/commands/compute/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ func TestBuildGo(t *testing.T) {
// NOTE: The following constraints should be kept in-sync with
// ./pkg/config/config.toml
opts.ConfigFile.Language.Go.TinyGoConstraint = ">= 0.24.0-0" // NOTE: -0 is to allow prereleases.
opts.ConfigFile.Language.Go.ToolchainConstraint = ">= 1.17 < 1.19"
opts.ConfigFile.Language.Go.ToolchainConstraint = ">= 1.17"

err = app.Run(opts)

Expand Down
36 changes: 36 additions & 0 deletions pkg/errors/exit_error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package errors

import (
"io"

"github.com/fastly/cli/pkg/text"
)

// SkipExitError is an error that can cause the os.Exit(1) to be skipped.
// An example is 'help' output (e.g. --help).
type SkipExitError struct {
Skip bool
Err error
}

// Unwrap returns the inner error.
func (ee SkipExitError) Unwrap() error {
return ee.Err
}

// Error prints the inner error string.
func (ee SkipExitError) Error() string {
if ee.Err == nil {
return ""
}
return ee.Err.Error()
}

// Print the error to the io.Writer for human consumption.
// The inner error is always printed via text.Output with an "Error: " prefix
// and a "." suffix.
func (ee SkipExitError) Print(w io.Writer) {
if ee.Err != nil {
text.Error(w, "%s.", ee.Err.Error())
}
}

0 comments on commit 3c5384c

Please sign in to comment.