Ask questionscmd/go: add a workspace mode

Detailed Design Doc: Proposal: Multi-Module Workspaces in cmd/go

Demo Video: Go Workspaces Proposal Demo

High level overview:

I propose adding a new workspace mode in the go command for editing multiple modules. The presence of a file in the working directory or a containing directory will put the go command into workspace mode. The 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 file would look like:

go 1.17

directory (
    ./baz //
    ./tools //

replace => v1.4.5

This adds two modules to the workspace. If the user's current working directory is is under the directory containing this, the go command will be in workspace mode and use both the modules defined by ./baz/go.mod and ./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' go.mod files.

Related issues

#32394 x/tools/gopls: support multi-module workspaces

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 go command.

#44347 proposal: cmd/go: support local experiments with interdependent modules; then retire GOPATH

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 GOPATH at 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 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 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.

#26640 cmd/go: allow go.mod.local to contain replace/exclude lines

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 file provides users a place to put many of the local changes that would be put in the proposed go.mod.local file.


Answer questions ulikunitz

I have still some questions regarding the contents and handling of the file.

  • Must all locations of go.mod files be listed explicitly?
  • Must v2, v3, ... modules be listed explicitly?
  • Will gopls or the go tool update the file? What are the semantics for the updates?

How about the assumption that subdirectories of the workspace directory contain source code repositories and all modules included are part of the workspace? The file could still contain ignore and replace clauses, but the need would be very limited.

In the ideal case an empty file would be sufficient and creating a workspace would be as simple as

$ touch

The 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.

Ulrich Kunitz ulikunitz Germany Go developer interested in compression; DevOps manager for identity & authentication
Github User Rank List