1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-04-15 11:56:56 +02:00

feat: improve project and build hooks error handling

closes #4451
This commit is contained in:
Carlos Alexandro Becker 2023-11-29 22:01:13 -03:00
parent d89557b277
commit bd7933d185
No known key found for this signature in database
GPG Key ID: E61E2F7DC14AB940
4 changed files with 20 additions and 23 deletions

View File

@ -2,15 +2,11 @@
package before package before
import ( import (
"bytes"
"fmt" "fmt"
"io"
"os/exec"
"github.com/caarlos0/go-shellwords" "github.com/caarlos0/go-shellwords"
"github.com/caarlos0/log" "github.com/caarlos0/log"
"github.com/goreleaser/goreleaser/internal/gio" "github.com/goreleaser/goreleaser/internal/shell"
"github.com/goreleaser/goreleaser/internal/logext"
"github.com/goreleaser/goreleaser/internal/skips" "github.com/goreleaser/goreleaser/internal/skips"
"github.com/goreleaser/goreleaser/internal/tmpl" "github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context" "github.com/goreleaser/goreleaser/pkg/context"
@ -39,17 +35,9 @@ func (Pipe) Run(ctx *context.Context) error {
return err return err
} }
cmd := exec.Command(args[0], args[1:]...) log.WithField("hook", s).Info("running")
cmd.Env = ctx.Env.Strings() if err := shell.Run(ctx, "", args, ctx.Env.Strings(), false); err != nil {
return fmt.Errorf("hook failed: %w", err)
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())
} }
} }
return nil return nil

View File

@ -55,8 +55,8 @@ func TestRunPipeInvalidCommand(t *testing.T) {
func TestRunPipeFail(t *testing.T) { func TestRunPipeFail(t *testing.T) {
for err, tc := range map[string][]string{ 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: shell: 'go tool foobar': exit status 2: 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: 'sh ./testdata/foo.sh': exit status 1: lalala\n": {"sh ./testdata/foo.sh"},
} { } {
ctx := testctx.NewWithCfg( ctx := testctx.NewWithCfg(
config.Project{ config.Project{

View File

@ -8,6 +8,7 @@ import (
"strings" "strings"
"github.com/caarlos0/log" "github.com/caarlos0/log"
"github.com/charmbracelet/x/exp/ordered"
"github.com/goreleaser/goreleaser/internal/gio" "github.com/goreleaser/goreleaser/internal/gio"
"github.com/goreleaser/goreleaser/internal/logext" "github.com/goreleaser/goreleaser/internal/logext"
"github.com/goreleaser/goreleaser/pkg/context" "github.com/goreleaser/goreleaser/pkg/context"
@ -17,7 +18,8 @@ import (
func Run(ctx *context.Context, dir string, command, env []string, output bool) error { func Run(ctx *context.Context, dir string, command, env []string, output bool) error {
log := log. log := log.
WithField("cmd", command). WithField("cmd", command).
WithField("env", env) WithField("env", env).
WithField("dir", dir)
/* #nosec */ /* #nosec */
cmd := exec.CommandContext(ctx, command[0], command[1:]...) 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") log.Debug("running")
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
log.WithError(err).Debug("failed") return fmt.Errorf(
return fmt.Errorf("failed to run '%s': %w", strings.Join(command, " "), err) "shell: '%s': %w: %s",
strings.Join(command, " "),
err,
ordered.First(
strings.TrimSpace(b.String()),
"[no output]",
),
)
} }
return nil return nil

View File

@ -18,7 +18,7 @@ func TestRunCommand(t *testing.T) {
require.EqualError( require.EqualError(
t, t,
shell.Run(testctx.New(), "", []string{"sh", "-c", "exit 1"}, []string{}, false), 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( require.EqualError(
t, t,
shell.Run(testctx.New(), "", []string{"sh", "-c", `echo something; exit 1`}, []string{}, true), 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`,
) )
}) })