Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore more errors in go list #131

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 36 additions & 11 deletions go/packages/golist.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,17 @@ func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, q
// modCacheRegexp splits a path in a module cache into module, module version, and package.
var modCacheRegexp = regexp.MustCompile(`(.*)@([^/\\]*)(.*)`)

// noFileRe looks for a package name in a "no Go files in" errors line that is output by go list.
var noFileRe = regexp.MustCompile(`(?m)^go build ([\p{L}\p{Nd}\/.]+): (no Go files in.*)$`)

// cgoErrRe attempts to detect cgo errors from go list stderr output
var cgoErrRe = regexp.MustCompile(
`(collect2: error: ld returned)|(could not determine kind of name for C\.)|` +
`(fatal error: \S+.(c|h): No such file or directory)`)

// goListErrRe attempts to extract errors from go list stderr output
var goListErrRe = regexp.MustCompile(`(?m)^# ([\p{L}\p{Nd}\/.]+)\n((?:[^#].*\n)+)`)

func runNamedQueries(cfg *Config, driver driver, response *responseDeduper, queries []string) error {
// calling `go env` isn't free; bail out if there's nothing to do.
if len(queries) == 0 {
Expand Down Expand Up @@ -616,6 +627,8 @@ type jsonPackage struct {
ForTest string // q in a "p [q.test]" package, else ""
DepOnly bool

Gen bool // generated by this code

Error *jsonPackageError
}

Expand Down Expand Up @@ -688,11 +701,15 @@ func golistDriver(cfg *Config, rootsDirs func() *goInfo, words ...string) (*driv
}

if old, found := seen[p.ImportPath]; found {
if !reflect.DeepEqual(p, old) {
if p.Gen {
// new package is generated, skip it
continue
} else if !reflect.DeepEqual(p, old) {
return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath)
} else if !old.Gen {
// skip the duplicate if the old package wasn't generated
continue
}
// skip the duplicate
continue
}
seen[p.ImportPath] = p

Expand Down Expand Up @@ -934,15 +951,23 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
// a zero exit status and set an error on that package.
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") {
// try to extract package name from string
stderrStr := stderr.String()
var importPath string
colon := strings.Index(stderrStr, ":")
if colon > 0 && strings.HasPrefix(stderrStr, "go build ") {
importPath = stderrStr[len("go build "):colon]
for _, matches := range noFileRe.FindAllStringSubmatch(stderr.String(), -1) {
stdout.WriteString(fmt.Sprintf("\n"+`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q},"Gen": true}`,
matches[1], matches[2]))
}
output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
importPath, strings.Trim(stderrStr, "\n"))
return bytes.NewBufferString(output), nil
return stdout, nil
}

// Workaround for an instance of golang.org/issue/26755: go list -e will
// return a non-zero exit status if cgo preprocessing fails. But it should
// return a zero exit status and set an error on that package.
if len(stderr.String()) > 0 && cgoErrRe.MatchString(stderr.String()) {
for _, matches := range goListErrRe.FindAllStringSubmatch(stderr.String(), -1) {
stdout.WriteString(fmt.Sprintf("\n"+`{"ImportPath": %q,"Incomplete":true,"Error": {"Pos": "","Err": %q},"Gen": true}`,
matches[1], strings.Trim(matches[2], "\n")))
}

return stdout, nil
}

// Export mode entails a build.
Expand Down