Description
This is a proposal to support vendoring in workspace mode.
We originally didn't support vendoring of a workspace to simplify the implementation of workspaces, but there's recently been demand by users of vendoring who want to workspaces for that support, so now is a good time to consider adding that support in.
go work vendor
subcommand
Under this proposal, a new subcommand, go work vendor
, will be added to the go
command. go work vendor
will check to make sure that workspace mode is active when it starts, (and return an error if it isn't) and if it is, it will write a vendor directory for the workspace. The vendor directory will be created in the same directory as the go.work
file. The vendor directory will contain packages taken from the modules in the build list of the workspace. vendor/modules.txt will contain the set of packages from each of the modules in the build list as usual, will list modules with # explicit
annotations for each module required by one of the workspace modules, and will annotate replacements for each of the effective replacements in the workspace (That is, if the go.work
file overrides replacements in workspace only the replacement in the go.work
file will be annotated.)
go work vendor
otherwise behaves the same as and takes the same flags as go mod vendor
.
go mod vendor
subcommand
go mod vendor
will explicitly fail if a go.work
file is found and GOWORK
is not set to off
. See discussion below.
-mod=vendor
in workspace mode.
Under this proposal, when workspace mode is active, if -mod=vendor
is set explicitly, or it is set implicitly through the existence of a vendor directory in the same directory as the go.work
The go command will enter workspace mode and interpret the vendor directory as reflecting the workspace's modules. The go command will use the vendor directory in the same directory as go.work
. vendor/modules.txt
is interpreted as reflecting the modules in the workspace. That interpretation is done through the vendoring consistency check, and the structure of the internal module graph built.
The vendoring consistency check would check vendor/modules.txt
against the workspace modules. It will check that all explicitly required modules appear in vendor/modules.txt
with an # explicit
annotation and all modules in vendor/modules.txt
with # explicit
are required by a workspace module. Similarly, all effective replacements in the workspace are expected to appear in vendor/modules.txt and all replacements in vendor/modules.txt are expected to appear in a workspace module go.mod
or the go.work
file.
The way the module graph is built is similar to to that of an unpruned module. The module graph contains the main modules as its roots, and each of the main modules would require their module requirements in addition to a fake vendor/modules.txt
module that in turn requires the set of modules in the vendorList
(the set of modules in vendor/modules.txt` that provide packages.
Otherwise, vendor mode with a workspace behaves the same as vendor mode with a module. The packages in the vendor directory are used to satisfy imports in the main modules when loading packages and doing builds.
Other considerations.
go work vendor
and go mod vendor
.
Under the proposal as it is, go mod vendor
works to vendor the module it's in, but fails if there's a go.work
file present and GOWORK
is not set to off. If that wasn't the case, there could be confusion if a go.mod
and go.work
files exist in the same directory. Then go mod vendor
and go work vendor
would create vendor directories in the same place, but with different contents. Since in workspace mode, the vendor directory is interpreted as a reflecting the workspace, if go mod vendor
is run before another command in workspace mode, the vendor consistency checks will likely fail. When they fail the error message will give the user the appropriate command to run go mod vendor
or go work vendor
depending on whether modules.txt
was checked against a single module or a the workspace. Even so, the user might still get confused about why running go mod vendor
and immediately running another command might result in an error. To reduce the confusion, we require a user to not have a go.work
file present or have GOWORK
set to off
when go mod vendor
is run, so that when a following command is run under the same conditions, it doesn't interpret the vendor directory as reflecting the workspace.
The behavior might break already existing workflows where go mod vendor
is run when a go.work
is present and module vendoring is being used, but it seems better to do so than to introduce the potential confusion of the user creating a vendor directory that fails consistency checks.