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: support multi-module workspaces #32394

Closed
johan-lejdung opened this issue Jun 2, 2019 · 101 comments
Closed

x/tools/gopls: support multi-module workspaces #32394

johan-lejdung opened this issue Jun 2, 2019 · 101 comments
Labels
gopls Issues related to the Go language server, gopls. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@johan-lejdung
Copy link

johan-lejdung commented Jun 2, 2019

I'm using go version go1.12.5 darwin/amd64 and the latest gopls release and the latest go extension in VSCode.

So I'm working a a project with a rather weird project structure for a Go project. It's a mono-repo of sorts. Here is the basic structure:

<config_files>
services/
- go_service1
- go_service2
README.MD

I usually open up the entire workspace in VSCode when I work in this project. With that I've noticed a rather weird (or maybe not) behaviour from gopls.

You see it's looking at code in the wrong mod versions. I've discovered that it's because it's reading a go.mod file that were in the root of the workspace - which has since been removed. That go.mod file contained an old version of a module. Even though I were actually working in go_service1 it preferred that one. I realized it's most likely because VSCode is invoking gopls from the workspace level, since it works perfectly if i open up either of the service-folders in a separate window.

I didn't find any flags that I could set in gopls. Is it possible to configure how gopls works with modules? To properly support working in monorepo's like this?

This issue were spawned from this discussion: microsoft/vscode-go#2490

@gopherbot gopherbot added this to the Unreleased milestone Jun 2, 2019
@gopherbot gopherbot added the gopls Issues related to the Go language server, gopls. label Jun 2, 2019
@stamblerre
Copy link
Contributor

Right now, the best way to work with gopls in VSCode is to use Workspace Folders per module. For every go.mod file that you have, you should do "File" > "Add Folder to Workspace" and then add the module root.

@johan-lejdung
Copy link
Author

johan-lejdung commented Jun 4, 2019

Sure 👍, but are there any plans to implement a feature like this? I'm betting most editors have this issue, not just VSCode.

@stamblerre stamblerre added FeatureRequest NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Jun 5, 2019
@stamblerre stamblerre changed the title x/tools/cmd/gopls: mono-repo project x/tools/cmd/gopls: manage multiple module roots automatically Jun 5, 2019
@slnt
Copy link

slnt commented Jun 5, 2019

I am having a similar issue, and am currently using bingo right now since it does support this.

Our monorepo has a similar setup as the issue reporters, where we have several services with their own go.mods, and most of them import another local library that contains common code for setting up logs and such.

root/
  deployables/
    service1/
      go.mod
    service2/
      /go.mod
  lib/
    common/
      go.mod

My experience has been that gopls doesn't load the full repository, and then is unable to figure out where things are.

@ermik
Copy link

ermik commented Jul 18, 2019

How can I explicitly specify the module root for a given project?

@stamblerre
Copy link
Contributor

This depends on your editor - if you are using VSCode, this can be done via File -> Add Folder to Workspace.

@ermik
Copy link

ermik commented Jul 18, 2019

@stamblerre thank you for quick reply. I understand and can work with the limitation of having one module per-hierarchy, but it does not appear to matter unless the root folder is the one that has .mod. My projects pull supporting files one step up and have go.mod in {workspaceFolder}/src subfolder. Usually, for things like running debug, I can set the root:

{
    "version": "0.2.0",
    "configurations": [

        {
            "name": "Launch",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${workspaceFolder}/src", // <- specify where Go code is located
            "args": []
        }
    ]
}

Is there a similar workaround for gopls?

@stamblerre
Copy link
Contributor

Yes, for gopls to work correctly the root folder has to be the one that contains your go.mod file. I do not believe there is any such workaround for gopls, but we will ultimately try to resolve this bug to make this work more seamlessly.

@ermik
Copy link

ermik commented Jul 18, 2019

If there is a code path you can point to I’d love to take a stab at restoring my normality.

