golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.18k stars 17.57k forks source link

x/tools/gopls: detect tools.go files, and suppress warning #69072

Open Jyosua opened 1 month ago

Jyosua commented 1 month ago

I've been looking for a way to fix this for quite a bit of time and nothing I've tried has worked. I'm using oapi-codegen to generate boilerplate for my webserver. The authors of this library recommend the tools.go pattern for managing the dependency, so that go.mod can act as the single source of truth for versioning. For transparency, their readme recommends this here. Doing this actually works -- I can run go generate just fine and my code builds. However, VSCode insists on showing an error and warning in this tools.go file, marking the file and the module folder red:

image

This is driving me crazy. I'd like to at least suppress these, but I can't find any way to do so. I've tried using the lintFlags to exclude it, but it appears to be gopls and not staticcheck, so this doesn't do anything. I can't find a gopls configuration setting that will allow me to ignore this file or any issues with it, either.

For what it's worth, someone else noticed the same thing with a different library in this issue.

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.22.5 darwin/arm64 * Run `gopls -v version` to get version of Gopls from _the VS Code integrated terminal_. - golang.org/x/tools/gopls v0.16.1 * Run `code -v` or `code-insiders -v` to get version of VS Code or VS Code Insiders. - Version: 1.92.1 * Check your installed extensions to get the version of the VS Code Go extension - v0.42.0 * Run Ctrl+Shift+P (Cmd+Shift+P on Mac OS) > `Go: Locate Configured Go Tools` command. ``` # Tools Configuration ## Environment GOBIN: undefined toolsGopath: gopath: /Users/[username]/go GOROOT: /opt/homebrew/Cellar/go/1.22.5/libexec PATH: /opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Users/[username]/Library/Application Support/JetBrains/Toolbox/scripts:/Users/[username]/go/bin ## Tools go: /opt/homebrew/bin/go: go version go1.22.5 darwin/arm64 gopls: /Users/[username]/go/bin/gopls (version: v0.16.1 built with go: go1.22.5) gotests: not installed gomodifytags: not installed impl: not installed goplay: not installed dlv: /Users/[username]/go/bin/dlv (version: v1.23.0 built with go: go1.22.5) staticcheck: /Users/[username]/go/bin/staticcheck (version: v0.4.7 built with go: go1.22.5) ## Go env Workspace Folder (point-system): /Users/[username]/Documents/Repositories/point-system GO111MODULE='' GOARCH='arm64' GOBIN='' GOCACHE='/Users/[username]/Library/Caches/go-build' GOENV='/Users/[username]/Library/Application Support/go/env' GOEXE='' GOEXPERIMENT='' GOFLAGS='' GOHOSTARCH='arm64' GOHOSTOS='darwin' GOINSECURE='' GOMODCACHE='/Users/[username]/go/pkg/mod' GONOPROXY='' GONOSUMDB='' GOOS='darwin' GOPATH='/Users/[username]/go' GOPRIVATE='' GOPROXY='https://proxy.golang.org,direct' GOROOT='/opt/homebrew/Cellar/go/1.22.5/libexec' GOSUMDB='sum.golang.org' GOTMPDIR='' GOTOOLCHAIN='auto' GOTOOLDIR='/opt/homebrew/Cellar/go/1.22.5/libexec/pkg/tool/darwin_arm64' GOVCS='' GOVERSION='go1.22.5' GCCGO='gccgo' AR='ar' CC='cc' CXX='c++' CGO_ENABLED='1' GOMOD='/dev/null' GOWORK='' CGO_CFLAGS='-O2 -g' CGO_CPPFLAGS='' CGO_CXXFLAGS='-O2 -g' CGO_FFLAGS='-O2 -g' CGO_LDFLAGS='-O2 -g' PKG_CONFIG='pkg-config' GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/by/cxzl4qc57c3c8dd9p9snhn680000gn/T/go-build3419525479=/tmp/go-build -gno-record-gcc-switches -fno-common' ```

Share the Go related settings you have added/edited

{
    "go.lintTool": "staticcheck",
    "go.lintFlags": [
        "-exclude=gateway/tools/tools.go"
    ]
}
hyangah commented 1 month ago

Yes, the error and warning messages come from the gopls (the language server). Since the tools.go file has //go:build tools build tag, gopls processes and analyzes the file only it is open. The diagnostics will disappear as soon as you close the tools.go file.

The warning message ("No packages found for open file ...") seems intentional, but I think we can consider different wording and info-level.

The error message ("import X is a program, not an importable package") is not great for tools.go style dependency management practice. Can we teach gopls this special case and suppress this specific error message?

cc @findleyr

findleyr commented 1 month ago

I'd be happy to accept a change suppressing errors that match this pattern. The heuristic seems accurate enough. Moving this to the Go issue tracker as a gopls issue.

A couple quick notes: