Skip to content

Commit e9bd85e

Browse files
authored
Merge pull request github#16704 from github/mbg/go/fix/build-scripts-running-more-than-once
2 parents 202d77d + 0f56e40 commit e9bd85e

File tree

3 files changed

+56
-24
lines changed

3 files changed

+56
-24
lines changed

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

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func tryUpdateGoModAndGoSum(workspace project.GoWorkspace) {
168168
beforeGoSumFileInfo, beforeGoSumErr := os.Stat(goSumPath)
169169

170170
// run `go mod tidy -e`
171-
cmd := toolchain.TidyModule(goModDir)
171+
cmd := goMod.Tidy()
172172
res := util.RunCmd(cmd)
173173

174174
if !res {
@@ -320,8 +320,7 @@ func setGopath(root string) {
320320

321321
// Try to build the project with a build script. If that fails, return a boolean indicating
322322
// that we should install dependencies in the normal way.
323-
func buildWithoutCustomCommands(modMode project.ModMode) bool {
324-
shouldInstallDependencies := false
323+
func buildWithoutCustomCommands(workspaces []project.GoWorkspace) {
325324
// try to run a build script
326325
scriptSucceeded, scriptsExecuted := autobuilder.Autobuild()
327326
scriptCount := len(scriptsExecuted)
@@ -335,13 +334,19 @@ func buildWithoutCustomCommands(modMode project.ModMode) bool {
335334
log.Println("Unable to find any build scripts, continuing to install dependencies in the normal way.")
336335
}
337336

338-
shouldInstallDependencies = true
339-
} else if toolchain.DepErrors("./...", modMode.ArgsForGoVersion(toolchain.GetEnvGoSemVer())...) {
340-
log.Printf("Dependencies are still not resolving after executing %d build script(s), continuing to install dependencies in the normal way.\n", scriptCount)
337+
// Install dependencies for all workspaces.
338+
for i, _ := range workspaces {
339+
workspaces[i].ShouldInstallDependencies = true
340+
}
341+
} else {
342+
for i, workspace := range workspaces {
343+
if toolchain.DepErrors("./...", workspace.ModMode.ArgsForGoVersion(toolchain.GetEnvGoSemVer())...) {
344+
log.Printf("Dependencies are still not resolving for `%s` after executing %d build script(s), continuing to install dependencies in the normal way.\n", workspace.BaseDir, scriptCount)
341345

342-
shouldInstallDependencies = true
346+
workspaces[i].ShouldInstallDependencies = true
347+
}
348+
}
343349
}
344-
return shouldInstallDependencies
345350
}
346351

347352
// Build the project with custom commands.
@@ -428,7 +433,7 @@ func installDependencies(workspace project.GoWorkspace) {
428433
path := filepath.Dir(module.Path)
429434

430435
if util.DirExists(filepath.Join(path, "vendor")) {
431-
vendor := toolchain.VendorModule(path)
436+
vendor := module.Vendor()
432437
log.Printf("Synchronizing vendor file using `go mod vendor` in %s.\n", path)
433438
util.RunCmd(vendor)
434439
}
@@ -553,23 +558,25 @@ func installDependenciesAndBuild() {
553558
// Track all projects which could not be extracted successfully
554559
var unsuccessfulProjects = []string{}
555560

556-
// Attempt to extract all workspaces; we will tolerate individual extraction failures here
557-
for i, workspace := range workspaces {
561+
// Attempt to automatically fix issues with each workspace
562+
for _, workspace := range workspaces {
558563
goVersionInfo := workspace.RequiredGoVersion()
559564

560565
fixGoVendorIssues(&workspace, goVersionInfo != nil)
561566

562567
tryUpdateGoModAndGoSum(workspace)
568+
}
563569

564-
// check whether an explicit dependency installation command was provided
565-
inst := util.Getenv("CODEQL_EXTRACTOR_GO_BUILD_COMMAND", "LGTM_INDEX_BUILD_COMMAND")
566-
shouldInstallDependencies := false
567-
if inst == "" {
568-
shouldInstallDependencies = buildWithoutCustomCommands(workspace.ModMode)
569-
} else {
570-
buildWithCustomCommands(inst)
571-
}
570+
// check whether an explicit dependency installation command was provided
571+
inst := util.Getenv("CODEQL_EXTRACTOR_GO_BUILD_COMMAND", "LGTM_INDEX_BUILD_COMMAND")
572+
if inst == "" {
573+
buildWithoutCustomCommands(workspaces)
574+
} else {
575+
buildWithCustomCommands(inst)
576+
}
572577

578+
// Attempt to extract all workspaces; we will tolerate individual extraction failures here
579+
for i, workspace := range workspaces {
573580
if workspace.ModMode == project.ModVendor {
574581
// test if running `go` with -mod=vendor works, and if it doesn't, try to fallback to -mod=mod
575582
// or not set if the go version < 1.14. Note we check this post-build in case the build brings
@@ -580,7 +587,7 @@ func installDependenciesAndBuild() {
580587
}
581588
}
582589

583-
if shouldInstallDependencies {
590+
if workspace.ShouldInstallDependencies {
584591
if workspace.ModMode == project.ModVendor {
585592
log.Printf("Skipping dependency installation because a Go vendor directory was found.")
586593
} else {

go/extractor/project/project.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package project
33
import (
44
"log"
55
"os"
6+
"os/exec"
67
"path/filepath"
78
"regexp"
89
"slices"
@@ -47,6 +48,16 @@ func (module *GoModule) RequiredGoVersion() util.SemVer {
4748
}
4849
}
4950

51+
// Runs `go mod tidy` for this module.
52+
func (module *GoModule) Tidy() *exec.Cmd {
53+
return toolchain.TidyModule(filepath.Dir(module.Path))
54+
}
55+
56+
// Runs `go mod vendor -e` for this module.
57+
func (module *GoModule) Vendor() *exec.Cmd {
58+
return toolchain.VendorModule(filepath.Dir(module.Path))
59+
}
60+
5061
// Represents information about a Go project workspace: this may either be a folder containing
5162
// a `go.work` file or a collection of `go.mod` files.
5263
type GoWorkspace struct {
@@ -56,6 +67,8 @@ type GoWorkspace struct {
5667
DepMode DependencyInstallerMode // A value indicating how to install dependencies for this workspace
5768
ModMode ModMode // A value indicating which module mode to use for this workspace
5869
Extracted bool // A value indicating whether this workspace was extracted successfully
70+
71+
ShouldInstallDependencies bool // A value indicating whether dependencies should be installed for this module
5972
}
6073

6174
// Represents a nullable version string.

go/extractor/toolchain/toolchain.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,14 @@ func RunList(format string, patterns []string, flags ...string) (string, error)
181181
return RunListWithEnv(format, patterns, nil, flags...)
182182
}
183183

184+
// Constructs a `go list` command with `format`, `patterns`, and `flags` for the respective inputs.
185+
func List(format string, patterns []string, flags ...string) *exec.Cmd {
186+
return ListWithEnv(format, patterns, nil, flags...)
187+
}
188+
184189
// Runs `go list`.
185190
func RunListWithEnv(format string, patterns []string, additionalEnv []string, flags ...string) (string, error) {
186-
args := append([]string{"list", "-e", "-f", format}, flags...)
187-
args = append(args, patterns...)
188-
cmd := exec.Command("go", args...)
189-
cmd.Env = append(os.Environ(), additionalEnv...)
191+
cmd := ListWithEnv(format, patterns, additionalEnv, flags...)
190192
out, err := cmd.Output()
191193

192194
if err != nil {
@@ -201,6 +203,16 @@ func RunListWithEnv(format string, patterns []string, additionalEnv []string, fl
201203
return strings.TrimSpace(string(out)), nil
202204
}
203205

206+
// Constructs a `go list` command with `format`, `patterns`, and `flags` for the respective inputs
207+
// and the extra environment variables given by `additionalEnv`.
208+
func ListWithEnv(format string, patterns []string, additionalEnv []string, flags ...string) *exec.Cmd {
209+
args := append([]string{"list", "-e", "-f", format}, flags...)
210+
args = append(args, patterns...)
211+
cmd := exec.Command("go", args...)
212+
cmd.Env = append(os.Environ(), additionalEnv...)
213+
return cmd
214+
}
215+
204216
// PkgInfo holds package directory and module directory (if any) for a package
205217
type PkgInfo struct {
206218
PkgDir string // the directory directly containing source code of this package

0 commit comments

Comments
 (0)