I watch commits to the Go development repository for various reasons, and some times I see interesting changes fly by. One recent one was a merger of a long-running branch called 'dev.cmdgo' , which made me curious what this branch was for. It turns out it was for a new feature called multi-module workspaces, which has a proposal document and an open issue with discussions . Although nothing is sure until Go 1.18 is released, it's very likely that this feature will be in 1.18.
The abstract of the proposal document explains the basic idea fairly well:
This proposal describes a new workspace mode in the
gocommand for editing multiple modules. The presence of ago.workfile in the working directory or a containing directory will put thegocommand into workspace mode. Thego.workfile specifies a set of local modules that comprise a workspace. When invoked in workspace mode, thegocommand will always select these modules and a consistent set of dependencies.
At the moment, two important things can go in
go.work
files. The first is Go module
replace
directives , which apply to all modules in the workspace and override any
go.mod
replace directives already present. The second is a list of directories of Go modules; these are the modules that are part of the workspace. When a Go file in the workspace imports a package from another module in the workspace, it always comes from whatever is in the directory tree, regardless of what version is nominally being asked for in a
go.mod
.
(As noted in the proposal, this allows you to create a GOPATH-like setup, among other things.)
If you're going to get much use out of your Go workspace, at least one module needs to be in the directory tree under your
go.work
, but as the proposal covers, you don't have to put all directories there. You can point to other modules anywhere in the filesystem, enabling various things. However, normally many or all of your listed directories will be in the directory tree with your
go.work
in it.
The proposal document covers some official usage cases for this feature (in the Rationale section), such as making changes to several separate modules at once. Previously this might require a cascade of
replace
directives in
go.mod
files, but now it can be done centrally in one place and say what you mean. I can also already see other uses, such as creating a self-contained build area for your Go programs when you have different programs in different modules.
(With a single module you can vendor all your external dependencies, but with several programs in several separate modules you'd normally have to vendor repeatedly, and then worry about keeping them all consistent.)
(At some point people will write better articles about all of this, with practical examples, but since I found and read the proposal out of curiosity, I'm writing down this bare bones version now.)