mirror of
https://github.com/github/codeql.git
synced 2026-01-29 14:23:03 +01:00
autobuilder: Test for vendor inconsistency
This commit is contained in:
committed by
Chris Smowton
parent
28c69743a4
commit
852ae9397b
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/mod/semver"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/url"
|
||||
@@ -44,12 +45,17 @@ variable is 32.
|
||||
fmt.Fprintf(os.Stderr, "Usage:\n\n %s\n", os.Args[0])
|
||||
}
|
||||
|
||||
var goVersion = ""
|
||||
|
||||
func getEnvGoVersion() string {
|
||||
gover, err := exec.Command("go", "version").CombinedOutput()
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to run the go command, is it installed?\nError: %s", err.Error())
|
||||
if goVersion == "" {
|
||||
gover, err := exec.Command("go", "version").CombinedOutput()
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to run the go command, is it installed?\nError: %s", err.Error())
|
||||
}
|
||||
goVersion = strings.Fields(string(gover))[2]
|
||||
}
|
||||
return strings.Fields(string(gover))[2]
|
||||
return goVersion
|
||||
}
|
||||
|
||||
func run(cmd *exec.Cmd) bool {
|
||||
@@ -141,6 +147,40 @@ const (
|
||||
Glide
|
||||
)
|
||||
|
||||
// ModMode corresponds to the possible values of the -mod flag for the Go compiler
|
||||
type ModMode int
|
||||
|
||||
const (
|
||||
ModUnset ModMode = iota
|
||||
ModReadonly
|
||||
ModMod
|
||||
ModVendor
|
||||
)
|
||||
|
||||
func (m ModMode) String() string {
|
||||
switch m {
|
||||
case ModUnset:
|
||||
return ""
|
||||
case ModReadonly:
|
||||
return "-mod=readonly"
|
||||
case ModMod:
|
||||
return "-mod=mod"
|
||||
case ModVendor:
|
||||
return "-mod=vendor"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// modModIfSupported returns `ModMod` if that flag is supported, or `ModUnset` if it is not, in
|
||||
// which case the behavior should be identical to `ModMod`.
|
||||
func modModIfSupported() ModMode {
|
||||
if semver.Compare(getEnvGoVersion(), "1.14") < 0 {
|
||||
return ModUnset
|
||||
} else {
|
||||
return ModMod
|
||||
}
|
||||
}
|
||||
|
||||
// addVersionToMod add a go version directive, e.g. `go 1.14` to a `go.mod` file.
|
||||
func addVersionToMod(goMod []byte, version string) bool {
|
||||
cmd := exec.Command("go", "mod", "edit", "-go="+version)
|
||||
@@ -174,6 +214,7 @@ func main() {
|
||||
// determine how to install dependencies and whether a GOPATH needs to be set up before
|
||||
// extraction
|
||||
depMode := GoGetNoModules
|
||||
modMode := ModUnset
|
||||
needGopath := true
|
||||
if util.FileExists("go.mod") {
|
||||
depMode = GoGetWithModules
|
||||
@@ -189,8 +230,10 @@ func main() {
|
||||
|
||||
// if a vendor/modules.txt file exists, we assume that there are vendored Go dependencies, and
|
||||
// skip the dependency installation step and run the extractor with `-mod=vendor`
|
||||
hasVendor := util.FileExists("vendor/modules.txt")
|
||||
if hasVendor {
|
||||
if util.FileExists("vendor/modules.txt") {
|
||||
modMode = ModVendor
|
||||
}
|
||||
if modMode == ModVendor {
|
||||
// fix go vendor issues with go versions >= 1.14 when no go version is specified in the go.mod
|
||||
// if this is the case, and dependencies were vendored with an old go version (and therefore
|
||||
// do not contain a '## explicit' annotation, the go command will fail and refuse to do any
|
||||
@@ -212,7 +255,7 @@ func main() {
|
||||
log.Println("Adding a version directive to the go.mod file as the modules.txt does not have explicit annotations")
|
||||
if !addVersionToMod(goMod, "1.13") {
|
||||
log.Println("Failed to add a version to the go.mod file to fix explicitly required package bug; not using vendored dependencies")
|
||||
hasVendor = false
|
||||
modMode = modModIfSupported()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -336,7 +379,7 @@ func main() {
|
||||
tryBuild("build.sh", "./build.sh")
|
||||
|
||||
if !buildSucceeded {
|
||||
if hasVendor {
|
||||
if modMode == ModVendor {
|
||||
log.Printf("Skipping dependency installation because a Go vendor directory was found.")
|
||||
} else {
|
||||
// automatically determine command to install dependencies
|
||||
@@ -422,6 +465,20 @@ func main() {
|
||||
run(install)
|
||||
}
|
||||
|
||||
if modMode == ModVendor {
|
||||
// test if running `go` with -mod=vendor works, and if it doesn't, try to fallback to -mod=mod
|
||||
// or not set if the go version < 1.14.
|
||||
vendorCheckCmd := exec.Command("go", "list", "-mod=vendor", "./...")
|
||||
outp, err := vendorCheckCmd.CombinedOutput()
|
||||
if err != nil {
|
||||
badVendorRe := regexp.MustCompile(`(?m)^go: inconsistent vendoring in .*:$`)
|
||||
if badVendorRe.Match(outp) {
|
||||
modMode = modModIfSupported()
|
||||
log.Println("The vendor directory is not consistent with the go.mod; not using vendored dependencies.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// extract
|
||||
mypath, err := os.Executable()
|
||||
if err != nil {
|
||||
@@ -438,14 +495,8 @@ func main() {
|
||||
}
|
||||
|
||||
var cmd *exec.Cmd
|
||||
// check for `vendor/modules.txt` and not just `vendor` in order to distinguish non-go vendor dirs
|
||||
if depMode == GoGetWithModules && hasVendor {
|
||||
log.Printf("Running extractor command '%s -mod=vendor ./...' from directory '%s'.\n", extractor, cwd)
|
||||
cmd = exec.Command(extractor, "-mod=vendor", "./...")
|
||||
} else {
|
||||
log.Printf("Running extractor command '%s ./...' from directory '%s'.\n", extractor, cwd)
|
||||
cmd = exec.Command(extractor, "./...")
|
||||
}
|
||||
log.Printf("Running extractor command '%s %s ./...' from directory '%s'.\n", extractor, modMode, cwd)
|
||||
cmd = exec.Command(extractor, modMode.String(), "./...")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
|
||||
Reference in New Issue
Block a user