-
Notifications
You must be signed in to change notification settings - Fork 140
Open
Description
Reproduction steps:
- Install go version 1.16+ or export GO111MODULE=on
- Go to the module directory of a module that does not include a go.mod file--for example, confluentinc's kafka client library: https://github.com/confluentinc/confluent-kafka-go
- Run godef on a function in the library. Observe that it fails to locate the source, even though the source is in the current directory:
.../kafka$ godef -f consumer_test.go Consumer.CommitMessage
godef: There must be at least one package that contains the file
Analysis:
godef uses the go env GOMOD command to determine whether modules are enabled. Unfortunately, this command for some reason returns the operating system's null device when no go.mod is present, as documented here. This means that when go.mod is not present, godef will attempt to use the module system but will be unable to find any modules.
Proposed solution:
Obviously there are various ways to work around this, such as setting GO111MODULE=auto. However users may not wish to do this, and it seems strictly better for godef to fall back to non-module mode than to fail. I therefore think this method in adapt.go should be modified to check whether GOMOD is equal to the system's null device:
func detectModuleMode(cfg *packages.Config) bool {
// first see if the config forces module mode
for _, e := range cfg.Env {
switch e {
case "GO111MODULE=off":
return false
case "GO111MODULE=on":
return true
}
}
// do a fast test for go.mod in the working directory
if _, err := os.Stat(filepath.Join(cfg.Dir, "go.mod")); !os.IsNotExist(err) {
return true
}
// fall back to invoking the go tool to see if it will pick module mode
cmd := exec.Command("go", "env", "GOMOD")
cmd.Env = cfg.Env
cmd.Dir = cfg.Dir
out, err := cmd.Output()
if err == nil {
return len(strings.TrimSpace(string(out))) > 0
}
// default to non module mode
return false
}
ALTree
Metadata
Metadata
Assignees
Labels
No labels