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

document (unfortunate) relationship between [go,gopls].buildFlags and go.lintFlags (was ["-mod=mod"] doesn't seem to work) #2932

Open
aathan opened this issue Aug 9, 2023 · 9 comments
Labels
Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Comments

@aathan
Copy link

aathan commented Aug 9, 2023

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.19.3 linux/amd64 * Run `gopls -v version` to get version of Gopls from _the VS Code integrated terminal_. - golang.org/x/tools/[email protected] h1:Q0cfPbEG1WVfgxcRZ9uKTA6/ckIRNXx6Ym7KgT/VFE4= * Run `code -v` or `code-insiders -v` to get version of VS Code or VS Code Insiders. - 1.80.2 2ccd690cbff1569e4a83d7c43d45101f817401dc x64
  • Check your installed extensions to get the version of the VS Code Go extension
    • v0.39.1

Share the Go related settings you have added/edited

"gopls.buildFlags": [
    "-mod=mod"
],
"go.buildFlags": [
    "-mod=mod"
]

Describe the bug

"undefined: xyz (compile)" shows up for symbols that are defined but only if you need to compile with -mod=mod, despite having properly set the flag in buildFlags

Steps to reproduce the behavior:

in go.mod, use a module from github (e.g. gopkg.in/yaml.v3).
go mod vendor (not sure if vendoring is the problem)
Also, set a replace => for that module, to a local git clone.
Add a public function in your local git clone
Use/reference that function in the project that has the replace for that module...
Observe that if you leave out the gopls.buildFlags, you get red warnings about unknown functions etc.
Set the gopls.buildFlags and reload the window
Observe that after reloading the window, no red warnings exist about the unknown function (i.e., the -mod=mod took effect)
Now, Command-S (save) the file.
Observe that "undefined: yaml.Xyz() (compile)" warning in yellow appears, despite having the go.buildFlags="-mod=mod"

EDIT: I should mention, compiling on the command line with -mod=mod works. I.e., the code and go.mod etc is in fact correct, and correctly compiles vs the local git repo clone. The vscode warning seems to be based on a compile that does not reference the right version of the foreign mod.

Screenshots or recordings

If applicable, add screenshots or recordings to help explain your problem.

@gopherbot gopherbot added this to the Untriaged milestone Aug 9, 2023
@aathan
Copy link
Author

aathan commented Aug 9, 2023

It looks like this is solved by:

    "go.lintFlags": [
        "-mod=mod"
    ]

I'm leaving this open because well, it seems like there should be some link between these settings and/or at least some mention of the lintFlags where the relationship between the other buildFlags are described?

Also, maybe instead of (compile) it should say (linter) ?

@aathan aathan changed the title go.buildFlags = ["-mod=mod"] doesn't seem to work relationship between [go,gopls].buildFlags and go.lintFlags is unfortunate (was ["-mod=mod"] doesn't seem to work) Aug 9, 2023
@jamalc
Copy link
Contributor

jamalc commented Aug 10, 2023

What problem do you want to solve by setting this flag?

@aathan
Copy link
Author

aathan commented Aug 10, 2023

As described, the problem I'm trying to solve is to get correct editor error/lint/etc messages when a project requires the -mod=mod flag to build. If you're unfamiliar: There are cases when you are working in a mod vendor'ed project, but need to debug an external module. In that case, you may use the go.mod "replace xyz => xyzfeature to point a given module to your local git clone of that project, that you're fixing bugs in. Since the main project is vendor'ed, you need to supply-mod=modflag togo buildetc in order to have it *in fact* use your local copy, even though thereplace ...` exists in that project go.mod.

What I've found is that there are at least three places (as described above) where the same flags have to be provided, and I may just have found a fourth: Namely, here when I'm using the vscode debugger, I think it's using the vendor'ed module again instead of the -mod=mod one, so there must be yet another place I have to go search for to set this flag.

