Skip to content

cmd/go: support vendoring in workspace mode #60056

Closed
@matloob

Description

@matloob

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.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions