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  }