golang / vscode-go

Go extension for Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=golang.Go
Other
3.84k stars 735 forks source link

Truly standalone scripts don't play well with the extension #3078

Closed ConcurrentCrab closed 9 months ago

ConcurrentCrab commented 9 months ago

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


* Run `go version` to get version of Go from _the VS Code integrated terminal_. - go version go1.21.4 windows/amd64 * Run `gopls -v version` to get version of Gopls from _the VS Code integrated terminal_. - golang.org/x/tools/gopls v0.14.2 * Run `code -v` or `code-insiders -v` to get version of VS Code or VS Code Insiders. - 1.84.2 * Check your installed extensions to get the version of the VS Code Go extension - v0.40.0 * Run Ctrl+Shift+P (Cmd+Shift+P on Mac OS) > `Go: Locate Configured Go Tools` command. - ``` Checking configured tools.... GOBIN: undefined toolsGopath: gopath: C:\Users\Ishan\go GOROOT: C:\Users\Ishan\scoop\apps\go\current PATH: C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\dotnet\;C:\Program Files (x86)\Tailscale IPN;C:\Users\Ishan\scoop\apps\vscodium\current\bin;C:\Users\Ishan\go\bin;C:\Users\Ishan\scoop\apps\openssl\current\bin;C:\Users\Ishan\scoop\apps\openjdk\current\bin;C:\Users\Ishan\scoop\apps\imagemagick\current;C:\Users\Ishan\scoop\apps\python\current\Scripts;C:\Users\Ishan\scoop\apps\python\current;C:\Users\Ishan\scoop\apps\mingw\current\bin;C:\Users\Ishan\scoop\apps\qemu\current;C:\Users\Ishan\scoop\apps\mpv\current;C:\Users\Ishan\scoop\shims;C:\Users\Ishan\AppData\Local\Microsoft\WindowsApps go: C:\Users\Ishan\scoop\shims\go.exe: go version go1.21.4 windows/amd64 gopls: C:\Users\Ishan\go\bin\gopls.exe (version: v0.14.2 built with go: go1.21.4) gotests: not installed gomodifytags: not installed impl: not installed goplay: not installed dlv: C:\Users\Ishan\go\bin\dlv.exe (version: v1.21.0 built with go: go1.21.0) staticcheck: C:\Users\Ishan\go\bin\staticcheck.exe (version: v0.4.5 built with go: go1.21.0) go env Workspace Folder (snips): f:\prog\snips set GO111MODULE= set GOARCH=amd64 set GOBIN= set GOCACHE=C:\Users\Ishan\AppData\Local\go-build set GOENV=C:\Users\Ishan\AppData\Roaming\go\env set GOEXE=.exe set GOEXPERIMENT= set GOFLAGS= set GOHOSTARCH=amd64 set GOHOSTOS=windows set GOINSECURE= set GOMODCACHE=C:\Users\Ishan\go\pkg\mod set GONOPROXY= set GONOSUMDB= set GOOS=windows set GOPATH=C:\Users\Ishan\go set GOPRIVATE= set GOPROXY=https://proxy.golang.org,direct set GOROOT=C:\Users\Ishan\scoop\apps\go\current set GOSUMDB=sum.golang.org set GOTMPDIR= set GOTOOLCHAIN=auto set GOTOOLDIR=C:\Users\Ishan\scoop\apps\go\current\pkg\tool\windows_amd64 set GOVCS= set GOVERSION=go1.21.4 set GCCGO=gccgo set GOAMD64=v1 set AR=ar set CC=gcc set CXX=g++ set CGO_ENABLED=1 set GOMOD=NUL set GOWORK= set CGO_CFLAGS=-O2 -g set CGO_CPPFLAGS= set CGO_CXXFLAGS=-O2 -g set CGO_FFLAGS=-O2 -g set CGO_LDFLAGS=-O2 -g set PKG_CONFIG=pkg-config set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\Ishan\AppData\Local\Temp\go-build1832283827=/tmp/go-build -gno-record-gcc-switches ```

