diff --git a/internal/pipe/before/before.go b/internal/pipe/before/before.go index a8fd3dd69fe..5947810e8bc 100644 --- a/internal/pipe/before/before.go +++ b/internal/pipe/before/before.go @@ -2,15 +2,11 @@ package before import ( - "bytes" "fmt" - "io" - "os/exec" "github.com/caarlos0/go-shellwords" "github.com/caarlos0/log" - "github.com/goreleaser/goreleaser/internal/gio" - "github.com/goreleaser/goreleaser/internal/logext" + "github.com/goreleaser/goreleaser/internal/shell" "github.com/goreleaser/goreleaser/internal/skips" "github.com/goreleaser/goreleaser/internal/tmpl" "github.com/goreleaser/goreleaser/pkg/context" @@ -39,17 +35,9 @@ func (Pipe) Run(ctx *context.Context) error { return err } - cmd := exec.Command(args[0], args[1:]...) - cmd.Env = ctx.Env.Strings() - - var b bytes.Buffer - w := gio.Safe(&b) - cmd.Stderr = io.MultiWriter(logext.NewWriter(), w) - cmd.Stdout = io.MultiWriter(logext.NewWriter(), w) - - log.WithField("hook", step).Info("running") - if err := cmd.Run(); err != nil { - return fmt.Errorf("hook failed: %s: %w; output: %s", step, err, b.String()) + log.WithField("hook", s).Info("running") + if err := shell.Run(ctx, "", args, ctx.Env.Strings(), false); err != nil { + return fmt.Errorf("hook failed: %w", err) } } return nil diff --git a/internal/pipe/before/before_test.go b/internal/pipe/before/before_test.go index e0183f38977..0cb4a202912 100644 --- a/internal/pipe/before/before_test.go +++ b/internal/pipe/before/before_test.go @@ -55,8 +55,8 @@ func TestRunPipeInvalidCommand(t *testing.T) { func TestRunPipeFail(t *testing.T) { for err, tc := range map[string][]string{ - "hook failed: go tool foobar: exit status 2; output: go: no such tool \"foobar\"\n": {"go tool foobar"}, - "hook failed: sh ./testdata/foo.sh: exit status 1; output: lalala\n": {"sh ./testdata/foo.sh"}, + "hook failed: shell: 'go tool foobar': exit status 2: go: no such tool \"foobar\"\n": {"go tool foobar"}, + "hook failed: shell: 'sh ./testdata/foo.sh': exit status 1: lalala\n": {"sh ./testdata/foo.sh"}, } { ctx := testctx.NewWithCfg( config.Project{ diff --git a/internal/shell/shell.go b/internal/shell/shell.go index f70d3ca6bc0..a879dd19bad 100644 --- a/internal/shell/shell.go +++ b/internal/shell/shell.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/caarlos0/log" + "github.com/charmbracelet/x/exp/ordered" "github.com/goreleaser/goreleaser/internal/gio" "github.com/goreleaser/goreleaser/internal/logext" "github.com/goreleaser/goreleaser/pkg/context" @@ -17,7 +18,8 @@ import ( func Run(ctx *context.Context, dir string, command, env []string, output bool) error { log := log. WithField("cmd", command). - WithField("env", env) + WithField("env", env). + WithField("dir", dir) /* #nosec */ cmd := exec.CommandContext(ctx, command[0], command[1:]...) @@ -35,8 +37,15 @@ func Run(ctx *context.Context, dir string, command, env []string, output bool) e log.Debug("running") if err := cmd.Run(); err != nil { - log.WithError(err).Debug("failed") - return fmt.Errorf("failed to run '%s': %w", strings.Join(command, " "), err) + return fmt.Errorf( + "shell: '%s': %w: %s", + strings.Join(command, " "), + err, + ordered.First( + strings.TrimSpace(b.String()), + "[no output]", + ), + ) } return nil diff --git a/internal/shell/shell_test.go b/internal/shell/shell_test.go index 7649a20998a..3f2f3e9f187 100644 --- a/internal/shell/shell_test.go +++ b/internal/shell/shell_test.go @@ -18,7 +18,7 @@ func TestRunCommand(t *testing.T) { require.EqualError( t, shell.Run(testctx.New(), "", []string{"sh", "-c", "exit 1"}, []string{}, false), - `failed to run 'sh -c exit 1': exit status 1`, + `shell: 'sh -c exit 1': exit status 1: [no output]`, ) }) @@ -26,7 +26,7 @@ func TestRunCommand(t *testing.T) { require.EqualError( t, shell.Run(testctx.New(), "", []string{"sh", "-c", `echo something; exit 1`}, []string{}, true), - `failed to run 'sh -c echo something; exit 1': exit status 1`, + `shell: 'sh -c echo something; exit 1': exit status 1: something`, ) })