Skip to content

Commit 0dc3c84

Browse files
committed
Go: Move go invocations to separate file
1 parent df8d453 commit 0dc3c84

File tree

4 files changed

+70
-58
lines changed

4 files changed

+70
-58
lines changed

go/extractor/cli/go-autobuilder/go-autobuilder.go

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"bufio"
54
"fmt"
65
"log"
76
"net/url"
@@ -17,6 +16,7 @@ import (
1716

1817
"github.com/github/codeql-go/extractor/autobuilder"
1918
"github.com/github/codeql-go/extractor/diagnostics"
19+
"github.com/github/codeql-go/extractor/toolchain"
2020
"github.com/github/codeql-go/extractor/util"
2121
)
2222

@@ -56,43 +56,9 @@ Build behavior:
5656
fmt.Fprintf(os.Stderr, "Usage:\n\n %s\n", os.Args[0])
5757
}
5858

59-
var goVersion = ""
60-
61-
// Returns the current Go version as returned by 'go version', e.g. go1.14.4
62-
func getEnvGoVersion() string {
63-
if goVersion == "" {
64-
// Since Go 1.21, running 'go version' in a directory with a 'go.mod' file will attempt to
65-
// download the version of Go specified in there. That may either fail or result in us just
66-
// being told what's already in 'go.mod'. Setting 'GOTOOLCHAIN' to 'local' will force it
67-
// to use the local Go toolchain instead.
68-
cmd := exec.Command("go", "version")
69-
cmd.Env = append(os.Environ(), "GOTOOLCHAIN=local")
70-
out, err := cmd.CombinedOutput()
71-
72-
if err != nil {
73-
log.Fatalf("Unable to run the go command, is it installed?\nError: %s", err.Error())
74-
}
75-
76-
goVersion = parseGoVersion(string(out))
77-
}
78-
return goVersion
79-
}
80-
81-
// The 'go version' command may output warnings on separate lines before
82-
// the actual version string is printed. This function parses the output
83-
// to retrieve just the version string.
84-
func parseGoVersion(data string) string {
85-
var lastLine string
86-
sc := bufio.NewScanner(strings.NewReader(data))
87-
for sc.Scan() {
88-
lastLine = sc.Text()
89-
}
90-
return strings.Fields(lastLine)[2]
91-
}
92-
9359
// Returns the current Go version in semver format, e.g. v1.14.4
9460
func getEnvGoSemVer() string {
95-
goVersion := getEnvGoVersion()
61+
goVersion := toolchain.GetEnvGoVersion()
9662
if !strings.HasPrefix(goVersion, "go") {
9763
log.Fatalf("Expected 'go version' output of the form 'go1.2.3'; got '%s'", goVersion)
9864
}
@@ -780,7 +746,7 @@ func getBuildInfo(emitDiagnostics bool) BuildInfo {
780746

781747
// Build the project and run the extractor.
782748
func installDependenciesAndBuild() {
783-
log.Printf("Autobuilder was built with %s, environment has %s\n", runtime.Version(), getEnvGoVersion())
749+
log.Printf("Autobuilder was built with %s, environment has %s\n", runtime.Version(), toolchain.GetEnvGoVersion())
784750

785751
srcdir := getSourceDir()
786752

@@ -1110,22 +1076,16 @@ func (v versionInfo) String() string {
11101076
v.goModVersion, v.goModVersionFound, v.goEnvVersion, v.goEnvVersionFound)
11111077
}
11121078

1113-
// Check if Go is installed in the environment.
1114-
func isGoInstalled() bool {
1115-
_, err := exec.LookPath("go")
1116-
return err == nil
1117-
}
1118-
11191079
// Get the version of Go to install and output it to stdout as json.
11201080
func identifyEnvironment() {
11211081
var v versionInfo
11221082
buildInfo := getBuildInfo(false)
11231083
goVersionInfo := tryReadGoDirective(buildInfo)
11241084
v.goModVersion, v.goModVersionFound = goVersionInfo.Version, goVersionInfo.Found
11251085

1126-
v.goEnvVersionFound = isGoInstalled()
1086+
v.goEnvVersionFound = toolchain.IsInstalled()
11271087
if v.goEnvVersionFound {
1128-
v.goEnvVersion = getEnvGoVersion()[2:]
1088+
v.goEnvVersion = toolchain.GetEnvGoVersion()[2:]
11291089
}
11301090

11311091
msg, versionToInstall := getVersionToInstall(v)

go/extractor/cli/go-autobuilder/go-autobuilder_test.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,6 @@ func TestGetImportPathFromRepoURL(t *testing.T) {
2121
}
2222
}
2323

24-
func TestParseGoVersion(t *testing.T) {
25-
tests := map[string]string{
26-
"go version go1.18.9 linux/amd64": "go1.18.9",
27-
"warning: GOPATH set to GOROOT (/usr/local/go) has no effect\ngo version go1.18.9 linux/amd64": "go1.18.9",
28-
}
29-
for input, expected := range tests {
30-
actual := parseGoVersion(input)
31-
if actual != expected {
32-
t.Errorf("Expected parseGoVersion(\"%s\") to be \"%s\", but got \"%s\".", input, expected, actual)
33-
}
34-
}
35-
}
36-
3724
func TestGetVersionToInstall(t *testing.T) {
3825
tests := map[versionInfo]string{
3926
// getVersionWhenGoModVersionNotFound()

go/extractor/toolchain/toolchain.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package toolchain
2+
3+
import (
4+
"bufio"
5+
"log"
6+
"os"
7+
"os/exec"
8+
"strings"
9+
)
10+
11+
// Check if Go is installed in the environment.
12+
func IsInstalled() bool {
13+
_, err := exec.LookPath("go")
14+
return err == nil
15+
}
16+
17+
var goVersion = ""
18+
19+
// Returns the current Go version as returned by 'go version', e.g. go1.14.4
20+
func GetEnvGoVersion() string {
21+
if goVersion == "" {
22+
// Since Go 1.21, running 'go version' in a directory with a 'go.mod' file will attempt to
23+
// download the version of Go specified in there. That may either fail or result in us just
24+
// being told what's already in 'go.mod'. Setting 'GOTOOLCHAIN' to 'local' will force it
25+
// to use the local Go toolchain instead.
26+
cmd := exec.Command("go", "version")
27+
cmd.Env = append(os.Environ(), "GOTOOLCHAIN=local")
28+
out, err := cmd.CombinedOutput()
29+
30+
if err != nil {
31+
log.Fatalf("Unable to run the go command, is it installed?\nError: %s", err.Error())
32+
}
33+
34+
goVersion = parseGoVersion(string(out))
35+
}
36+
return goVersion
37+
}
38+
39+
// The 'go version' command may output warnings on separate lines before
40+
// the actual version string is printed. This function parses the output
41+
// to retrieve just the version string.
42+
func parseGoVersion(data string) string {
43+
var lastLine string
44+
sc := bufio.NewScanner(strings.NewReader(data))
45+
for sc.Scan() {
46+
lastLine = sc.Text()
47+
}
48+
return strings.Fields(lastLine)[2]
49+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package toolchain
2+
3+
import "testing"
4+
5+
func TestParseGoVersion(t *testing.T) {
6+
tests := map[string]string{
7+
"go version go1.18.9 linux/amd64": "go1.18.9",
8+
"warning: GOPATH set to GOROOT (/usr/local/go) has no effect\ngo version go1.18.9 linux/amd64": "go1.18.9",
9+
}
10+
for input, expected := range tests {
11+
actual := parseGoVersion(input)
12+
if actual != expected {
13+
t.Errorf("Expected parseGoVersion(\"%s\") to be \"%s\", but got \"%s\".", input, expected, actual)
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)