Skip to content

Commit 2cd5cd3

Browse files
committed
TOOLS-4102 Use mise to execute go as well as other dev tools
This gets rid of the Go code to install dev tools entirely, and updates all the places we call these tools to use `mise exec`.
1 parent 6540086 commit 2cd5cd3

10 files changed

Lines changed: 29 additions & 529 deletions

File tree

build.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,12 @@ func init() {
4545
Do(buildscript.WriteThirdPartyNotices)
4646

4747
// Static Analysis
48-
taskRegistry.Declare("sa:installdevtools").
49-
Description("installs dev tools").
50-
Do(buildscript.SAInstallDevTools)
5148
taskRegistry.Declare("sa:lint").
5249
Description("runs precious linting").
53-
DependsOn("sa:installdevtools").
5450
Do(buildscript.SAPreciousLint)
55-
taskRegistry.Declare("sa:modtidy").Description("runs go mod tidy").Do(buildscript.SAModTidy)
51+
taskRegistry.Declare("sa:modtidy").
52+
Description("runs go mod tidy").
53+
Do(buildscript.SAModTidy)
5654
taskRegistry.Declare("sa:evgvalidate").
5755
Description("runs evergreen validate").
5856
Do(buildscript.SAEvergreenValidate)

buildscript/sa.go

Lines changed: 1 addition & 319 deletions
Original file line numberDiff line numberDiff line change
@@ -4,339 +4,21 @@ import (
44
"bytes"
55
"errors"
66
"fmt"
7-
"io"
87
"os"
98
"os/exec"
10-
"path/filepath"
11-
"runtime"
129
"strings"
1310

1411
"github.com/craiggwilson/goke/pkg/sh"
1512
"github.com/craiggwilson/goke/task"
1613
)
1714

18-
const (
19-
goimportsVersion = "v0.29.0"
20-
goimportsPkg = "golang.org/x/tools/cmd/goimports@" + goimportsVersion
21-
22-
// For JS tools like eslint and prettier, these versions need to match the ones in the
23-
// `package.json` file. To update to a new version, run a command like this:
24-
//
25-
// npm install --save-dev --save-exact prettier@3.3.1
26-
//
27-
// Then update the version in this file as well.
28-
29-
// This is the latest version to support a YAML config file. Updating to
30-
// the new config file syntax did not seem trivial.
31-
eslintVersion = "8.57.0"
32-
gitHubCodeownersVersion = "0.2.1"
33-
golangCILintVersion = "2.6.2"
34-
golinesVersion = "0.12.2" // 0.13.0 fails w/ libc errors
35-
gosecVersion = "2.22.10"
36-
preciousVersion = "0.10.1"
37-
ubiVersion = "0.8.4"
38-
prettierVersion = "3.6.2"
39-
)
40-
41-
func SAInstallDevTools(ctx *task.Context) error {
42-
if err := installUBI(ctx); err != nil {
43-
return err
44-
}
45-
if err := installGoimports(ctx); err != nil {
46-
return err
47-
}
48-
if err := installGolangCILint(ctx); err != nil {
49-
return err
50-
}
51-
if err := installGolines(ctx); err != nil {
52-
return err
53-
}
54-
if err := installGosec(ctx); err != nil {
55-
return err
56-
}
57-
if err := installPrecious(ctx); err != nil {
58-
return err
59-
}
60-
return installJSTools(ctx)
61-
}
62-
63-
// Install goimports.
64-
func installGoimports(ctx *task.Context) error {
65-
return goInstall(ctx, goimportsPkg)
66-
}
67-
68-
// Install UBI.
69-
func installUBI(ctx *task.Context) error {
70-
var err error
71-
devBin, err := devBinDir()
72-
if err != nil {
73-
return err
74-
}
75-
76-
ubi, err := devBinFile("ubi")
77-
if err != nil {
78-
return err
79-
}
80-
81-
exists, err := executableExistsWithVersion(ctx, ubi, ubiVersion)
82-
if err != nil {
83-
return err
84-
}
85-
if exists {
86-
return nil
87-
}
88-
89-
var ubiBootstrapURL string
90-
switch runtime.GOOS {
91-
case "windows":
92-
ubiBootstrapURL = "https://raw.githubusercontent.com/houseabsolute/ubi/ci-for-bootstrap/bootstrap/bootstrap-ubi.ps1"
93-
default:
94-
ubiBootstrapURL = fmt.Sprintf(
95-
"https://raw.githubusercontent.com/houseabsolute/ubi/v%s/bootstrap/bootstrap-ubi.sh",
96-
ubiVersion,
97-
)
98-
}
99-
100-
s := strings.Split(ubiBootstrapURL, "/")
101-
bootstrapPath := filepath.Join(os.TempDir(), s[len(s)-1])
102-
103-
out, err := os.Create(bootstrapPath)
104-
if err != nil {
105-
return err
106-
}
107-
defer out.Close()
108-
109-
resp, err := httpGetWithRetries(ubiBootstrapURL, 5)
110-
if err != nil {
111-
return err
112-
}
113-
defer resp.Body.Close()
114-
115-
_, err = io.Copy(out, resp.Body)
116-
if err != nil {
117-
return err
118-
}
119-
120-
var cmd []string
121-
if strings.HasSuffix(ubiBootstrapURL, ".ps1") {
122-
cmd = []string{"powershell", bootstrapPath}
123-
} else {
124-
cmd = []string{"sh", bootstrapPath}
125-
}
126-
127-
// On Windows the bootstrapper always installs into the current directory,
128-
// so chdir there first.
129-
return doInDir(devBin, func() error {
130-
c := exec.CommandContext(ctx, cmd[0], cmd[1:]...)
131-
c.Env = []string{"TARGET=" + devBin, "TAG=v" + ubiVersion}
132-
return sh.RunCmd(ctx, c)
133-
})
134-
}
135-
136-
// Install golangci-lint.
137-
func installGolangCILint(ctx *task.Context) error {
138-
return installBinaryTool(
139-
ctx,
140-
"golangci-lint",
141-
golangCILintVersion,
142-
"golangci/golangci-lint",
143-
fmt.Sprintf(
144-
"https://github.com/golangci/golangci-lint/releases/download/v%s/golangci-lint-%s-linux-amd64.tar.gz",
145-
golangCILintVersion,
146-
golangCILintVersion,
147-
),
148-
)
149-
}
150-
151-
// Install golines.
152-
func installGolines(ctx *task.Context) error {
153-
return installBinaryTool(
154-
ctx,
155-
"golines",
156-
golinesVersion,
157-
"segmentio/golines",
158-
fmt.Sprintf(
159-
"https://github.com/segmentio/golines/releases/download/v%s/golines_%s_linux_amd64.tar.gz",
160-
golinesVersion,
161-
golinesVersion,
162-
),
163-
)
164-
}
165-
166-
// Install gosec.
167-
func installGosec(ctx *task.Context) error {
168-
return installBinaryTool(
169-
ctx,
170-
"gosec",
171-
gosecVersion,
172-
"securego/gosec",
173-
fmt.Sprintf(
174-
"https://github.com/securego/gosec/releases/download/v%s/gosec_%s_linux_amd64.tar.gz",
175-
gosecVersion,
176-
gosecVersion,
177-
),
178-
)
179-
}
180-
181-
func installPrecious(ctx *task.Context) error {
182-
return installBinaryTool(
183-
ctx,
184-
"precious",
185-
preciousVersion,
186-
"houseabsolute/precious",
187-
fmt.Sprintf(
188-
"https://github.com/houseabsolute/precious/releases/download/v%s/precious-Linux-musl-x86_64.tar.gz",
189-
preciousVersion,
190-
),
191-
)
192-
}
193-
194-
// Install a Golang package as an executable with "go install".
195-
func goInstall(ctx *task.Context, link string) error {
196-
root, err := repoRoot()
197-
if err != nil {
198-
return err
199-
}
200-
if err = os.Setenv("GOBIN", filepath.Join(root, "dev-bin")); err != nil {
201-
return err
202-
}
203-
204-
return withRetries(
205-
5,
206-
fmt.Sprintf("go install %s", link),
207-
func() error {
208-
return sh.Run(ctx, "go", "install", link)
209-
},
210-
)
211-
}
212-
213-
func installBinaryTool(
214-
ctx *task.Context,
215-
exeName, toolVersion, githubProject, downloadURLForCI string,
216-
) error {
217-
devBin, err := devBinDir()
218-
if err != nil {
219-
return err
220-
}
221-
222-
devBinExe, err := devBinFile(exeName)
223-
if err != nil {
224-
return err
225-
}
226-
227-
exists, err := executableExistsWithVersion(ctx, devBinExe, toolVersion)
228-
if err != nil {
229-
return err
230-
}
231-
if exists {
232-
return nil
233-
}
234-
235-
cmd := []string{
236-
filepath.Join(devBin, "ubi"),
237-
"--in", devBin,
238-
}
239-
if inCI() {
240-
// Using the `--url` arg avoids hitting the GitHub API, but it skips
241-
// all the platform detection ubi provides. We do it this way because
242-
// even with authentication, the limits on the GitHub API are
243-
// something like 5,000 requests an hour. Without it, the limit is way
244-
// lower.
245-
//
246-
// This seemed simpler than adding a GitHub token to Evergreen. If we
247-
// ever switch to GH Actions we can reconsider, since in that case
248-
// we'd have a token automatically available in the `GITHUB_TOKEN` env
249-
// var.
250-
cmd = append(cmd, "--url", downloadURLForCI)
251-
} else {
252-
cmd = append(
253-
cmd,
254-
"--project", githubProject,
255-
"--tag", "v"+toolVersion,
256-
)
257-
}
258-
259-
return withRetries(
260-
5,
261-
fmt.Sprintf("installing %s", exeName),
262-
func() error {
263-
return sh.Run(ctx, cmd[0], cmd[1:]...)
264-
},
265-
)
266-
}
267-
268-
// We have to install all the JS tools at once. If we run `npm install <tool>` multiple times, each
269-
// execution wipes the entire `node_modules` directory, so we only end up with one tool (the last
270-
// one) installed.
271-
func installJSTools(ctx *task.Context) error {
272-
eslint, err := npmPath("eslint")
273-
if err != nil {
274-
return err
275-
}
276-
277-
prettier, err := npmPath("prettier")
278-
if err != nil {
279-
return err
280-
}
281-
282-
for _, tool := range [][]string{
283-
{eslint, eslintVersion},
284-
{prettier, prettierVersion},
285-
} {
286-
exists, err := executableExistsWithVersion(ctx, tool[0], tool[1])
287-
if err != nil {
288-
return err
289-
}
290-
if !exists {
291-
return runNPMInstall(ctx)
292-
}
293-
}
294-
295-
gitHubCodeowners, err := npmPath("github-codeowners")
296-
if err != nil {
297-
return err
298-
}
299-
300-
// This program doesn't have any way to print its version. :(
301-
exists, err := fileExists(gitHubCodeowners)
302-
if err != nil {
303-
return err
304-
}
305-
if !exists {
306-
return runNPMInstall(ctx)
307-
}
308-
309-
return nil
310-
}
311-
312-
func runNPMInstall(ctx *task.Context) error {
313-
return sh.Run(
314-
ctx,
315-
"npm", "install",
316-
)
317-
}
318-
319-
func npmPath(exe string) (string, error) {
320-
root, err := repoRoot()
321-
if err != nil {
322-
return "", err
323-
}
324-
325-
return filepath.Join(root, "node_modules", ".bin", exe), nil
326-
}
327-
32815
func SAPreciousLint(ctx *task.Context) error {
32916
return runPrecious(ctx, "lint", "--all")
33017
}
33118

33219
func runPrecious(ctx *task.Context, args ...string) error {
333-
devBin, err := devBinDir()
334-
if err != nil {
335-
return err
336-
}
337-
33820
cmd := append(
339-
[]string{filepath.Join(devBin, "precious")},
21+
[]string{"mise", "exec", "github:houseabsolute/precious", "--", "precious"},
34022
args...,
34123
)
34224

0 commit comments

Comments
 (0)