diff --git a/internal/pipe/build/build.go b/internal/pipe/build/build.go index a0972b2b0..b4f993dc3 100644 --- a/internal/pipe/build/build.go +++ b/internal/pipe/build/build.go @@ -97,8 +97,13 @@ func runHook(ctx *context.Context, env []string, hook string) error { if hook == "" { return nil } - log.WithField("hook", hook).Info("running hook") - cmd := strings.Fields(hook) + sh, err := tmpl.New(ctx).WithEnvS(env).Apply(hook) + if err != nil { + return err + } + log.WithField("hook", sh).Info("running hook") + cmd := strings.Fields(sh) + env = append(env, ctx.Env.Strings()...) return run(ctx, cmd, env) } diff --git a/internal/pipe/build/build_test.go b/internal/pipe/build/build_test.go index 3e81eff44..bb55a11c1 100644 --- a/internal/pipe/build/build_test.go +++ b/internal/pipe/build/build_test.go @@ -2,6 +2,8 @@ package build import ( "errors" + "fmt" + "io/ioutil" "os" "path/filepath" "testing" @@ -325,6 +327,51 @@ func TestTemplate(t *testing.T) { assert.Contains(t, binary, `-X "main.foo=123"`) } +func TestHookEnvs(t *testing.T) { + tmp, back := testlib.Mktmp(t) + defer back() + + var build = config.Build{ + Env: []string{ + fmt.Sprintf("FOO=%s/foo", tmp), + fmt.Sprintf("BAR=%s/bar", tmp), + }, + } + + t.Run("valid template", func(t *testing.T) { + var err = runHook(context.New(config.Project{ + Builds: []config.Build{ + build, + }, + }), build.Env, "touch {{ .Env.FOO }}") + assert.NoError(t, err) + assert.True(t, exists(filepath.Join(tmp, "foo"))) + }) + + t.Run("invalid template", func(t *testing.T) { + var err = runHook(context.New(config.Project{ + Builds: []config.Build{ + build, + }, + }), build.Env, "touch {{ .Env.FOOss }}") + assert.EqualError(t, err, `template: tmpl:1:13: executing "tmpl" at <.Env.FOOss>: map has no entry for key "FOOss"`) + }) + + t.Run("env inside shell", func(t *testing.T) { + t.Skip("this fails on travis for some reason") + var shell = `#!/bin/sh -e +touch "$BAR"` + ioutil.WriteFile(filepath.Join(tmp, "test.sh"), []byte(shell), 0750) + var err = runHook(context.New(config.Project{ + Builds: []config.Build{ + build, + }, + }), build.Env, "sh test.sh") + assert.NoError(t, err) + assert.True(t, exists(filepath.Join(tmp, "bar"))) + }) +} + // // Helpers // diff --git a/www/content/build.md b/www/content/build.md index 8efde01dc..8167d3cc8 100644 --- a/www/content/build.md +++ b/www/content/build.md @@ -92,6 +92,7 @@ builds: # Hooks can be used to customize the final binary, # for example, to run generators. + # Those fields allow templates. # Default is both hooks empty. hooks: pre: rice embed-go