diff --git a/internal/builders/golang/build.go b/internal/builders/golang/build.go index 604b6ebbd..49826fba7 100644 --- a/internal/builders/golang/build.go +++ b/internal/builders/golang/build.go @@ -59,7 +59,11 @@ func (*Builder) WithDefaults(build config.Build) (config.Build, error) { if len(build.Gomips) == 0 { 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 if err != nil { return build, err diff --git a/internal/builders/golang/build_test.go b/internal/builders/golang/build_test.go index d394acd0d..0ece15a5f 100644 --- a/internal/builders/golang/build_test.go +++ b/internal/builders/golang/build_test.go @@ -90,6 +90,9 @@ func TestWithDefaults(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{ Builds: []config.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) { type testcase struct { build config.Build diff --git a/internal/builders/golang/targets.go b/internal/builders/golang/targets.go index dd6589840..2f93152ef 100644 --- a/internal/builders/golang/targets.go +++ b/internal/builders/golang/targets.go @@ -131,9 +131,14 @@ var ( go117re = regexp.MustCompile(`go version go1.1[7-9]`) ) -func goVersion(build config.Build) []byte { - bts, _ := exec.Command(build.GoBinary, "version").CombinedOutput() - return bts +func goVersion(build config.Build) ([]byte, error) { + cmd := exec.Command(build.GoBinary, "version") + 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 { diff --git a/internal/pipe/build/build_test.go b/internal/pipe/build/build_test.go index 8514dc1b8..a0c3a0600 100644 --- a/internal/pipe/build/build_test.go +++ b/internal/pipe/build/build_test.go @@ -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)) t.Run("build0", func(t *testing.T) { build := ctx.Config.Builds[0]