@stamblerre
Copy link
Contributor

We still have to make some decisions about if this is the responsibility of gopls or of the editor. More likely than not, we would start off by making this change in VSCode-Go rather than in gopls.

@slnt
Copy link

slnt commented Jul 22, 2019

fwiw @stamblerre the scenario I mentioned above is handled by https://github.com/saibing/bingo.

I guess I did mention that in my original comment.

@stamblerre
Copy link
Contributor

@sint: The way that bingo does this is technically a "hack" (see saibing/bingo@169f54c). The module root is not necessarily the directory of the current file. A better solution would be to search for all directories containing mod files and notify gopls about them, but we still haven't made a final decision on how we want to implement this.

@arthurkiller
Copy link

I'm under vim+ale+gopls and facing the same problem.

And I can not go to references in the standard library, I'm not sure if this is the same problem.

@mochi-co
Copy link

mochi-co commented Apr 8, 2021

experimentalWorkspaceModule is also working for me perfectly. Huge thanks to everyone!

@deesejohn
Copy link

deesejohn commented Apr 9, 2021

I just started experiencing issues with this today. I'm having issues with this on wsl2 using Debian testing.

{
   "go.useLanguageServer": true,
   "gopls": {
        "experimentalWorkspaceModule": true,
    },
}

Here is my .bashrc

export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOROOT:$GOPATH:$GOBIN

image

I'm experiencing this issue when opening the root of this repository.
https://github.com/deesejohn/distributed-codenames

Edit:
I cloned the repository to a new directory and everything worked fine again. I saved the broken directory, if anyone is interested in debugging it.

Edit:
Happening again, but re-cloning the repo isn't solving the issue. I can open a single directory containing a go.mod but not the parent dir with two child go.mods.

@matloob
Copy link
Contributor

matloob commented Apr 28, 2021

Hi, I've filed a proposal (#45713) for a workspace mode and config file that could be used to support the same workspace across the go command and gopls. Feel free to provide feedback if the proposal helps (or doesn't)!

jgehrcke added a commit to opstrace/opstrace that referenced this issue May 12, 2021
In a previous commit, we deliberately decided
for using a workspace config file, and against
a local .vscode directory.

Previous commit message:

I could not find a way to configure multiple
folders per workspace when using the .vscode
directory. That makes sense: the .vscode directory
defines the current directory (that it is in)
as a workspace.

Instead, we need to have a multi-root
workspace which seemingly requires the
workspace settings file.

Ref: https://code.visualstudio.com/docs/editor/multi-root-workspaces

microsoft/vscode-go#2935
golang/go#32394

Signed-off-by: Dr. Jan-Philip Gehrcke <jp@opstrace.com>
MatApple pushed a commit to opstrace/opstrace that referenced this issue May 12, 2021
In a previous commit, we deliberately decided
for using a workspace config file, and against
a local .vscode directory.

Previous commit message:

I could not find a way to configure multiple
folders per workspace when using the .vscode
directory. That makes sense: the .vscode directory
defines the current directory (that it is in)
as a workspace.

Instead, we need to have a multi-root
workspace which seemingly requires the
workspace settings file.

Ref: https://code.visualstudio.com/docs/editor/multi-root-workspaces

microsoft/vscode-go#2935
golang/go#32394

Signed-off-by: Dr. Jan-Philip Gehrcke <jp@opstrace.com>
@stamblerre stamblerre moved this from To Do to P1 in gopls on-deck Aug 12, 2021
@behnood-eghbali
Copy link

I don't how you guys figured this out, but adding workspace folder and go.mod file worked for me! 😄️🚀️🎉️❤️

@dee-kryvenko
Copy link

dee-kryvenko commented Oct 4, 2021

Having multiple go modules in a single Workspace doesn't produce that old error anymore, but now I'm getting another error:

[Error - 11:37:33 AM] 2021/10/04 11:37:33 initial workspace load failed: found module "github.com/cloudposse/terraform-aws-ec2-bastion-server" twice in the workspace

