Skip to content

Godef fails in dependency module directories where no go.mod is present #124

@teeters

Description

@teeters

Reproduction steps:

  1. Install go version 1.16+ or export GO111MODULE=on
  2. 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
  3. 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
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions