Years ago, Go started having trouble compiling and installing applications on native Windows environments (Command Prompt, PowerShell, not Cygwin-like or WSL environments).
The go mod vendor
system sometimes malfunctions in Windows. go install [./...]
reports an inability to look in the vendor
directory to fulfill import dependencies.
In an attempt to resolve this, the user may try to run go clean -modcache
. However, that command fails due to quirks for Windows users, as well as quirks for users who update Go versions. In fact, running go clean -modcache
both fails, and also triggers go install [./...]
to generate even more errors than before, since a broken go clean -modcache
leaves the $GOPATH/pkg
tree in such a poor state.
From Go 1.15 onward, an awkward, opt-in GODEBUG=modcacheunzipinplace=1
environment variable configuration is required to Windows Go application contributors to get commands like go clean -modcache
and go install ./...
to succeed. Then, applications are able to build in Windows (with precisely the same git contents for vendor/
as before).
That’s not an intuitive behavior out of the box. Let’s improve Go, so that Windows users can make use of the vendor
system, without having to waste time troubleshooting errors and changing the default Go configuration.
One way to reduce risk of corruption between Go versions, is to mark the pkg directory with a helper file like $GOPATH/pkg/.go-touch
to indicate the version of Go that last wrote to the directory tree. We could backport error handling to present warnings, or better yet, errors, in the event that an incompatible Go version tries to read or write from the directory tree. The incompatible versions would still be incompatible, but with safer error handling, in a way that empowers us to promote GODEBUG=modcacheunzipinplace=1
as the new default behavior, at least in Windows.
That being said, I recognize that we would like not to break past versions of Go wherever possible. To that end, another grander option is possible: Move the pkg
location from $GOPATH/pkg
to $GOPATH/<go-version>/pkg
. Given that certain packages like x/tools linters often break API’s anyway, it seems reasonable to stop reusing a single global location for this directory. Make it relative to the Go version for safety and future compatibility.
Go 1.24 could do this. Or Go 1.25. Without sacrificing backwards compatibility with old, insecure Go versions.
In ASDF, this is perhaps less of an issue, not just because ASDF is primarily a UNIX, non-Windows version manager; But also because ASDF tends to automatically nest many Go elements within version-relative directories…
Perhaps this is possible with some snippets in the (fragile) psenv system, though that’s only for PowerShell, not Command Prompt.
Perhaps this is possible with direnv, which if memory serves has been prototyping some kind of Windows (PowerShell?) support at long last.
Ideally, such improvements are made directly in Go, available to as many coders and environments as possible.