github.com/triarius/goreleaser@v1.12.5/internal/pipe/before/before.go (about) 1 // Package before provides the pipe implementation that runs before all other pipes. 2 package before 3 4 import ( 5 "bytes" 6 "fmt" 7 "io" 8 "os/exec" 9 10 "github.com/caarlos0/go-shellwords" 11 "github.com/caarlos0/log" 12 "github.com/triarius/goreleaser/internal/gio" 13 "github.com/triarius/goreleaser/internal/logext" 14 "github.com/triarius/goreleaser/internal/tmpl" 15 "github.com/triarius/goreleaser/pkg/context" 16 ) 17 18 // Pipe is a global hook pipe. 19 type Pipe struct{} 20 21 func (Pipe) String() string { return "running before hooks" } 22 func (Pipe) Skip(ctx *context.Context) bool { 23 return len(ctx.Config.Before.Hooks) == 0 || ctx.SkipBefore 24 } 25 26 // Run executes the hooks. 27 func (Pipe) Run(ctx *context.Context) error { 28 tmpl := tmpl.New(ctx) 29 /* #nosec */ 30 for _, step := range ctx.Config.Before.Hooks { 31 s, err := tmpl.Apply(step) 32 if err != nil { 33 return err 34 } 35 args, err := shellwords.Parse(s) 36 if err != nil { 37 return err 38 } 39 40 cmd := exec.Command(args[0], args[1:]...) 41 cmd.Env = ctx.Env.Strings() 42 43 var b bytes.Buffer 44 w := gio.Safe(&b) 45 fields := log.Fields{"hook": step} 46 cmd.Stderr = io.MultiWriter(logext.NewWriter(fields, logext.Error), w) 47 cmd.Stdout = io.MultiWriter(logext.NewWriter(fields, logext.Info), w) 48 49 log.WithFields(fields).Info("running") 50 if err := cmd.Run(); err != nil { 51 return fmt.Errorf("hook failed: %s: %w; output: %s", step, err, b.String()) 52 } 53 } 54 return nil 55 }