github.com/goreleaser/goreleaser@v1.25.1/internal/pipe/gomod/gomod.go (about)

     1  package gomod
     2  
     3  import (
     4  	"fmt"
     5  	"os/exec"
     6  	"strings"
     7  
     8  	"github.com/goreleaser/goreleaser/internal/pipe"
     9  	"github.com/goreleaser/goreleaser/pkg/context"
    10  )
    11  
    12  const (
    13  	goPreModulesError      = "flag provided but not defined: -m"
    14  	go115NotAGoModuleError = "go list -m: not using modules"
    15  	go116NotAGoModuleError = "command-line-arguments"
    16  )
    17  
    18  // Pipe for gomod.
    19  type Pipe struct{}
    20  
    21  func (Pipe) String() string { return "loading go mod information" }
    22  
    23  // Default sets the pipe defaults.
    24  func (Pipe) Default(ctx *context.Context) error {
    25  	if ctx.Config.GoMod.GoBinary == "" {
    26  		ctx.Config.GoMod.GoBinary = "go"
    27  	}
    28  	return nil
    29  }
    30  
    31  // Run the pipe.
    32  func (Pipe) Run(ctx *context.Context) error {
    33  	flags := []string{"list", "-m"}
    34  	if ctx.Config.GoMod.Mod != "" {
    35  		flags = append(flags, "-mod="+ctx.Config.GoMod.Mod)
    36  	}
    37  	cmd := exec.CommandContext(ctx, ctx.Config.GoMod.GoBinary, flags...)
    38  	cmd.Env = append(ctx.Env.Strings(), ctx.Config.GoMod.Env...)
    39  	if dir := ctx.Config.GoMod.Dir; dir != "" {
    40  		cmd.Dir = dir
    41  	}
    42  	out, err := cmd.CombinedOutput()
    43  	result := strings.TrimSpace(string(out))
    44  	if strings.HasPrefix(result, goPreModulesError) {
    45  		return pipe.Skip("go version does not support modules")
    46  	}
    47  	if result == go115NotAGoModuleError || result == go116NotAGoModuleError {
    48  		return pipe.Skip("not a go module")
    49  	}
    50  	if err != nil {
    51  		return fmt.Errorf("failed to get module path: %w: %s", err, string(out))
    52  	}
    53  
    54  	// Splits and use the first line in case a `go.work` file exists with multiple modules.
    55  	// The first module is/should be `.` in the `go.work` file, so this should be correct.
    56  	// Running `go work sync` also always puts `.` as the first line in `use`.
    57  	ctx.ModulePath = strings.Split(result, "\n")[0]
    58  	return nil
    59  }