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: manage multiple module roots automatically #32394

Open
johan-lejdung opened this issue Jun 2, 2019 · 16 comments

Comments

@johan-lejdung
Copy link

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

@stamblerre

This comment has been minimized.

Copy link
Contributor

commented Jun 3, 2019

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

This comment has been minimized.

Copy link
Author

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 changed the title x/tools/cmd/gopls: mono-repo project x/tools/cmd/gopls: manage multiple module roots automatically Jun 5, 2019
@slnt

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Jul 18, 2019

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

@stamblerre

This comment has been minimized.

Copy link
Contributor

commented Jul 18, 2019

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

@ermik

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Contributor

commented Jul 18, 2019

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Contributor

commented Jul 18, 2019

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Contributor

commented Jul 22, 2019

@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

This comment has been minimized.

Copy link

commented Jul 23, 2019

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.

@zilman

This comment has been minimized.

Copy link

commented Aug 16, 2019

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.

@stamblerre I think it might be helpful to look at how other LSPs/editor combos handle this problem.

I've just run into this issue using coc.nvim + gopls. In case you're not familiar with coc it is a bridge between vim and a multitude of language servers, so for example, there's also coc-python.

With the python setup if you open a python file without cd'ing into the project root folder first the LSP gets confused about unresolved imports (neoclide/coc-python#26) very similarly to this issue.

There is a somewhat hacky workaround to use "workspace folders" which requires users to place an .env file into the project root and configure coc to look for it. Coc in turn is able to call the language server with the pwd and path set correctly as a result.

This is not a complete solution but seems directionally correct as vim unfortunately doesn't have a concept of a project folder.

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.

This seems very much the way to go. What do you think of a .gopls?

@ermik

This comment has been minimized.

Copy link

commented Aug 19, 2019

I am assuming it's possible the same logic that Go uses to figure out how to build modules with submodules expressly defined (handling submodules with go.mod files, rather than inferred) to create a set of subtreet contexts. Figure out which go.mod subtree the currently edited file belongs to when it is edited and change the context for go toolchain calls.

Another issue is program-scope linting. If I change inner-most modules I want to see which code paths that change turned red. Assuming one can relate go.mod contexts to each other, we could subsequently run the toolchain on the root context or even recursively run it on the ancestors until reaching the root for the currently open file to see the change impact up the tree.

@asciifaceman

This comment has been minimized.

Copy link

commented Sep 19, 2019

Adding folders to the workspace instead of just honoring whats defined in go.mod is extremely alienating

It just turns the VSCode workflow into a mess

@nickhow83

This comment has been minimized.

Copy link

commented Oct 8, 2019

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.

This sorted my "issue" out, which I guess wasn't really so much of an issue with the extension, just how I expected it to work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
9 participants
You can’t perform that action at this time.