Skip to content

Commit

Permalink
fix: better shellwords on hooks (#1437)
Browse files Browse the repository at this point in the history
Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
  • Loading branch information
caarlos0 committed Apr 12, 2020
1 parent 8032d12 commit 34c8fd4
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 3 deletions.
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -14,6 +14,7 @@ require (
github.com/goreleaser/nfpm v1.2.1
github.com/imdario/mergo v0.3.9
github.com/jarcoal/httpmock v1.0.5
github.com/mattn/go-shellwords v1.0.10
github.com/mattn/go-zglob v0.0.1
github.com/mitchellh/go-homedir v1.1.0
github.com/pkg/errors v0.9.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -172,6 +172,8 @@ github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-zglob v0.0.1 h1:xsEx/XUoVlI6yXjqBK062zYhRTZltCNmYPx6v+8DNaY=
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
Expand Down
7 changes: 5 additions & 2 deletions internal/pipe/before/before.go
Expand Up @@ -3,12 +3,12 @@ package before
import (
"fmt"
"os/exec"
"strings"

"github.com/apex/log"
"github.com/fatih/color"
"github.com/goreleaser/goreleaser/internal/tmpl"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/mattn/go-shellwords"
)

// Pipe is a global hook pipe
Expand All @@ -28,7 +28,10 @@ func (Pipe) Run(ctx *context.Context) error {
if err != nil {
return err
}
args := strings.Fields(s)
args, err := shellwords.Parse(s)
if err != nil {
return err
}
log.Infof("running %s", color.CyanString(step))
cmd := exec.Command(args[0], args[1:]...)
cmd.Env = ctx.Env.Strings()
Expand Down
16 changes: 16 additions & 0 deletions internal/pipe/before/before_test.go
Expand Up @@ -20,6 +20,7 @@ func TestRunPipe(t *testing.T) {
{},
{"go version"},
{"go version", "go list"},
{`bash -c "go version; echo \"lala spaces and such\""`},
} {
ctx := context.New(
config.Project{
Expand All @@ -32,6 +33,21 @@ func TestRunPipe(t *testing.T) {
}
}

func TestRunPipeInvalidCommand(t *testing.T) {
for _, tc := range [][]string{
{`bash -c "echo \"unterminated command\"`},
} {
ctx := context.New(
config.Project{
Before: config.Before{
Hooks: tc,
},
},
)
require.Error(t, Pipe{}.Run(ctx))
}
}

func TestRunPipeFail(t *testing.T) {
for _, tc := range [][]string{
{"go tool foobar"},
Expand Down
6 changes: 5 additions & 1 deletion internal/pipe/build/build.go
Expand Up @@ -16,6 +16,7 @@ import (
builders "github.com/goreleaser/goreleaser/pkg/build"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/mattn/go-shellwords"
"github.com/pkg/errors"

// langs to init
Expand Down Expand Up @@ -134,7 +135,10 @@ func runHook(ctx *context.Context, opts builders.Options, buildEnv []string, hoo
}

log.WithField("hook", sh).Info("running hook")
cmd := strings.Fields(sh)
cmd, err := shellwords.Parse(sh)
if err != nil {
return err
}

if err := run(ctx, dir, cmd, env); err != nil {
return err
Expand Down
26 changes: 26 additions & 0 deletions internal/pipe/build/build_test.go
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

var fakeArtifact = &artifact.Artifact{
Expand Down Expand Up @@ -668,3 +669,28 @@ func TestBuildOptionsForTarget(t *testing.T) {
Target: "linux_amd64",
}, opts)
}

func TestHookComplex(t *testing.T) {
tmp, back := testlib.Mktmp(t)
defer back()

require.NoError(t, runHook(context.New(config.Project{}), api.Options{}, []string{}, config.BuildHooks{
{
Cmd: `bash -c "touch foo"`,
},
{
Cmd: `bash -c "touch \"bar\""`,
},
}))

require.FileExists(t, filepath.Join(tmp, "foo"))
require.FileExists(t, filepath.Join(tmp, "bar"))
}

func TestHookInvalidShelCommand(t *testing.T) {
require.Error(t, runHook(context.New(config.Project{}), api.Options{}, []string{}, config.BuildHooks{
{
Cmd: `bash -c "echo \"unterminated command\"`,
},
}))
}

0 comments on commit 34c8fd4

Please sign in to comment.