github.com/goreleaser/goreleaser@v1.25.1/internal/shell/shell.go (about) 1 package shell 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "os/exec" 8 "strings" 9 10 "github.com/caarlos0/log" 11 "github.com/charmbracelet/x/exp/ordered" 12 "github.com/goreleaser/goreleaser/internal/gio" 13 "github.com/goreleaser/goreleaser/internal/logext" 14 "github.com/goreleaser/goreleaser/pkg/context" 15 ) 16 17 // Run a shell command with given arguments and envs 18 func Run(ctx *context.Context, dir string, command, env []string, output bool) error { 19 log := log. 20 WithField("cmd", command). 21 WithField("dir", dir) 22 23 /* #nosec */ 24 cmd := exec.CommandContext(ctx, command[0], command[1:]...) 25 cmd.Env = env 26 27 var b bytes.Buffer 28 w := gio.Safe(&b) 29 30 cmd.Stderr = io.MultiWriter(logext.NewConditionalWriter(output), w) 31 cmd.Stdout = io.MultiWriter(logext.NewConditionalWriter(output), w) 32 33 if dir != "" { 34 cmd.Dir = dir 35 } 36 37 log.Debug("running") 38 if err := cmd.Run(); err != nil { 39 return fmt.Errorf( 40 "shell: '%s': %w: %s", 41 strings.Join(command, " "), 42 err, 43 ordered.First( 44 strings.TrimSpace(b.String()), 45 "[no output]", 46 ), 47 ) 48 } 49 50 return nil 51 }