Skip to content

Commit ae7ee31

Browse files
committed
Go: pass source root from autobuilder to extractor
This ensures the extractor can resolve the relative paths for files changed in the overlay.
1 parent b4b30b7 commit ae7ee31

File tree

4 files changed

+57
-19
lines changed

4 files changed

+57
-19
lines changed

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ func installDependencies(workspace project.GoWorkspace) {
448448
}
449449

450450
// Run the extractor.
451-
func extract(workspace project.GoWorkspace) bool {
451+
func extract(workspace project.GoWorkspace, sourceRoot string) bool {
452452
extractor, err := util.GetExtractorPath()
453453
if err != nil {
454454
log.Fatalf("Could not determine path of extractor: %v.\n", err)
@@ -459,6 +459,12 @@ func extract(workspace project.GoWorkspace) bool {
459459
extractorArgs = append(extractorArgs, workspace.ModMode.ArgsForGoVersion(toolchain.GetEnvGoSemVer())...)
460460
}
461461

462+
if util.IsOverlayExtraction() {
463+
// When we are extracting an overlay, pass the source root to the extractor so that it knows
464+
// how to resolve the relative paths in the list of changed files.
465+
extractorArgs = append(extractorArgs, "--source-root", sourceRoot)
466+
}
467+
462468
if len(workspace.Modules) == 0 {
463469
// There may be no modules if we are using e.g. Dep or Glide
464470
extractorArgs = append(extractorArgs, "./...")
@@ -587,6 +593,12 @@ func installDependenciesAndBuild() {
587593
buildWithCustomCommands(inst)
588594
}
589595

596+
// The autobuilder is invoked with its working directory set to the source directory.
597+
sourceRoot, err := os.Getwd()
598+
if err != nil {
599+
log.Fatalf("Failed to get current working directory: %s\n", err.Error())
600+
}
601+
590602
// Attempt to extract all workspaces; we will tolerate individual extraction failures here
591603
for i, workspace := range workspaces {
592604
if workspace.ModMode == project.ModVendor {
@@ -607,7 +619,7 @@ func installDependenciesAndBuild() {
607619
}
608620
}
609621

610-
workspaces[i].Extracted = extract(workspace)
622+
workspaces[i].Extracted = extract(workspace, sourceRoot)
611623

612624
if !workspaces[i].Extracted {
613625
unsuccessfulProjects = append(unsuccessfulProjects, workspace.BaseDir)
@@ -632,6 +644,8 @@ func installDependenciesAndBuild() {
632644
} else {
633645
log.Printf("Success: extraction succeeded for all %d discovered project(s).\n", len(workspaces))
634646
}
647+
648+
util.WriteOverlayBaseMetadata()
635649
}
636650

637651
func main() {

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ func usage() {
2424

2525
// extractTests is set (a) if we were manually commanded to extract tests via the relevant
2626
// environment variable / extractor option, or (b) we're mimicking a `go test` command.
27-
func parseFlags(args []string, mimic bool, extractTests bool) ([]string, []string, bool) {
27+
func parseFlags(args []string, mimic bool, extractTests bool) ([]string, []string, bool, string) {
2828
i := 0
2929
buildFlags := []string{}
30+
var sourceRoot string
3031
for ; i < len(args) && strings.HasPrefix(args[i], "-"); i++ {
3132
if args[i] == "--" {
3233
i++
@@ -61,6 +62,18 @@ func parseFlags(args []string, mimic bool, extractTests bool) ([]string, []strin
6162
} else {
6263
log.Fatalf("--mimic requires an argument, e.g. --mimic go")
6364
}
65+
case "--source-root":
66+
// The extractor can be called by the autobuilder with the working directory set to
67+
// the directory containing the workspace we're extracting, and this may be a
68+
// subdirectory of the actual source root. This argument lets us resolve paths that
69+
// are relative to that source root, e.g. for the list of overlay changed files.
70+
if i+1 < len(args) {
71+
i++
72+
sourceRoot = args[i]
73+
log.Printf("Source root is %s", sourceRoot)
74+
} else {
75+
log.Fatalf("--source-root requires an argument, e.g. --source-root /path/to/root")
76+
}
6477
}
6578
}
6679

@@ -93,14 +106,14 @@ func parseFlags(args []string, mimic bool, extractTests bool) ([]string, []strin
93106
cpuprofile = os.Getenv("CODEQL_EXTRACTOR_GO_CPU_PROFILE")
94107
memprofile = os.Getenv("CODEQL_EXTRACTOR_GO_MEM_PROFILE")
95108

96-
return buildFlags, args[i:], extractTests
109+
return buildFlags, args[i:], extractTests, sourceRoot
97110
}
98111

99112
func main() {
100113
util.SetLogLevel()
101114

102115
extractTestsDefault := os.Getenv("CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_TESTS") == "true"
103-
buildFlags, patterns, extractTests := parseFlags(os.Args[1:], false, extractTestsDefault)
116+
buildFlags, patterns, extractTests, sourceRoot := parseFlags(os.Args[1:], false, extractTestsDefault)
104117

105118
if cpuprofile != "" {
106119
f, err := os.Create(cpuprofile)
@@ -120,7 +133,7 @@ func main() {
120133
}
121134

122135
log.Printf("Build flags: '%s'; patterns: '%s'\n", strings.Join(buildFlags, " "), strings.Join(patterns, " "))
123-
err := extractor.ExtractWithFlags(buildFlags, patterns, extractTests)
136+
err := extractor.ExtractWithFlags(buildFlags, patterns, extractTests, sourceRoot)
124137
if err != nil {
125138
errString := err.Error()
126139
if strings.Contains(errString, "unexpected directory layout:") {

go/extractor/extractor.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,11 @@ func init() {
5858
}
5959
}
6060

61-
// Extract extracts the packages specified by the given patterns
62-
func Extract(patterns []string) error {
63-
return ExtractWithFlags(nil, patterns, false)
64-
}
65-
6661
// ExtractWithFlags extracts the packages specified by the given patterns and build flags
67-
func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool) error {
62+
func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool, sourceRoot string) error {
6863
startTime := time.Now()
6964

70-
extraction := NewExtraction(buildFlags, patterns)
65+
extraction := NewExtraction(buildFlags, patterns, sourceRoot)
7166
defer extraction.StatWriter.Close()
7267

7368
modEnabled := os.Getenv("GO111MODULE") != "off"
@@ -311,8 +306,6 @@ func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool)
311306

312307
extraction.WaitGroup.Wait()
313308

314-
util.WriteOverlayBaseMetadata()
315-
316309
log.Println("Done extracting packages.")
317310

318311
t := time.Now()
@@ -370,7 +363,7 @@ func (extraction *Extraction) GetNextErr(path string) int {
370363
return res
371364
}
372365

373-
func NewExtraction(buildFlags []string, patterns []string) *Extraction {
366+
func NewExtraction(buildFlags []string, patterns []string, sourceRoot string) *Extraction {
374367
hash := md5.New()
375368
io.WriteString(hash, "go")
376369
for _, buildFlag := range buildFlags {
@@ -382,7 +375,7 @@ func NewExtraction(buildFlags []string, patterns []string) *Extraction {
382375
}
383376
sum := hash.Sum(nil)
384377

385-
overlayChangeList := util.GetOverlayChanges()
378+
overlayChangeList := util.GetOverlayChanges(sourceRoot)
386379
var overlayChanges map[string]bool
387380
if overlayChangeList == nil {
388381
overlayChanges = nil

go/extractor/util/overlays.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@ import (
44
"encoding/json"
55
"log"
66
"os"
7+
"path/filepath"
78
)
89

10+
func IsOverlayExtraction() bool {
11+
_, present := os.LookupEnv("CODEQL_EXTRACTOR_GO_OVERLAY_METADATA_IN")
12+
return present
13+
}
14+
915
// If the relevant environment variable is set, indicating that we are extracting an overlay
1016
// database, GetOverlayChanges returns the list of relative paths of files that have changed (or
1117
// been deleted). Otherwise, it returns `nil`.
12-
func GetOverlayChanges() []string {
18+
func GetOverlayChanges(sourceRoot string) []string {
1319
if overlayChangesJsonPath, present := os.LookupEnv("CODEQL_EXTRACTOR_GO_OVERLAY_CHANGES"); present {
1420
log.Printf("Reading overlay changes from: %s", overlayChangesJsonPath)
1521

@@ -28,7 +34,19 @@ func GetOverlayChanges() []string {
2834
log.Fatalf("Failed to decode overlay changes JSON file: %s", err)
2935
}
3036

31-
return overlayData.Changes
37+
absPaths := make([]string, 0, len(overlayData.Changes))
38+
if sourceRoot == "" {
39+
// This shouldn't happen, because it implies the extractor was invoked in some way other
40+
// than from the autobuilder. However, we'll only attempt to build an overlay if there
41+
// exists an overlay _base_, and only the autobuilder writes the metadata file that
42+
// ensures a database is created as an overlay-base.
43+
log.Fatalf("Extractor is running in overlay mode, but --source-root was not provided")
44+
}
45+
for _, relPath := range overlayData.Changes {
46+
absPaths = append(absPaths, filepath.Clean(sourceRoot+"/"+relPath))
47+
}
48+
49+
return absPaths
3250
} else {
3351
return nil
3452
}

0 commit comments

Comments
 (0)