Skip to content

Commit 04e10fc

Browse files
authored
Attempt build even if fetching of build flags fails (#800)
Attempts to build the tools with local detection have heretofore required the build system to determine build flags on the local platform. This needlessly complicates the process. The present changeset removes that requirement. Now the build system will always attempt a build even if it cannot determine build flags. This also removes the baked-in assumption that locally-detected Linux versions are Ubuntu 18.04. Now the build system runs `lsb_release` to determine the Linux distribution’s name & release version.
1 parent 8688866 commit 04e10fc

File tree

4 files changed

+107
-61
lines changed

4 files changed

+107
-61
lines changed

buildscript/build.go

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -102,20 +102,12 @@ func TestAWSAuth(ctx *task.Context) error {
102102
// buildToolBinary builds the tool with the specified name, putting
103103
// the resulting binary into outDir.
104104
func buildToolBinary(ctx *task.Context, tool string, outDir string) error {
105-
pf, err := getPlatform()
106-
if err != nil {
107-
return err
108-
}
109-
110-
outPath := filepath.Join(outDir, tool+pf.BinaryExt)
105+
outPath := filepath.Join(outDir, tool+platform.GetLocalBinaryExt())
111106
_ = sh.Remove(ctx, outPath)
112107

113108
mainFile := filepath.Join(tool, "main", fmt.Sprintf("%s.go", tool))
114109

115-
buildFlags, err := getBuildFlags(ctx, false)
116-
if err != nil {
117-
return fmt.Errorf("failed to get build flags: %w", err)
118-
}
110+
buildFlags := getBuildFlags(ctx, false)
119111

120112
args := []string{
121113
"build",
@@ -125,8 +117,9 @@ func buildToolBinary(ctx *task.Context, tool string, outDir string) error {
125117
args = append(args, mainFile)
126118

127119
cmd := exec.CommandContext(ctx, "go", args...)
120+
cmd.Stderr = os.Stderr
128121
sh.LogCmd(ctx, cmd)
129-
output, err := cmd.CombinedOutput()
122+
output, err := cmd.Output()
130123

131124
if len(output) > 0 {
132125
_, _ = ctx.Write(output)
@@ -147,10 +140,7 @@ func runTests(ctx *task.Context, pkgs []string, testType string) error {
147140
}
148141
defer outFile.Close()
149142

150-
buildFlags, err := getBuildFlags(ctx, true)
151-
if err != nil {
152-
return fmt.Errorf("failed to get build flags: %w", err)
153-
}
143+
buildFlags := getBuildFlags(ctx, true)
154144

155145
// Use the recursive wildcard (...) to run all tests
156146
// of the provided testType for the current pkg.
@@ -223,38 +213,39 @@ func getLdflags(ctx *task.Context) (string, error) {
223213

224214
// getBuildFlags gets all the build flags that should be used when
225215
// building the tools on the current platform, including tags and ldflags.
226-
func getBuildFlags(ctx *task.Context, forTests bool) ([]string, error) {
216+
func getBuildFlags(ctx *task.Context, forTests bool) []string {
217+
flags := []string{}
218+
227219
ldflags, err := getLdflags(ctx)
228-
if err != nil {
229-
return nil, fmt.Errorf("failed to get ldflags: %w", err)
220+
if err == nil {
221+
flags = append(flags, "-ldflags", ldflags)
222+
} else {
223+
ctx.Logf("failed to get ldflags (error: %v); will still attempt build\n", err)
230224
}
231225

232226
tags, err := getTags(ctx)
233-
if err != nil {
234-
return nil, fmt.Errorf("failed to get tags: %w", err)
235-
}
236-
237-
flags := []string{
238-
"-ldflags", ldflags,
239-
"-tags", strings.Join(tags, " "),
227+
if err == nil {
228+
flags = append(flags, "-tags", strings.Join(tags, " "))
229+
} else {
230+
ctx.Logf("failed to get tags (error: %v); will still attempt build\n", err)
240231
}
241232

242233
pf, err := getPlatform()
243-
if err != nil {
244-
return nil, fmt.Errorf("failed to get platform: %w", err)
245-
}
246-
247-
if pf.OS == platform.OSLinux {
248-
// We don't want to enable -buildmode=pie for tests. This interferes with enabling the race
249-
// detector.
250-
if !forTests {
251-
flags = append(flags, "-buildmode=pie")
234+
if err == nil {
235+
if pf.OS == platform.OSLinux {
236+
// We don't want to enable -buildmode=pie for tests. This interferes with enabling the race
237+
// detector.
238+
if !forTests {
239+
flags = append(flags, "-buildmode=pie")
240+
}
241+
} else if pf.OS == platform.OSWindows {
242+
flags = append(flags, "-buildmode=exe")
252243
}
253-
} else if pf.OS == platform.OSWindows {
254-
flags = append(flags, "-buildmode=exe")
244+
} else {
245+
ctx.Logf("failed to get platform (error: %v); will still attempt build\n", err)
255246
}
256247

257-
return flags, nil
248+
return flags
258249
}
259250

260251
// runCmd runs the command with the provided name and arguments, and

release/platform/platform.go

Lines changed: 76 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
package platform
22

33
import (
4+
"bytes"
45
"cmp"
56
"fmt"
7+
"os"
68
"os/exec"
79
"regexp"
10+
"runtime"
811
"sort"
912
"strings"
1013

1114
mapset "github.com/deckarep/golang-set/v2"
1215
"github.com/mongodb/mongo-tools/release/env"
1316
"github.com/mongodb/mongo-tools/release/version"
17+
"github.com/samber/lo"
1418
)
1519

1620
type OS string
@@ -63,7 +67,6 @@ type Platform struct {
6367
Pkg Pkg
6468
Repos []Repo
6569
BuildTags []string
66-
BinaryExt string
6770
SkipForJSONFeed bool
6871
ServerVariantNames mapset.Set[string]
6972
ServerPlatform string
@@ -104,6 +107,7 @@ func GetFromEnv() (Platform, error) {
104107
func DetectLocal() (Platform, error) {
105108

106109
cmd := exec.Command("uname", "-sm")
110+
cmd.Stderr = os.Stderr
107111
out, err := cmd.Output()
108112
if err != nil {
109113
return Platform{}, fmt.Errorf("failed to run uname: %w", err)
@@ -118,30 +122,72 @@ func DetectLocal() (Platform, error) {
118122
kernelName := pieces[0]
119123
archName := Arch(pieces[1])
120124

125+
var os string
126+
var pf Platform
127+
var foundPf bool
128+
121129
if strings.HasPrefix(kernelName, "CYGWIN") || strings.HasPrefix(kernelName, "MSYS_NT") {
122-
pf, ok := GetByVariant("windows")
123-
if !ok {
124-
panic("windows platform name changed")
130+
os = "windows"
131+
pf, foundPf = GetByVariant("windows")
132+
} else {
133+
switch kernelName {
134+
case "Linux":
135+
var version string
136+
137+
os, version, err = GetLinuxDistroAndVersion()
138+
if err != nil {
139+
return Platform{}, fmt.Errorf(
140+
"detecting local Linux distro/version: %w",
141+
err,
142+
)
143+
}
144+
145+
os = strings.ToLower(os)
146+
version = strings.ReplaceAll(version, ".", "")
147+
148+
os += version
149+
case "Darwin":
150+
os = "macos"
151+
default:
152+
return Platform{}, fmt.Errorf("failed to detect local platform from kernel name %q", kernelName)
125153
}
126-
return pf, nil
154+
155+
pf, foundPf = GetByOsAndArch(os, archName)
127156
}
128157

129-
switch kernelName {
130-
case "Linux":
131-
pf, ok := GetByOsAndArch("ubuntu1804", archName)
132-
if !ok {
133-
panic("ubuntu1804 platform name changed")
134-
}
135-
return pf, nil
136-
case "Darwin":
137-
pf, ok := GetByOsAndArch("macos", archName)
138-
if !ok {
139-
panic("macos platform name changed")
140-
}
141-
return pf, nil
158+
if !foundPf {
159+
return Platform{}, fmt.Errorf(
160+
"no platform %s/%s found; did %s’s platform name change?",
161+
os,
162+
archName,
163+
os,
164+
)
165+
}
166+
167+
return pf, nil
168+
}
169+
170+
func GetLinuxDistroAndVersion() (string, string, error) {
171+
cmd := exec.Command("lsb_release", "--short", "--id")
172+
cmd.Stderr = os.Stderr
173+
distro, err := cmd.Output()
174+
175+
if err != nil {
176+
return "", "", fmt.Errorf("fetching Linux distro name: %w", err)
142177
}
143178

144-
return Platform{}, fmt.Errorf("failed to detect local platform from kernel name %q", kernelName)
179+
cmd = exec.Command("lsb_release", "--short", "--release")
180+
cmd.Stderr = os.Stderr
181+
version, err := cmd.Output()
182+
183+
if err != nil {
184+
return "", "", fmt.Errorf("fetching %#q version: %w", distro, err)
185+
}
186+
187+
distroStr := string(bytes.TrimSpace(distro))
188+
versionStr := string(bytes.TrimSpace(version))
189+
190+
return distroStr, versionStr, nil
145191
}
146192

147193
func GetByVariant(variant string) (Platform, bool) {
@@ -255,9 +301,9 @@ func (p Platform) asGolangString() string {
255301
}
256302
}
257303

258-
var binaryExt string
259-
if p.BinaryExt != "" {
260-
binaryExt = indentGolangField("BinaryExt", fmt.Sprintf(`"%s"`, p.BinaryExt))
304+
binaryExt := GetLocalBinaryExt()
305+
if binaryExt != "" {
306+
binaryExt = indentGolangField("BinaryExt", fmt.Sprintf(`"%s"`, binaryExt))
261307
}
262308

263309
return fmt.Sprintf(
@@ -272,6 +318,14 @@ func (p Platform) asGolangString() string {
272318
)
273319
}
274320

321+
func GetLocalBinaryExt() string {
322+
return lo.Ternary(
323+
runtime.GOOS == "windows",
324+
".exe",
325+
"",
326+
)
327+
}
328+
275329
var canonicalTarget = map[string]string{
276330
"rhel80": "rhel8",
277331
}
@@ -684,7 +738,6 @@ var platforms = []Platform{
684738
Arch: ArchX86_64,
685739
OS: OSWindows,
686740
BuildTags: defaultBuildTags,
687-
BinaryExt: ".exe",
688741
ServerVariantNames: mapset.NewSet("enterprise-windows"),
689742
},
690743
}

release/release.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func main() {
7979
Action: func(cCtx *cli.Context) error {
8080
v, err := version.GetCurrent()
8181
if err != nil {
82-
return fmt.Errorf("Failed to get current version: %v", err)
82+
return fmt.Errorf("Failed to get current version: %w", err)
8383
}
8484
fmt.Println(v.StringWithCommit())
8585
return nil

release/version/version.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package version
22

33
import (
44
"fmt"
5+
"os"
56
"os/exec"
67
"regexp"
78
"strconv"
@@ -143,6 +144,7 @@ func git(args ...string) (string, error) {
143144
}
144145

145146
cmd := exec.Command("git", args...)
147+
cmd.Stderr = os.Stderr
146148
out, err := cmd.Output()
147149
if err != nil {
148150
if exerr, ok := err.(*exec.ExitError); ok {

0 commit comments

Comments
 (0)