Shouldn't there be a single setting for these flags, with these individual breakout settings used only if they're specified, so that users don't have to set 3-4 things to the same value? The current situation makes it a pain to switch back and forth between -mod=mod and normal mode...

@aathan
Copy link
Author

aathan commented Aug 10, 2023

EDIT: I'm leaving this open in case others run into this problem, but i looks like the supported launch.json flags for the dlv-dap adapter are in fact documented (here) and buildFlags is a supported key in launch.json.

Please also see: go-delve/delve#3462

I'm not sure how/if the go vscode extension is involved in what is allowed or how to specify launch.json entries relevant to the debuggering, but it seems that I cannot successfully pas dlvFlags to the remote dlv dap instance so as to build/launch using -mod=mod

@hyangah
Copy link
Contributor

hyangah commented Aug 15, 2023

Different lint tools have different flags. So, we cannot plumb all go.buildFlags mechanically to lint tools.
Alternative I think is setting GOFLAGS env var.

However, the -mod flag is one of the flags gopls controls internally to avoid extraneous network access (gopls runs go commands so frequently), so I wouldn't be surprised if gopls doesn't handle the case.

Have you tried to remove the vendor directory instead of trying to set -mod=mod? Once go mod tidy runs after updating go.mod, -mod=readonly (the default when no vendor directory is present) and the replace rules will apply as you expect and most of the tools will work as expected. You can also regenerate the vendor easily by running go mod vendor.

@aathan
Copy link
Author

aathan commented Aug 15, 2023

I understand. Please consider the following points:

  • The relationship between these settings is not necessarily dependent on the choice of tools, and some helpful text alerting users that all three exist and may be linked, could be provided.

  • It's clear that for certain combinations of tools (the default, in my case) there are at least some options that clearly do work exactly the same across all three settings. This is evidenced by the fact that when I entered -mod=mod in all three places, things started working correctly.

  • There is already a linkage between go.buildFlags and gopls.buildFlags, so perhaps linking lintFlags into the same behavior is not worse than not doing so?

  • The suggestion you make could be copy/pasted into the right docs, I can submit a PR with such changes if you point me to the right project/location.

@aathan
Copy link
Author

aathan commented Aug 16, 2023

For anyone arriving here searching for how to make -mod=mod work well in vscode, also note:

https://github.com/golang/vscode-go/wiki/debugging#launchjson-attributes

If you use the go debugger in vscode, you'll want to set -mod=mod in your buildFlags in launch.json.

@findleyr
Copy link
Contributor

Let's use this issue to track improving our documentation.

@findleyr findleyr changed the title relationship between [go,gopls].buildFlags and go.lintFlags is unfortunate (was ["-mod=mod"] doesn't seem to work) document (unfortunate) relationship between [go,gopls].buildFlags and go.lintFlags (was ["-mod=mod"] doesn't seem to work) Aug 28, 2023
@findleyr findleyr modified the milestones: Untriaged, vscode-go/backlog Aug 28, 2023
@hyangah
Copy link
Contributor

hyangah commented Nov 29, 2023

The current documentation already mention the relationship between go.buildFlags and gopls.build.buildFalgs

Flags to go build/go test used during build-on-save or running tests. (e.g. ["-ldflags='-s'"]) This is propagated to the language server if gopls.build.buildFlags is not specified.

buildFlags is the set of flags passed on to the build system when invoked. It is applied to queries like go list, which is used when discovering files. The most common use is to set -tags.

I verified the flags set with "go.buildFlags" are copied to gopls. However, gopls selectively applies flags and "-mod" flag is one of those dropped (in my case, I see the "inconsistent vendoring" errors coming from go command during package loading). @findleyr shouldn't gopls respect the user-specified mod flag?

@aathan what linter are you using? Neither staticcheck nor golangci-lint accepts -mod=mod flag (so, basically setting such value in "go.lintFlags" basically makes lint functionality stop).

p.s. BTW, the use case (hacking dependencies locally) is served better with go.work.

@hyangah hyangah added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Nov 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants