Ask questionscmd/go: add a workspace mode
Detailed Design Doc: Proposal: Multi-Module Workspaces in
Demo Video: Go Workspaces Proposal Demo
I propose adding a new workspace mode in the
go command for editing multiple modules. The presence of a
go.work file in the working directory or a containing directory will put the
go command into workspace mode. The
go.work file specifies a set of local modules that comprise a workspace. When invoked in workspace mode, the
go command will always select these modules and a consistent set of dependencies.
This is intended to help with workflows making changes across multiple modules and with editor support for those workflows.
This is what an example
go.work file would look like:
go 1.17 directory ( ./baz // foo.org/bar/baz ./tools // golang.org/x/tools ) replace golang.org/x/net => example.com/fork/net v1.4.5
This adds two modules to the workspace. If the user's current working directory is is under the directory containing this
go command will be in workspace mode and use both the modules defined by
./tools/go.mod as main modules, regardless of which module the user is currently in (unless workspace mode is turned off or a different workspace is chosen with the proposed new
-workfile flag). The
replace would override any replaces
in the main modules'
Issue #32394 is about
gopls' support for multi-module workspaces.
gopls currently allows users to provide a "workspace root" which is a directory it searches for
go.mod files to build a supermodule from. Alternatively, users can create a
gopls.mod file in their workspace root that
gopls will use as its supermodule. This proposal creates a concept of a workspace that is similar to that
gopls that is understood by the
go command so that users can have a consistent configuration across their editor and direct invocations of the
Issue #44347 proposes adding a
GOTINKER mode to the
go command. Under the proposal, if
GOTINKER is set to a directory, the
go command will resolve import paths and dependencies in modules by looking first in a
GOPATH-structured tree under the
GOTINKER directory before looking at the module cache. This would allow users who want to have a
GOPATH like workflow to build a
GOTINKER, but still resolve most of their dependencies (those not in the
GOTINKER tree) using the standard module resolution system. It also provides for a multi-module workflow for users who put their modules under
GOTINKER and work in those modules.
This proposal also tries to provide some aspects of the
GOPATH workflow and to help with multi-module workflows. A user could put the modules that they would put under
GOTINKER in that proposal into their
go.work files to get a similar experience to the one they'd get under the
GOTINKER proposal. A major difference between the proposals is that in
GOTINKER modules would be found by their paths under the
GOTINKER tree instead of being explicitly listed in the
go.work file. But both proposals provide for a set of replaced module directories that take precedence over the module versions that would normally be resolved by MVS, when working in any of those modules.
The issue of maintaining user-specific replaces in
go.mod files was brought up in #26640. It proposes an alternative
go.mod.local file so that local changes to the go.mod file could be made adding replaces without needing to risk local changes being committed in
go.mod itself. The
go.work file provides users a place to put many of the local changes that would be put in the proposed
Answer questions ulikunitz
I have still some questions regarding the contents and handling of the go.work file.
How about the assumption that subdirectories of the workspace directory contain source code repositories and all modules included are part of the workspace? The go.work file could still contain ignore and replace clauses, but the need would be very limited.
In the ideal case an empty go.work file would be sufficient and creating a workspace would be as simple as
$ touch go.work
The go.work file will not be part of a source code repository and I would like to keep it simple. And it cannot become simpler than an empty file.