1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-02-03 13:11:48 +02:00

fix: run 'go version' command in build.Dir (#2411)

Currently, the 'goVersion' function is run without any directory set.
This is problematic when a build uses the 'dir' config in combination
with the 'gobinary' config. When 'gobinary' is a relative path (like a
script in the current repository), goVersion silently fails, returning
an empty string.

This commit refactors 'goVersion' to execute the command with '.Dir' set
to the 'build.Dir', in addition to now returning an error, so that
issues may be bubbled up in the build log, rather than silently failing.

It also adds a new helper function to facilitate running 'goVersion' by
creating a temporary executable that outputs a given 'version' string.
This function is only currently used by 'TestWithDefaults'.

Co-authored-by: Rob Prentiss <prentiss@apple.com>
This commit is contained in:
Rob Prentiss 2021-08-21 06:56:54 -07:00 committed by GitHub
parent 5e006eb236
commit 013bd69126
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 4 deletions

View File

@ -59,7 +59,11 @@ func (*Builder) WithDefaults(build config.Build) (config.Build, error) {
if len(build.Gomips) == 0 { if len(build.Gomips) == 0 {
build.Gomips = []string{"hardfloat"} build.Gomips = []string{"hardfloat"}
} }
targets, err := matrix(build, goVersion(build)) version, err := goVersion(build)
if err != nil {
return build, err
}
targets, err := matrix(build, version)
build.Targets = targets build.Targets = targets
if err != nil { if err != nil {
return build, err return build, err

View File

@ -90,6 +90,9 @@ func TestWithDefaults(t *testing.T) {
}, },
} { } {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
if testcase.build.GoBinary != "" && testcase.build.GoBinary != "go" {
helperCreateGoVersionExe(t, testcase.build.GoBinary, "go1.17")
}
config := config.Project{ config := config.Project{
Builds: []config.Build{ Builds: []config.Build{
testcase.build, testcase.build,
@ -105,6 +108,29 @@ func TestWithDefaults(t *testing.T) {
} }
} }
// helperCreateGoVersionExe creates a temporary executable with the given 'name', which will output
// a 'go version' string with the given 'version'. The temporary directory created by this function
// will be placed in the PATH variable for the duration of (and cleaned up at the end of) the
// current test run.
func helperCreateGoVersionExe(t *testing.T, name, version string) {
t.Helper()
d := t.TempDir()
f, err := os.Create(filepath.Join(d, name))
if err != nil {
t.Fatalf("unable to create temporary GoBinary file for testing: %v", err)
}
fmt.Fprintf(f, "#!/bin/sh\necho \"go version %s %s/%s\"\n", version, runtime.GOOS, runtime.GOARCH)
if err := f.Chmod(0o0755); err != nil {
t.Fatalf("unable to create temporary GoBinary file for testing: %v", err)
}
if err := f.Close(); err != nil {
t.Fatalf("unable to create temporary GoBinary file for testing: %v", err)
}
currentPath := os.Getenv("PATH")
t.Cleanup(func() { os.Setenv("PATH", currentPath) })
os.Setenv("PATH", fmt.Sprintf("%s%c%s", d, os.PathListSeparator, currentPath))
}
func TestInvalidTargets(t *testing.T) { func TestInvalidTargets(t *testing.T) {
type testcase struct { type testcase struct {
build config.Build build config.Build

View File

@ -131,9 +131,14 @@ var (
go117re = regexp.MustCompile(`go version go1.1[7-9]`) go117re = regexp.MustCompile(`go version go1.1[7-9]`)
) )
func goVersion(build config.Build) []byte { func goVersion(build config.Build) ([]byte, error) {
bts, _ := exec.Command(build.GoBinary, "version").CombinedOutput() cmd := exec.Command(build.GoBinary, "version")
return bts cmd.Dir = build.Dir // Set Dir to build directory in case of reletive path to GoBinary
bts, err := cmd.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("unable to determine version of go binary (%s): %w", build.GoBinary, err)
}
return bts, nil
} }
func valid(target target) bool { func valid(target target) bool {

View File

@ -330,6 +330,15 @@ func TestDefaultPartialBuilds(t *testing.T) {
}, },
}, },
} }
// Create any 'Dir' paths necessary for builds.
cwd, _ := os.Getwd()
t.Cleanup(func() { os.Chdir(cwd) })
os.Chdir(t.TempDir())
for _, b := range ctx.Config.Builds {
if b.Dir != "" {
os.Mkdir(b.Dir, 0o755)
}
}
require.NoError(t, Pipe{}.Default(ctx)) require.NoError(t, Pipe{}.Default(ctx))
t.Run("build0", func(t *testing.T) { t.Run("build0", func(t *testing.T) {
build := ctx.Config.Builds[0] build := ctx.Config.Builds[0]