Skip to content

Commit

Permalink
feat: allow to output on hooks
Browse files Browse the repository at this point in the history
refs #2875
  • Loading branch information
caarlos0 committed Feb 5, 2022
1 parent 482cc64 commit f585f3b
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 29 deletions.
2 changes: 1 addition & 1 deletion internal/pipe/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func runHook(ctx *context.Context, opts builders.Options, buildEnv []string, hoo
return err
}

if err := shell.Run(ctx, dir, cmd, env); err != nil {
if err := shell.Run(ctx, dir, cmd, env, hook.Output); err != nil {
return err
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/pipe/universalbinary/universalbinary.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func runHook(ctx *context.Context, hooks config.Hooks) error {
return err
}

if err := shell.Run(ctx, dir, cmd, envs); err != nil {
if err := shell.Run(ctx, dir, cmd, envs, hook.Output); err != nil {
return err
}
}
Expand Down
9 changes: 5 additions & 4 deletions internal/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"os/exec"
"strings"

"github.com/apex/log"

Expand All @@ -14,7 +15,7 @@ import (
)

// Run a shell command with given arguments and envs
func Run(ctx *context.Context, dir string, command, env []string) error {
func Run(ctx *context.Context, dir string, command, env []string, output bool) error {
fields := log.Fields{
"cmd": command,
"env": env,
Expand All @@ -27,8 +28,8 @@ func Run(ctx *context.Context, dir string, command, env []string) error {
var b bytes.Buffer
w := gio.Safe(&b)

cmd.Stderr = io.MultiWriter(logext.NewWriter(fields, logext.Error), w)
cmd.Stdout = io.MultiWriter(logext.NewWriter(fields, logext.Info), w)
cmd.Stderr = io.MultiWriter(logext.NewConditionalWriter(fields, logext.Error, output), w)
cmd.Stdout = io.MultiWriter(logext.NewConditionalWriter(fields, logext.Info, output), w)

if dir != "" {
cmd.Dir = dir
Expand All @@ -37,7 +38,7 @@ func Run(ctx *context.Context, dir string, command, env []string) error {
log.WithFields(fields).Debug("running")
if err := cmd.Run(); err != nil {
log.WithFields(fields).WithError(err).Debug("failed")
return fmt.Errorf("%q: %w", b.String(), err)
return fmt.Errorf("failed to run '%s': %w", strings.Join(command, " "), err)
}

return nil
Expand Down
48 changes: 28 additions & 20 deletions internal/shell/shell_test.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
package shell_test

import (
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"

"github.com/goreleaser/goreleaser/internal/shell"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
)

func TestRunAValidCommand(t *testing.T) {
assert := assert.New(t)

ctx := context.New(config.Project{})

err := shell.Run(ctx, "", []string{"echo", "test"}, []string{})
assert.NoError(err)
}

func TestRunAnInValidCommand(t *testing.T) {
assert := assert.New(t)

ctx := context.New(config.Project{})

err := shell.Run(ctx, "", []string{"invalid", "command"}, []string{})

assert.Error(err)
assert.Contains(err.Error(), "executable file not found")
func TestRunCommand(t *testing.T) {
t.Run("simple", func(t *testing.T) {
require.NoError(t, shell.Run(context.New(config.Project{}), "", []string{"echo", "oi"}, []string{}, false))
})

t.Run("cmd failed", func(t *testing.T) {
require.EqualError(
t,
shell.Run(context.New(config.Project{}), "", []string{"sh", "-c", "exit 1"}, []string{}, false),
`failed to run 'sh -c exit 1': exit status 1`,
)
})

t.Run("cmd with output", func(t *testing.T) {
require.EqualError(
t,
shell.Run(context.New(config.Project{}), "", []string{"sh", "-c", `echo something; exit 1`}, []string{}, true),
`failed to run 'sh -c echo something; exit 1': exit status 1`,
)
})

t.Run("with env and dir", func(t *testing.T) {
dir := t.TempDir()
require.NoError(t, shell.Run(context.New(config.Project{}), dir, []string{"sh", "-c", "touch $FOO"}, []string{"FOO=bar"}, false))
require.FileExists(t, filepath.Join(dir, "bar"))
})
}
7 changes: 4 additions & 3 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,10 @@ func (bhc Hooks) JSONSchemaType() *jsonschema.Type {
}

type Hook struct {
Dir string `yaml:"dir,omitempty"`
Cmd string `yaml:"cmd,omitempty"`
Env []string `yaml:"env,omitempty"`
Dir string `yaml:"dir,omitempty"`
Cmd string `yaml:"cmd,omitempty"`
Env []string `yaml:"env,omitempty"`
Output bool `yaml:"output,omitempty"`
}

// UnmarshalYAML is a custom unmarshaler that allows simplified declarations of commands as strings.
Expand Down
1 change: 1 addition & 0 deletions www/docs/customization/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ builds:
pre:
- cmd: first-script.sh
dir: "{{ dir .Dist}}"
output: true # always print command output, otherwise only visible in debug mode
env:
- HOOK_SPECIFIC_VAR={{ .Env.GLOBAL_VAR }}
- second-script.sh
Expand Down
1 change: 1 addition & 0 deletions www/docs/customization/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ GoReleaser allows this with the global hooks feature.
- make clean # simple string
- cmd: go generate ./... # specify cmd
- cmd: go mod tidy
output: true # always prints command output
dir: ./submodule # specify command working directory
- cmd: touch {{ .Env.FILE_TO_TOUCH }}
env:
Expand Down

0 comments on commit f585f3b

Please sign in to comment.