And then it complains about that on any action. Auto completion, intellisense and etc doesn't work.

@hyangah
Copy link
Contributor

hyangah commented Oct 5, 2021

@dee-kryvenko Can you please check if you have the mentioned module twice in the workspace indeed? That won't work any way. And, ideally please file a separate issue with the details with how you configured your workspace (used go.work+go1.18 dev version, or used the experimental workspace module?) .

@dee-kryvenko
Copy link

dee-kryvenko commented Oct 5, 2021

Thanks - that was indeed the case. Well, not exactly - my terraform modules has been packaged together with their Terratest (Go Modules), and after Terraform got all dependencies unpacked under .terraform folder - the internals there was causing gopls to fail like that. I would never thought of that if not your comment, thanks @hyangah - though the error message is confusing, it was pointing me to go.mod files that legitimately had this module as a transitive dependency. It would have been helpful instead if it pointed me to all the locations the duplicated module actually declared at - not used as a dependency.

@IzioDev
Copy link

IzioDev commented Oct 13, 2021

It now works like a charm.

Thanks for the great changes you've made. ❤️

@upsampled
Copy link

Not sure if this is this ticket or a vs-code one needs to be opened, but this capability is doing something very weird to my go.mod, instead of listing the dependencies to keeps on reverting to (even after a go mod tidy):

module gopls-workspace

go 1.12

require gopls-workspace v1.9999999.0-goplsworkspace

replace gopls-workspace => $PROJECT_LOCAL_PATH

replace $PROJECT_IMPORT  =>  $PROJECT_LOCAL_PATH

So first off, is this the standard behavior? Will gopls work if I told it to kindly stop doing this as I definitly don't want local paths in a go.mod file?

@dee-kryvenko
Copy link

Now I get this, similar to what I was having before #32394 (comment):

[Error - 10:57:51 PM] 2021/11/01 22:57:51 imports fixes: AllImportsFixes: found module "main" twice in the workspace

Obviously I do have much more than one main package in my workspace and it is expected. I'm pretty sure it worked before the recent upgrade.

@StarpTech
Copy link

StarpTech commented Nov 6, 2021

Even with the workaround to open every module as a separate root, the extension cannot find references across modules in a monorepo. I think this is another issue?

@hyangah
Copy link
Contributor

hyangah commented Nov 8, 2021

@StarpTech My understanding is that modules open as separate workspace roots remain separate and gopls presents how go command would handle them. If you need to make it explicit that they are related, try Go1.18's go.work or use the experimental workspace module for older Go version.

@findleyr findleyr modified the milestones: gopls/on-deck, gopls/v0.8.0 Jan 27, 2022
ti-chi-bot pushed a commit to tikv/pd that referenced this issue Feb 18, 2022
…4658)

ref golang/go#32394

client: add the VS Code workspace file to handle the client module

Signed-off-by: JmPotato <ghzpotato@gmail.com>
@findleyr
Copy link
Contributor

findleyr commented Mar 3, 2022

gopls@v0.8.0 supports multi-module workspaces via integration with go.work files. However, I will leave this issue open until Go 1.18 comes out.

@findleyr findleyr modified the milestones: gopls/v0.8.0, gopls/v0.8.1 Mar 3, 2022
@findleyr findleyr modified the milestones: gopls/v0.8.1, gopls/v0.8.2 Mar 14, 2022
@findleyr
Copy link
Contributor

Go 1.18 is out. Please try out using gopls@v0.8.1 with go.work as described at https://github.com/golang/tools/blob/master/gopls/doc/workspace.md#go-workspaces-go-118

Right now, this works best if you create the go.work file before starting gopls. We're working on improving this workflow.

I'm going to close this issue in favor of other open issues to improve our go.work support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gopls Issues related to the Go language server, gopls. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
No open projects
Development

No branches or pull requests