Go version 1.18 is coming out soon, and in the mass consciousness it will most likely be associated with Generics. But besides them, there are a few more tasty features. For instance, Go Workspaces.
What gives Go Workspaces?
Go Workspaces allows you to work with multiple modules at the same time. Theoretically, this could have been done before, but Go Workspaces adds a bit of comfort.
Previously, when working with several modules at the same time, they had to be “linked” through the directive
The replace approach
go.mod has a number of significant disadvantages:
each module lives its own independent life and some development tools can only work with one module at a time.
replace-s are not transitive. That is, if you add
replace, then it must be added to all modules that use it. Even with a small number of modules, this causes noticeable inconvenience.
run the utility via
go runis possible only from the directories of those modules that either contain this utility or “see” it through replace (it must also be declared as
Go Workspaces adds some comfort:
goplsprovides information on all used modules at once;
replace-s can be declared in one place, and are visible to all declared modules;
local edits with directive
replaceno need to write inside
go.modfiles that are in the repository;
assembly and launch of utilities for all declared modules can be from the directory that contains
go.workand its child directories;
command is added
go work syncwhich allows you to update the dependencies of multiple modules to the most recent shared version.
How does it work?
go.work-file Go collects a common list of dependencies from all those listed in
go.mod-files, taking into account
replace– directives. Based on all the listed dependencies, a single dependency graph is formed, which is applied to all used modules. If for one module it is specified in different
go.mod several conflicting
replace-directives – there will be an error.
For example, if one module requires a dependency on github.com/davecgh/go-spew versions
v1.1.1and another module requires a dependency on github.com/davecgh/go-spew versions
v1.1.0then both module will be executed with an older version
This works for all modules of the same Go Workspace, even if there is no dependency between the modules.
What doesn’t give Go Workspace?
If you want to use multiple
go.mod-files within one (mono)repository, then
go.work will not help you in any way: within one Go Workspace, common dependencies are used, collected on the basis of all used
go.mod-files. That is, such an approach will not fundamentally differ from the use of one
go.mod-file, except for the increase in complexity due to the greater number of files used.
The actual link to neighboring modules through tags or the commit ID also remains behind the scenes of Go Workspace.
How to start using Go Workspaces?
A group of commands has been added to use Go Workspaces
First you need to call the command
go work init at the root of the workspace.
Let’s say we have a workspace like this:
Then to use Go Workspaces you need:
go work init
Add modules there:
go work use shared go work use tools
As a result, a file will be created
go.work with content like:
go 1.18 use ( shared tools )
And then, for example, you can call the assembly from any subdirectory inside the workspace:
go run github.com/bozaro/go/go-work-play/tools/hello
replace-s, they will also have an effect on all modules of the workspace.
What other problems are there?
It is important to understand that using Go Workspaces changes the behavior of some commands, for example:
go runstops working for modules that are not declared in
go listcan’t change
go list -mod=mod -m -json go: -mod may only be set to readonly when in workspace mode, but it is set to "mod" Remove the -mod flag to use the default readonly value, or set -workfile=off to disable workspace mode.
Some utilities may not be ready for this change.
I made the following conclusions for myself.
Using Go Workspaces greatly simplifies the execution of any utilities due to the ability to call them from anywhere in the workspace without unnecessary squats.
You can not add parasitic
go.modfiles in order to edit several related projects at the same time.
go.workyou can get a situation where the code being run will not be executed with the dependencies that are specified in
go.modfile, and you need to remember this. Fortunately, dependencies can be reduced through the command
go work sync.
The problem with multiple
go.modwithin the same repository using Go Workspaces is not solved in any way.