Share the Go related settings you have added/edited

None

Describe the bug

I have a folder full of scripts I use with go run. There is no go.mod module, or any other module-related metadata file in the directory.

The extension (and gopls) doesn't like that at all. It complains about all the redefined func main()s and everything else as you'd expect it to in an actual package.

Now, I am aware of build.standaloneTags, and adding //go:build ignore (since ignore is in the default value of that setting) to the top of all those scripts makes almost all those errors go away, except one:

gopls was not able to find modules in your workspace. When outside of GOPATH, gopls needs to know which modules you are working on. You can fix this by opening your workspace to a folder inside a Go module, or by using a go.work file to specify multiple modules. See the documentation for more information on setting up your workspace: https://github.com/golang/tools/blob/master/gopls/doc/workspace.md.

To my understanding, that setting is specifically only meant for specifying "standalone" scripts within a proper module, so I guess this does make sense.

Am I missing something obvious, or is there no way to use this extension in this way, with a bunch of loose standalone scripts?

Moreover, why are all these diagnostics kicking in at all without a module being present? go build, go build . all refuse to run in a directory when no go.mod is present. Shouldn't the extension follow its behavior, not automatically assuming a module exists, and falling back to a standalone-script mode by default?

Steps to reproduce the behavior:

  1. Create a new directory.
  2. Create a file hello1.go:

    //go:build ignore
    
    package main
    
    import "fmt"
    
    func main() {
            fmt.Println("Hello World")
    }
  3. Run cp hello1.go hello2.go
  4. Open the directory in vscode, open the files and look at the problems tab
hyangah commented 9 months ago

Ad-hoc package (or no package, or command-line-args package) support was never a priority, and even with the upcoming zero-config gopls, I am not sure if the build mode without go.mod will be supported reliably.

Since go1.21, go is moving towards configuring the stdlib and tooling versions using go.mod, like other third-party dependencies. The go version in go.mod will become more important - for example, loopvar change proposal (https://go.dev/blog/loopvar-preview) heavily depends on the go.mod go line value to determine the loop behavior. If so, I am sorry that supporting the scripts without go.mod will become much less important.

What prevents from having a go.mod file in the script directory?

ConcurrentCrab commented 9 months ago

Hi @hyangah,

What prevents from having a go.mod file in the script directory?

Nothing prevents me from adding one. It just seems weird to me that I am doing something that the language and toolchain allow me to do, but if I want autocomplete in my editor, I am forced to do things a certain different way. Or, more accurately, everything including autocomplete works as-is, but I am made to populate a file (which should ultimately be unnecessary information to the extension) to placate an error message.

Since go1.21, go is moving towards configuring the stdlib and tooling versions using go.mod, like other third-party dependencies. The go version in go.mod will become more important - for example, loopvar change proposal (https://go.dev/blog/loopvar-preview) heavily depends on the go.mod go line value to determine the loop behavior. If so, I am sorry that supporting the scripts without go.mod will become much less important.

I don't think this is a new development, really. Go tooling, including build and vet, has had diverging behavior depending on the specified version for quite a while. The most well-known example would probably be the whole old GOPATH vs. modules debacle. When you run or vet standalone go files, the toolchain assumes it was written for the most up-to-date language version, and treats it with those semantics.

The way I see it, standalone go run scripts having an unspecified version means it falls under a contract much like scripts in traditional interpreted languages, like python or bash, where either you specify the version it was created under as part of documentation (e.g. in comments), or you make sure it has no non-trivial behavior that behaves "controversially" across versions. And I'm fine with that contract personally.

hyangah commented 9 months ago

Zero-config gopls work will handle the ad-hoc package and make it possible to load it independent of go.mod's presence. See https://github.com/golang/go/issues/57979

The work is currently in progress. I will add a note to mention there to make sure the UX is tested. Closing in favor of the zero-config gopls work.

ConcurrentCrab commented 9 months ago

I see, thank you very much @hyangah ! Will be looking forward to the change.