diff --git a/const.go b/const.go index 8066c5b..aeae6aa 100644 --- a/const.go +++ b/const.go @@ -1,5 +1,9 @@ package main +const ( + gobin = "go" +) + const ( flagNameRace = "race" flagNameMSAN = "msan" diff --git a/constraints.go b/constraints.go new file mode 100644 index 0000000..886f6de --- /dev/null +++ b/constraints.go @@ -0,0 +1,97 @@ +package main + +import "github.com/hashicorp/go-version" + +var ( + flagConstraints map[string]version.Constraints + platformConstraints []PlatformConstraint + experimentConstraints map[string]version.Constraints +) + +// Parse all of the constraints as efficiently as possible. +func init() { + var ( + ok bool + constraint version.Constraints + err error + ) + + parsed := map[string]version.Constraints{} + + flagConstraints = map[string]version.Constraints{} + + flagConstraintsInputs := []struct { + name string + constraint string + }{ + {"C", ">= 1.20"}, + {flagNameASAN, ">= 1.18"}, + {flagNameCover, ">= 1.20"}, + {flagNameCoverPKG, ">= 1.20"}, + {flagNameBuildVCS, ">= 1.18"}, + {flagNameModCacheRW, ">= 1.14"}, + {flagNameMod, ">= 1.11"}, + {flagNameModFile, ">= 1.14"}, + {flagNameOverlay, ">= 1.16"}, + {flagNameProfileGuidedOptimization, ">= 1.20"}, + {flagNameTrimPath, ">= 1.13"}, + } + + for _, input := range flagConstraintsInputs { + if constraint, ok = parsed[input.constraint]; ok { + flagConstraints[input.name] = constraint + + continue + } + + if constraint, err = version.NewConstraint(input.constraint); err != nil { + panic(err) + } + + flagConstraints[input.name] = constraint + parsed[input.constraint] = constraint + } + + platformConstraintsInputs := []struct { + constraint string + platforms []Platform + }{ + {"<= 1.0", Platforms_1_0}, + {">= 1.1, < 1.3", Platforms_1_1}, + {">= 1.3, < 1.4", Platforms_1_3}, + {">= 1.4, < 1.5", Platforms_1_4}, + {">= 1.5, < 1.6", Platforms_1_5}, + {">= 1.6, < 1.7", Platforms_1_6}, + {">= 1.7, < 1.8", Platforms_1_7}, + {">= 1.8, < 1.9", Platforms_1_8}, + {">= 1.9, < 1.10", Platforms_1_9}, + {">= 1.10, < 1.11", Platforms_1_10}, + {">= 1.11, < 1.12", Platforms_1_11}, + {">= 1.12, < 1.13", Platforms_1_12}, + {">= 1.13, < 1.14", Platforms_1_13}, + {">= 1.14, < 1.15", Platforms_1_14}, + {">= 1.15, < 1.16", Platforms_1_15}, + {">= 1.16, < 1.17", Platforms_1_16}, + {">= 1.17, < 1.18", Platforms_1_17}, + {">= 1.18, < 1.19", Platforms_1_18}, + {">= 1.19, < 1.20", Platforms_1_19}, + {">= 1.20, < 1.21", Platforms_1_20}, + } + + platformConstraints = make([]PlatformConstraint, len(platformConstraintsInputs)) + + for i, input := range platformConstraintsInputs { + if constraint, ok = parsed[input.constraint]; ok { + platformConstraints[i] = PlatformConstraint{Constraints: constraint, Platforms: input.platforms} + + continue + } + + if constraint, err = version.NewConstraint(input.constraint); err != nil { + panic(err) + } + + platformConstraints[i] = PlatformConstraint{Constraints: constraint, Platforms: input.platforms} + parsed[input.constraint] = constraint + } +} diff --git a/go.go b/go.go index 93b5008..0c9769b 100644 --- a/go.go +++ b/go.go @@ -21,17 +21,6 @@ type OutputTemplateData struct { // GoCrossCompile func GoCrossCompile(opts *CompileOpts) error { - env := append(os.Environ(), - "GOOS="+opts.Platform.OS, - "GOARCH="+opts.Platform.Arch) - - if opts.Cc != "" { - env = append(env, "CC="+opts.Cc) - } - if opts.Cxx != "" { - env = append(env, "CXX="+opts.Cxx) - } - // If we're building for our own platform, then enable cgo always. We // respect the CGO_ENABLED flag if that is explicitly set on the platform. if !opts.Cgo && os.Getenv("CGO_ENABLED") != "0" { @@ -39,13 +28,6 @@ func GoCrossCompile(opts *CompileOpts) error { runtime.GOARCH == opts.Platform.Arch } - // If cgo is enabled then set that env var - if opts.Cgo { - env = append(env, "CGO_ENABLED=1") - } else { - env = append(env, "CGO_ENABLED=0") - } - var outputPath bytes.Buffer tpl, err := template.New("output").Parse(opts.OutputTpl) if err != nil { @@ -98,75 +80,15 @@ func GoCrossCompile(opts *CompileOpts) error { opts.PackagePath = "" } - args := []string{"build"} - - if opts.Rebuild { - args = append(args, "-a") - } - - if opts.TrimPath { - args = append(args, "-trimpath") - } - - if opts.ModMode != "" { - args = append(args, fmtFlag("mod", opts.ModMode)) - } - - if opts.BuildMode != "" { - args = append(args, fmtFlag("buildmode", opts.BuildMode)) - } - - if opts.BuildVCS != "" { - args = append(args, fmtFlag("buildvcs", opts.BuildVCS)) - } - - if opts.Compiler != "" { - args = append(args, fmtFlag("-compiler", opts.Compiler)) - } - - if opts.Race { - args = append(args, "-race") - } - - if opts.GcFlags != "" { - args = append(args, fmtFlagSpaceSeparated("gcflags", opts.GcFlags)) - } - - if opts.GcCGOFlags != "" { - args = append(args, fmtFlagSpaceSeparated("gccgoflags", opts.GcCGOFlags)) - } - - if opts.LDFlags != "" { - args = append(args, fmtFlagSpaceSeparated("ldflags", opts.LDFlags)) - } - - if opts.ASMFlags != "" { - args = append(args, fmtFlagSpaceSeparated("asmflags", opts.ASMFlags)) - } - - if opts.Tags != "" { - args = append(args, fmt.Sprintf("-tags=%s", opts.Tags)) - } + args := append([]string{"build"}, opts.Arguments()...) args = append(args, "-o", outputPathReal, opts.PackagePath) - _, err = execGo(opts.GoCmd, env, chdir, args...) + _, err = execGo(opts.GoCmd, opts.Env(), chdir, args...) return err } -func fmtFlag(name, value string) string { - return fmt.Sprintf(`-%s=%s`, name, value) -} - -func fmtFlagSpaceSeparated(name, value string) string { - if strings.Contains(value, " ") && value[0] != '"' { - return fmt.Sprintf(`-%s="%s"`, name, value) - } - - return fmt.Sprintf(`-%s=%s`, name, value) -} - // GoMainDirs returns the file paths to the packages that are "main" // packages, from the list of packages given. The list of packages can // include relative paths, the special "..." Go keyword, etc. @@ -202,7 +124,7 @@ func GoMainDirs(packages []string, GoCmd string) ([]string, error) { // GoRoot returns the GOROOT value for the compiled `go` binary. func GoRoot() (string, error) { - output, err := execGo("go", nil, "", "env", "GOROOT") + output, err := execGo(gobin, nil, "", "env", "GOROOT") if err != nil { return "", err } @@ -231,7 +153,7 @@ func GoVersion() (string, error) { } // Execute and read the version, which will be the only thing on stdout. - version, err := execGo("go", nil, "", "run", sourcePath) + version, err := execGo(gobin, nil, "", "run", sourcePath) fmt.Printf("Detected Go Version: %s\n", version) diff --git a/go.mod b/go.mod index 35bdc51..508a449 100644 --- a/go.mod +++ b/go.mod @@ -5,4 +5,11 @@ go 1.20 require ( github.com/hashicorp/go-version v1.6.0 github.com/mitchellh/iochan v1.0.0 + github.com/stretchr/testify v1.8.2 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index fd3ac47..74d1838 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,21 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 517d017..c026dc6 100644 --- a/main.go +++ b/main.go @@ -41,7 +41,7 @@ func realMain() int { flags.StringVar(&flagOutput, "output", "{{.Dir}}_{{.OS}}_{{.Arch}}", "") flags.IntVar(&flagParallel, "parallel", -1, "") flags.BoolVar(&flagVerbose, "verbose", false, "") - flags.StringVar(&flagGoCmd, "gocmd", "go", "") + flags.StringVar(&flagGoCmd, "gocmd", gobin, "") // Misc. flags.Var(flagPlatform.ArchFlagValue(), "arch", "") @@ -111,7 +111,7 @@ func realMain() int { var v *version.Version // Use latest if we get an unexpected version string - if strings.HasPrefix(versionStr, "go") { + if strings.HasPrefix(versionStr, gobin) { if v, err = version.NewVersion(versionStr[2:]); err != nil { log.Printf("Unable to parse current go version: %s\n%s", versionStr, err.Error()) } @@ -154,19 +154,6 @@ func realMain() int { return 1 } - // Assume -mod is supported when no version prefix is found - if flagMod != "" { - constraint, err := version.NewConstraint(">= 1.11") - if err != nil { - panic(err) - } - - if !constraint.Check(v) { - fmt.Printf("Go compiler version %s does not support the -mod flag\n", versionStr) - flagMod = "" - } - } - // Build in parallel! fmt.Printf("Number of parallel builds: %d\n\n", flagParallel) @@ -211,7 +198,7 @@ func realMain() int { InstallSuffix: flagInstallSuffix, LDFlags: flagLDFlags, LinkShared: flagLinkShared, - ModMode: flagMod, + Mod: flagMod, ModCacheRW: flagModCacheRW, ModFile: flagModFile, Overlay: flagOverlay, diff --git a/opts.go b/opts.go index 360c2e8..fbf93a8 100644 --- a/opts.go +++ b/opts.go @@ -1,7 +1,10 @@ package main import ( + "fmt" "github.com/hashicorp/go-version" + "os" + "strings" ) type CompileOpts struct { @@ -14,75 +17,159 @@ type CompileOpts struct { GoCmd string GoVersion *version.Version - ChangeDir string // -C (todo) + ChangeDir string // -C Rebuild bool // -a Race bool // -race - MemorySanitizer bool // -msan (todo) - AddressSanitizer bool // -asan (todo) + MemorySanitizer bool // -msan + AddressSanitizer bool // -asan - Cover bool // -cover (todo) MUST SET GOEXPERIMENT=coverageredesign - CoverPackage string // -coverpkg (todo) + Cover bool // -cover + CoverPackage string // -coverpkg ASMFlags string // -asmflags BuildMode string // -buildmode BuildVCS string // -buildvs - Compiler string // -compiler (todo) - GcCGOFlags string // -gccgoflags (todo) + Compiler string // -compiler + GcCGOFlags string // -gccgoflags GcFlags string // -gcflags - InstallSuffix string // -installsuffix (todo) + InstallSuffix string // -installsuffix LDFlags string // -ldflags - LinkShared bool // -linkshared (todo) - ModMode string // -mod - ModCacheRW bool // -modcacherw (todo) - ModFile string // -modfile (todo) - Overlay string // -overlay (todo) + LinkShared bool // -linkshared + Mod string // -mod + ModCacheRW bool // -modcacherw + ModFile string // -modfile + Overlay string // -overlay - ProfileGuidedOptimization string // -pgo (todo) + ProfileGuidedOptimization string // -pgo - PackageDir string // -pkgdir (todo) + PackageDir string // -pkgdir Tags string // -tags TrimPath bool // -trimpath } +func (opts *CompileOpts) Experiments() (exp []string) { + exp = strings.Split(os.Getenv("GOEXPERIMENT"), ",") + + if opts.Cover && (opts.GoVersion == nil || flagConstraints[flagNameCover].Check(opts.GoVersion)) { + if constraints, ok := experimentConstraints[flagNameCover]; !ok || constraints.Check(opts.GoVersion) { + exp = append(exp, "coverageredesign") + } + } + + return exp +} + +func (opts *CompileOpts) Env() []string { + env := append(os.Environ(), + "GOOS="+opts.Platform.OS, + "GOARCH="+opts.Platform.Arch) + + if opts.Cc != "" { + env = append(env, "CC="+opts.Cc) + } + + if opts.Cxx != "" { + env = append(env, "CXX="+opts.Cxx) + } + + if opts.Cgo { + env = append(env, "CGO_ENABLED=1") + } else { + env = append(env, "CGO_ENABLED=0") + } + + if exp := opts.Experiments(); len(exp) != 0 { + env = append(env, fmt.Sprintf("GOEXPERIMENT=%s", strings.Join(exp, ","))) + } + + return env +} + +func (opts *CompileOpts) Arguments() []string { + arguments := &BuildArgFlags{} + + arguments.AddString(opts.GoVersion, "C", opts.ChangeDir) + arguments.AddBoolean(opts.GoVersion, "a", opts.Rebuild) + arguments.AddBoolean(opts.GoVersion, flagNameRace, opts.Race) + arguments.AddBoolean(opts.GoVersion, flagNameMSAN, opts.MemorySanitizer) + arguments.AddBoolean(opts.GoVersion, flagNameASAN, opts.AddressSanitizer) + arguments.AddBoolean(opts.GoVersion, flagNameCover, opts.Cover) + arguments.AddString(opts.GoVersion, flagNameCoverPKG, opts.CoverPackage) + arguments.AddStrings(opts.GoVersion, flagNameASMFlags, opts.ASMFlags) + arguments.AddString(opts.GoVersion, flagNameBuildMode, opts.BuildMode) + arguments.AddString(opts.GoVersion, flagNameBuildVCS, opts.BuildVCS) + arguments.AddString(opts.GoVersion, flagNameCompiler, opts.Compiler) + arguments.AddStrings(opts.GoVersion, flagNameGcCGOFlags, opts.GcCGOFlags) + arguments.AddStrings(opts.GoVersion, flagNameGcFlags, opts.GcFlags) + arguments.AddString(opts.GoVersion, flagNameInstallSuffix, opts.InstallSuffix) + arguments.AddStrings(opts.GoVersion, flagNameLDFlags, opts.LDFlags) + arguments.AddBoolean(opts.GoVersion, flagNameLinkShared, opts.LinkShared) + arguments.AddString(opts.GoVersion, flagNameMod, opts.Mod) + arguments.AddBoolean(opts.GoVersion, flagNameModCacheRW, opts.ModCacheRW) + arguments.AddString(opts.GoVersion, flagNameModFile, opts.ModFile) + arguments.AddString(opts.GoVersion, flagNameOverlay, opts.Overlay) + arguments.AddString(opts.GoVersion, flagNameProfileGuidedOptimization, opts.ProfileGuidedOptimization) + arguments.AddString(opts.GoVersion, flagNamePackageDir, opts.PackageDir) + arguments.AddStrings(opts.GoVersion, flagNameTags, opts.Tags) + arguments.AddBoolean(opts.GoVersion, flagNameTrimPath, opts.TrimPath) + + return arguments.Args() +} + type BuildArgFlags struct { args []string } -func (f *BuildArgFlags) Add(v *version.Version, name, value string, formatter func(string, string) string) { +func (f *BuildArgFlags) Args() []string { + return f.args +} + +func (f *BuildArgFlags) ShouldSkipVersion(v *version.Version, name string) bool { + if v == nil { + return false + } + + if constraints, ok := flagConstraints[name]; ok { + if !constraints.Check(v) { + return true + } + } + + return false +} + +func (f *BuildArgFlags) AddStrings(v *version.Version, name, value string) { + if value == "" { + return + } + if f.ShouldSkipVersion(v, name) { + return + } + + f.args = append(f.args, fmt.Sprintf(`-%s="%s"`, name, value)) } -var flagConstraints map[string]version.Constraints - -func init() { - inputs := []struct { - name string - constraint string - }{ - {"C", ">= 1.20"}, - {"asan", ">= 1.18"}, - {"cover", ">= 1.20"}, - {"coverpkg", ">= 1.20"}, - {"buildvcs", ">= 1.18"}, - {"modcacherw", ">= 1.14"}, - {"modfile", ">= 1.14"}, - {"overlay", ">= 1.16"}, - {"pgo", ">= 1.20"}, - {"trimpath", ">= 1.13"}, +func (f *BuildArgFlags) AddString(v *version.Version, name, value string) { + if value == "" { + return } - var ( - constraint version.Constraints - err error - ) + if f.ShouldSkipVersion(v, name) { + return + } - flagConstraints = map[string]version.Constraints{} + f.args = append(f.args, fmt.Sprintf("-%s=%s", name, value)) +} - for _, input := range inputs { - if constraint, err = version.NewConstraint(input.constraint); err != nil { - panic(err) - } +func (f *BuildArgFlags) AddBoolean(v *version.Version, name string, value bool) { + if !value { + return + } - flagConstraints[input.name] = constraint + if f.ShouldSkipVersion(v, name) { + return } + + f.args = append(f.args, "-"+name) } diff --git a/opts_test.go b/opts_test.go new file mode 100644 index 0000000..6d42996 --- /dev/null +++ b/opts_test.go @@ -0,0 +1,51 @@ +package main + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestCompileOpts_Arguments(t *testing.T) { + testCases := []struct { + name string + have *CompileOpts + expected []string + }{ + {"ShouldNotReturnAnyArgs", &CompileOpts{}, nil}, + {"ShouldReturnBooleanTrimPath", &CompileOpts{TrimPath: true}, []string{"-trimpath"}}, + {"ShouldReturnBooleanRace", &CompileOpts{Race: true}, []string{"-race"}}, + {"ShouldReturnBooleanCover", &CompileOpts{Cover: true}, []string{"-cover"}}, + {"ShouldReturnBooleanCoverWithVersion", &CompileOpts{GoVersion: MustParseVersion("go1.20"), Cover: true}, []string{"-cover"}}, + {"ShouldReturnBooleanCoverWithBadVersion", &CompileOpts{GoVersion: MustParseVersion("go1.19"), Cover: true}, nil}, + {"ShouldReturnBooleanRebuild", &CompileOpts{Rebuild: true}, []string{"-a"}}, + {"ShouldReturnBooleanMSAN", &CompileOpts{MemorySanitizer: true}, []string{"-msan"}}, + {"ShouldReturnBooleanASAN", &CompileOpts{AddressSanitizer: true}, []string{"-asan"}}, + {"ShouldReturnBooleanLinkShared", &CompileOpts{LinkShared: true}, []string{"-linkshared"}}, + {"ShouldReturnBooleanLinkModCacheRW", &CompileOpts{ModCacheRW: true}, []string{"-modcacherw"}}, + {"ShouldReturnBooleanLinkModCacheRWWithVersion", &CompileOpts{GoVersion: MustParseVersion("go1.19"), ModCacheRW: true}, []string{"-modcacherw"}}, + {"ShouldReturnBooleanLinkModCacheRWWithBadVersion", &CompileOpts{GoVersion: MustParseVersion("go1.13"), ModCacheRW: true}, nil}, + {"ShouldReturnBooleanMiscMixed", &CompileOpts{GoVersion: MustParseVersion("go1.13"), ModCacheRW: true, TrimPath: true, Rebuild: true}, []string{"-a", "-trimpath"}}, + {"ShouldReturnStringC", &CompileOpts{GoVersion: MustParseVersion("go1.20"), ChangeDir: "foo"}, []string{"-C=foo"}}, + {"ShouldReturnStringCoverPackage", &CompileOpts{GoVersion: MustParseVersion("go1.20"), CoverPackage: "foo"}, []string{"-coverpkg=foo"}}, + {"ShouldReturnStringsASMFlags", &CompileOpts{GoVersion: MustParseVersion("go1.20"), ASMFlags: "foo"}, []string{`-asmflags="foo"`}}, + {"ShouldReturnStringBuildMode", &CompileOpts{GoVersion: MustParseVersion("go1.20"), BuildMode: "foo"}, []string{`-buildmode=foo`}}, + {"ShouldReturnStringBuildVCS", &CompileOpts{GoVersion: MustParseVersion("go1.20"), BuildVCS: "foo"}, []string{`-buildvcs=foo`}}, + {"ShouldReturnStringCompiler", &CompileOpts{GoVersion: MustParseVersion("go1.20"), Compiler: "foo"}, []string{`-compiler=foo`}}, + {"ShouldReturnStringsGcCGOFlags", &CompileOpts{GoVersion: MustParseVersion("go1.20"), GcCGOFlags: "foo"}, []string{`-gccgoflags="foo"`}}, + {"ShouldReturnStringsGcFlags", &CompileOpts{GoVersion: MustParseVersion("go1.20"), GcFlags: "foo"}, []string{`-gcflags="foo"`}}, + {"ShouldReturnStringInstallSuffix", &CompileOpts{GoVersion: MustParseVersion("go1.20"), InstallSuffix: "foo"}, []string{`-installsuffix=foo`}}, + {"ShouldReturnStringsLDFlags", &CompileOpts{GoVersion: MustParseVersion("go1.20"), LDFlags: "foo"}, []string{`-ldflags="foo"`}}, + {"ShouldReturnStringMod", &CompileOpts{GoVersion: MustParseVersion("go1.20"), Mod: "foo"}, []string{`-mod=foo`}}, + {"ShouldReturnStringModFile", &CompileOpts{GoVersion: MustParseVersion("go1.20"), ModFile: "foo"}, []string{`-modfile=foo`}}, + {"ShouldReturnStringOverlay", &CompileOpts{GoVersion: MustParseVersion("go1.20"), Overlay: "foo"}, []string{`-overlay=foo`}}, + {"ShouldReturnStringPGO", &CompileOpts{GoVersion: MustParseVersion("go1.20"), ProfileGuidedOptimization: "foo"}, []string{`-pgo=foo`}}, + {"ShouldReturnStringPkgDir", &CompileOpts{GoVersion: MustParseVersion("go1.20"), PackageDir: "foo"}, []string{`-pkgdir=foo`}}, + {"ShouldReturnStringsTags", &CompileOpts{GoVersion: MustParseVersion("go1.20"), Tags: "foo"}, []string{`-tags="foo"`}}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expected, tc.have.Arguments()) + }) + } +} diff --git a/platform.go b/platform.go index 511cd5e..bc3e206 100644 --- a/platform.go +++ b/platform.go @@ -207,48 +207,3 @@ type PlatformConstraint struct { Constraints version.Constraints Platforms []Platform } - -var platformConstraints []PlatformConstraint - -func init() { - inputs := []struct { - constraint string - platforms []Platform - }{ - {"<= 1.0", Platforms_1_0}, - {">= 1.1, < 1.3", Platforms_1_1}, - {">= 1.3, < 1.4", Platforms_1_3}, - {">= 1.4, < 1.5", Platforms_1_4}, - {">= 1.5, < 1.6", Platforms_1_5}, - {">= 1.6, < 1.7", Platforms_1_6}, - {">= 1.7, < 1.8", Platforms_1_7}, - {">= 1.8, < 1.9", Platforms_1_8}, - {">= 1.9, < 1.10", Platforms_1_9}, - {">= 1.10, < 1.11", Platforms_1_10}, - {">= 1.11, < 1.12", Platforms_1_11}, - {">= 1.12, < 1.13", Platforms_1_12}, - {">= 1.13, < 1.14", Platforms_1_13}, - {">= 1.14, < 1.15", Platforms_1_14}, - {">= 1.15, < 1.16", Platforms_1_15}, - {">= 1.16, < 1.17", Platforms_1_16}, - {">= 1.17, < 1.18", Platforms_1_17}, - {">= 1.18, < 1.19", Platforms_1_18}, - {">= 1.19, < 1.20", Platforms_1_19}, - {">= 1.20, < 1.21", Platforms_1_20}, - } - - platformConstraints = make([]PlatformConstraint, len(inputs)) - - var ( - constraint version.Constraints - err error - ) - - for i, input := range inputs { - if constraint, err = version.NewConstraint(input.constraint); err != nil { - panic(err) - } - - platformConstraints[i] = PlatformConstraint{Constraints: constraint, Platforms: input.platforms} - } -} diff --git a/toolchain.go b/toolchain.go index 5c1d0fc..8823326 100644 --- a/toolchain.go +++ b/toolchain.go @@ -16,7 +16,7 @@ import ( // The "main" method for when the toolchain build is requested. func mainBuildToolchain(v *version.Version, parallel int, platformFlag PlatformFlag, verbose bool) int { - if _, err := exec.LookPath("go"); err != nil { + if _, err := exec.LookPath(gobin); err != nil { fmt.Fprintf(os.Stderr, "You must have Go already built for your native platform\n") fmt.Fprintf(os.Stderr, "and the `go` binary on the PATH to build toolchains.\n") return 1