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

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

Open
teeters opened this issue Sep 23, 2021 · 1 comment · May be fixed by #125
Open

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

teeters opened this issue Sep 23, 2021 · 1 comment · May be fixed by #125

Comments

@teeters
Copy link

teeters commented Sep 23, 2021

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
}
@neo532
Copy link

neo532 commented Sep 26, 2021

I meet this,also.

@teeters teeters linked a pull request Sep 30, 2021 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants