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

x/tools/gopls: confusing behavior when using a go.work with duplicate module paths #53933

Closed
esimov opened this issue Jul 8, 2022 · 35 comments
Closed
Assignees
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@esimov
Copy link

esimov commented Jul 8, 2022

What version of Go, VS Code & VS Code Go extension are you using?

Version Information
  • Run go version to get version of Go from the VS Code integrated terminal.
    • go version go1.18.3 linux/amd64
  • Run gopls -v version to get version of Gopls from the VS Code integrated terminal.
    • golang.org/x/tools/gopls v0.9.0
  • Run code -v or code-insiders -v to get version of VS Code or VS Code Insiders.
    • 1.69.0
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/esimo/.cache/go-build"
GOENV="/home/esimo/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/esimo/projects/Go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/esimo/projects/Go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.18.3"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/esimo/projects/Go/src/esimov/go-generics/go.mod"
GOWORK="/home/esimo/projects/Go/src/esimov/go.work"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1041229074=/tmp/go-build -gno-record-gcc-switches"

Share the Go related settings you have added/edited

"go.toolsManagement.autoUpdate": true,
"go.alternateTools": {},
"go.formatTool":"goimports",
"go.useLanguageServer": true,
"[go]": {
    "editor.tabSize": 8,
    "editor.insertSpaces": false,
    "editor.detectIndentation": true
}

Describe the bug

I'm working on a WSL environment and Vscode suddenly stopped showing the suggestions and the code autocompletion functionality has stopped working too. I've tried reinstalling the Go tools by pressing CTRL+Shift+P and selecting Go: Install/Update Tools. I ran also the go mod tidy command to update the required packages. Another attempt was to execute go work use -r ./, because this helped in this case golang/vscode-go#2259, but didn't helped here. Instead I was getting something like in the snapshot below:

Screenshot 2022-07-08 130438

The package autoimport also is not working anymore. I'm out of ideas what else could I try.

@findleyr
Copy link
Contributor

findleyr commented Jul 8, 2022

Hi, could you try restarting gopls and collecting logs, as described here?
https://github.com/golang/vscode-go/blob/master/docs/troubleshooting.md#restart-gopls

@wtask
Copy link

wtask commented Jul 8, 2022

Yes, when your source contain syntax errors, the autocompletion stops working in most cases. On your screenshot you have an error, you create a variable assert and import assert package at the same time. This cannot be resolved by gopls as I think.

@esimov
Copy link
Author

esimov commented Jul 8, 2022

@wtask no, it's not that case. Even if I'm changing the variable name to something else, it's still not working. BTW the autocompletion and suggestion is not working on other workspaces/projects of mine.

@esimov
Copy link
Author

esimov commented Jul 8, 2022

@findleyr I have tried also to restart gopls, but it's still not working.

@findleyr
Copy link
Contributor

findleyr commented Jul 8, 2022

@esimov can you plesae try capturing logs? That will help us diagnose the problem.

@wtask
Copy link

wtask commented Jul 8, 2022

@wtask no, it's not that case. Even if I'm changing the variable name to something else, it's still not working. BTW the autocompletion and suggestion is not working on other workspaces/projects of mine.

@esimov Do you save the source after renaming?

@esimov
Copy link
Author

esimov commented Jul 8, 2022

It's not needed to save it after renaming, it should work instantly on typing, at least it worked that way until I have encountered this problem.

@findleyr
Copy link
Contributor

findleyr commented Jul 8, 2022

Correct, saving shouldn't matter in this case.

The likely scenario is that you were broken by the upgrade to gopls@v0.9.0, but before downgrading I would like to capture logs so that we can understand the failure.

@esimov
Copy link
Author

esimov commented Jul 8, 2022

These are the errors I'm getting:

[Error - 4:48:17 PM] 2022/07/08 16:48:17 imports fixes: AllImportsFixes: found module "github.com/gorilla/websocket" twice in the workspace
	file="/home/.../cache.go"

[Error - 4:48:17 PM] 2022/07/08 16:48:17 imports fixes: AllImportsFixes: found module "github.com/gorilla/websocket" twice in the workspace
	file="/home/.../range_test.go"

[Error - 4:48:17 PM] 2022/07/08 16:48:17 imports fixes: AllImportsFixes: found module "github.com/gorilla/websocket" twice in the workspace
	file="/home/.../range_test.go"

I'm not sure why gorilla websocket is considered to be interfered with my module, since I don't use it at all. I'm using in another module, but as I mentioned I didn't had this problem before updating to the latest vscode version, so it' might be related to an issue in the latest release.

@findleyr
Copy link
Contributor

findleyr commented Jul 8, 2022

Thank you for that. This is helpful.

Are you using either a go.work file, or the experimentalWorkspaceModule setting? (EDIT: based on settings it does not appear that experimentalWorkspaceModule is in use)

@esimov
Copy link
Author

esimov commented Jul 8, 2022

Yes, I do have a go.work file and in the root of my projects directory. No, I'm not using experimentalWorkspaceModul setting and I don't even know what is it.

@findleyr
Copy link
Contributor

findleyr commented Jul 8, 2022

Got it. I believe I have found the bug. We are failing on some old logic for the experimentalWorkspaceModule setting even though it is not active. You shouldn't need to know what that settings is: it is deprecated in favor of go.work.

Can you try removing all but one module from your go.work, and confirm whether this makes the problem go away when working on that one module?

@esimov
Copy link
Author

esimov commented Jul 8, 2022

I have already tried it, but the issue didn't went away. As it might help you in identifying the problem the gorilla websocket module is saved into the vendor folder, so it's not imported directly, it's loaded from the vendor folder, so this package is showing in two places, but in different vendor folders.

./project1/vendor/github.com/gorilla/websocket
./project2/vendor/github.com/gorilla/websocket

Note: I have replaced the actual project names.

@esimov
Copy link
Author

esimov commented Jul 15, 2022

Are there any updates about the issue?

@dzpt
Copy link

dzpt commented Jul 18, 2022

I have the same issue, no auto suggestion anymore.
golang.org/x/tools/gopls v0.9.1
go1.18.4 darwin/amd64
gotta jump back to the previous version gopls 0.8.4.

@findleyr
Copy link
Contributor

This is a gopls regression that we will fix for v0.9.2, scheduled for early August (though once it is fixed you can of course rebuild gopls from master).

However, I am not able to reproduce with a go.work file. @esimov it should not be possible to hit this error if you have a go.work file using project1 and project2. @esimov where is your go.work file? Is it in a parent directory of ./parent1 and ./parent2?

@dzpt thank you for the signal boost, and for sharing that this does not affect v0.8.4.

Transferring to the gopls issue tracker.

@findleyr findleyr changed the title Vscode suggestions and autocompletion is not working x/tools/gopls: spurious errors about vendor directories when using go.work Jul 18, 2022
@findleyr findleyr transferred this issue from golang/vscode-go Jul 18, 2022
@gopherbot gopherbot added Tools This label describes issues relating to any tools in the x/tools repository. gopls Issues related to the Go language server, gopls. labels Jul 18, 2022
@gopherbot gopherbot added this to the Unreleased milestone Jul 18, 2022
@findleyr
Copy link
Contributor

CC @hyangah

@gopherbot
Copy link

Change https://go.dev/cl/417593 mentions this issue: internal/lsp/cache: don't build the workspace module unless it is needed

@esimov
Copy link
Author

esimov commented Jul 18, 2022

@findleyr with an earlier version of gopls as suggested by @dzpt is working, but still the package autoimport is still not working.

@esimov
Copy link
Author

esimov commented Jul 18, 2022

@findleyr

where is your go.work file? Is it in a parent directory of ./parent1 and ./parent2

exactly.

@findleyr
Copy link
Contributor

Progress on this has been a bit slow because several team members have been out (myself included), but understanding and fixing this is among our top priorities.

However, I am still unable to reproduce this. Given the workspace layout below, everything works fine. I have two vendored copies of "github.com/gorilla/websocket" in the workspace, and everything still works.

A couple additional questions:

  • Which folder(s) are you opening in VS Code?
  • Does your go.work happen to be inside a directory named /vendor/? (in other words, is your workspace itself in a (possibly nested) subdirectory of a "vendor" directory?)
issue2324]> ls -R
.:
go.work  go.work.sum  mod1  mod2

./mod1:
go.mod  go.sum  lib  main.go  vendor

./mod1/lib:
lib.go

./mod1/vendor:
github.com  modules.txt

./mod1/vendor/github.com:
gorilla

./mod1/vendor/github.com/gorilla:
websocket

./mod1/vendor/github.com/gorilla/websocket:
AUTHORS         conn.go  json.go  mask_safe.go  README.md             tls_handshake.go
client.go       doc.go   LICENSE  prepared.go   server.go             util.go
compression.go  join.go  mask.go  proxy.go      tls_handshake_116.go  x_net_proxy.go

./mod2:
foo.go  go.mod  go.sum  main.go  vendor

./mod2/vendor:
github.com  modules.txt

./mod2/vendor/github.com:
gorilla

./mod2/vendor/github.com/gorilla:
websocket

./mod2/vendor/github.com/gorilla/websocket:
AUTHORS                 client.go       conn_write.go         json.go  mask_safe.go  README.md    trace.go
client_clone.go         compression.go  conn_write_legacy.go  LICENSE  prepared.go   server.go    util.go
client_clone_legacy.go  conn.go         doc.go                mask.go  proxy.go      trace_17.go  x_net_proxy.go

@esimov
Copy link
Author

esimov commented Jul 24, 2022

Does your go.work happen to be inside a directory named /vendor/? (in other words, is your workspace itself in a (possibly nested) subdirectory of a "vendor" directory?)

No, it's not. It's in the root directory of where my projects are located.

As a side note, if I'm reverting gopls to v0.8.4 these errors are not showing anymore. Another annoying thing which is quite hard to explain is that from time-to-time the package autoimport functionality stopped working. In this case I need to run go work use -r . to make it working again.

@findleyr
Copy link
Contributor

Since I don't reproduce this using the workspace above, I wonder if the "AllImportsFixes" error may be a red herring: that particular error should not necessarily prevent other functionality.

@esimov could you please confirm the directory you open from vs code? If possible, could you (or anyone else) also please share a full log from a session that exhibits the behavior?

@findleyr
Copy link
Contributor

findleyr commented Jul 24, 2022

Another note: https://go.dev/cl/417593 avoids the reported error. Because this may be a red herring I am not sure if it will fix the problem for you, but it would be interesting if you were to try using it:

EDIT: after repro'ing I can see that this doesn't yet fix the problem.

@findleyr
Copy link
Contributor

Aha, I believe I have reproduced the behavior you are observing.

Your comment about go work use -r . was key: it looks like these vendored modules were not created using go mod vendor, but rather with direct git checkouts, in which case they would have go.mod files that would be discovered by go work use -r .. Doing that does allow me to reproduce the errors you see. It also explains why this error was not more widely reported.

I should be able to fix this tomorrow and cut a prerelease. However, in the meantime you should be able to work around this by removing the vendored modules from your go.work file. Please let us know whether that resolves the issue for you (@esimov or anyone else who is experiencing the same problems).

I am not sure whether this warrants an ad-hoc patch release next week, assuming the workaround above (removing the vendored modules from your go.work file) resolves the issue. It does seem to be a very confusing and poor user experience, but one that perhaps affects only a small fraction of users. We'll discuss this tomorrow.

@findleyr
Copy link
Contributor

Ok, assuming folks can confirm that updating their go.work fixes the problem, here's the outcome of my investigation:

  • due to the duplicate requirements, the workspace was never valid, even at gopls v0.8.4, because our go.work parsing does some additional validation, rather than relying on e.g. go list -m all.
  • ...but the go command's handling of duplicate module paths is confusing to me: it seems to silently take the latest 'use' directive, without error
  • https://go.dev/cl/400822 "fixed" our logic for deriving workspace packages to depend on the go.work file (which gopls detects as invalid), and so the ad-hoc open package is not considered part of the workspace
  • gopls' completion handle gets the current file in "workspace mode", which for the open file is now "parseExported", meaning it doesn't contain function bodies and therefore can't complete the selector expression. This just seems wrong.
  • generally, our error handling for all this is not at all helpful. If we had a go command error, it would have been presented to the user, but as mentioned above the go command is surprisingly happy.

So, there are many things to fix, but also I don't understand the go command behavior here. (CC @bcmills for questions about the go command behavior with respect to duplicated module paths).

@bcmills
Copy link
Contributor

bcmills commented Jul 25, 2022

...but the go command's handling of duplicate module paths is confusing to me: it seems to silently take the latest 'use' directive, without error

If so, I would call that a cmd/go bug. The workspace should contain at most one module per module path.

@esimov
Copy link
Author

esimov commented Jul 26, 2022

@findleyr in many cases I'm opting to load modules from the vendor folder, because it happens, that due to the changes occurred in the dependent packages, these are causing breaking code changes and it's quite inconvenient in many cases to update the code to the latest release. Another reason why I'm loading the module dependencies from the vendor folder is missing or incomplete functionalities which could be extended to my own needs. What is strange is that gopls is complaining about the same module is loaded twice, but from different vendor folder.

@findleyr findleyr changed the title x/tools/gopls: spurious errors about vendor directories when using go.work x/tools/gopls: confusing behavior when using a go.work with duplicate module paths Jul 26, 2022
@findleyr
Copy link
Contributor

@esimov there can only be one module per module path in a go.work file. This is true both for gopls and for the go command: the fact that the go command was not returning errors for you is a bug (#54048): the go command was using whichever vendored copy appeared last in the go.work file.

As a corollary: vendoring does not work as expected when using go.work. In the future, the go command will not add vendored modules via go work -r: #51710.

To work on two different copies of a module, open two separate VS Code workspace folders using different go.work files.

This is a confusing UX. We'll use this issue to track improving that experience in gopls.

@esimov
Copy link
Author

esimov commented Jul 26, 2022

In the future, the go command will not add vendored modules via go work -r.

That wouldn't be a problem until the desired functionality is not affected (a possible side effect would be using different versions of the same package as vendored modules).

To work on two different copies of a module, open two separate VS Code workspace folders using different go.work files

That's not quite user friendly in my opinion, but I can live with it if we don't have a better approach.

@hyangah
Copy link
Contributor

hyangah commented Jul 26, 2022

My understanding is that vendored modules aren't complete copies of the original modules. They contain only packages required for the main module. When a workspace containing module A and B, and both A and B have dependency on a module C, there is no guarantee that the C under A's and B's vendor directories have compatible contents. Some packages required for B may not exist in C vendored for A.
I think a better approach is to check out the complete copy of C module somewhere and load that in the workspace.

gopherbot pushed a commit to golang/tools that referenced this issue Jul 27, 2022
When a go.work file fails to validate, the workspace is left in an
invalid state: we will detect that the workspace is defined by the
go.work, but will not actually parse any active modules. This should be
a critical error.

Fix this by adding allowing the workspace to surface critical errors via
a new cache.workspace.criticalError method.

Additionally:
 - only build the workspace mod file in workspace.build if the mode is
   fileSystemWorkspace (in all other modes the modfile is already
   determined)
 - rename workspace.invalidate to workspace.Clone, to be consistent with
   other data structures
 - rename CriticalError.DiagList to CriticalError.Diagnostics
 - add several TODOs for observations while reading the code
 - create a new file for regtests related to broken workspaces
 - make the regtest sandbox panic when duplicate paths are present in
   the sandbox file set (an error I made while writing the test)

Updates golang/go#53933

Change-Id: If8625ab190129bc9c57e784314bc9cc92644c955
Reviewed-on: https://go-review.googlesource.com/c/tools/+/417593
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
@findleyr
Copy link
Contributor

findleyr commented Aug 4, 2022

Closing as I think the "confusing" bit of this should hopefully be resolved by the new error message.

Opened #54261 for generally improving the experience of working on packages outside the workspace.

@findleyr findleyr closed this as completed Aug 4, 2022
@findleyr findleyr self-assigned this Aug 8, 2022
@esimov
Copy link
Author

esimov commented Aug 12, 2022

A new gopls has been released but unfortunately the issue I have mentioned related to the autocompletion shown in the snapshot is still not fixed.

@findleyr
Copy link
Contributor

@esimov the fix here was to make it an error when there are duplicate module paths in modules in your go.work file. We do not plan to change the restriction that there can only be one module per module path in your go.work: this is fundamental to the design of go workspaces.

#54261 tracks improving the user experience such that some features will still work even if the go.work file is broken.

@esimov
Copy link
Author

esimov commented Nov 24, 2022

As a follow up, I'm sorry to say, but unfortunately the last gopls version which is working with the above described configuration and project settings is v0.8.4. I was waiting to show up v0.9 and later on v0.10, but none of them are working: the autocompletion is broken completely.

@golang golang locked and limited conversation to collaborators Nov 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

8 participants