Go modules will land in Go 1.11: go mod split into multiple subcommands
Go 1.11 is expected to be released in August 2018 and guess what? It will add experimental support for a new concept called “modules.” Let’s take a look and see what this means for Go developers and what the new “go mod” command can do.
Modules are now supported by the main repo for Google Go. This means it’s possible to work on your modules, wherever you like, without setting an environment variable or following a predefined location.
“With Go 1.11 and modules you can write your Go modules anywhere you like,” writes Dave Cheney. “You’re no longer forced into having one copy of a project checked out in a specific sub directory of your $GOPATH.”
Given the kerfluffle over modules in Java, what does this mean for Go? Well, things are a little different in Golang.
Here’s what Russ Cox has written about Go modules:
A Go module is a collection of packages sharing a common import path prefix, known as the module path. The module is the unit of versioning, and module versions are written as semantic version strings. When developing using Git, developers will define a new semantic version of a module by adding a tag to the module’s Git repository. Although semantic versions are strongly preferred, referring to specific commits will be supported as well.
Basically, Go modules offer the chance to do some light housekeeping and maybe a major revamp in how the go command manages source code. Go is getting close to ten years old; it’s time to create a module design that will carefully carry Golang into the future.
SEE ALSO: Top 5 IDEs for Go
How does it work?
All of the information below was found on Russ Cox’s post to the golang-dev group. I highly recommend reading the whole thing!
Modules are defined by a tree of Go source files with a go.mod file in the tree’s root directory. The directory that contains the go.mod file is the module root. Sometimes, the module root corresponds to a source code repository root, but this isn’t necessary. The module is made up of all the Go packages and subdirectories in the module root. It doesn’t include any subtrees with their own go.mod files.
go mod command is all that is needed to create a new module.
The “main module” contains the directory where the go command is run. The go.mod files define exactly what is available for use by the go command with require, replace, and exclude statements. Dependency statements and require states also help define what packages are available.
The “build list” is the set of modules that provides packages to builds. Although it initially contains just the main module, the go command adds to that list until everything is complete.
go list command displays information about the main module and build list.
The go.mod file can be read and edited by both developers and tools. It is automatically updated by the go command, maintaining standardized formatting and accurate require statements.
If the go command finds an unfamiliar import, it automatically looks up the module and adds the latest version to the go.mod. After this new import is added, go.mod will run
go test, or
go list to analyze the package. Once analyzed, the import will be resolved and the go.mod file updated.
go mod –sync command builds a fill view of all the packages in the module across all possible build configurations. It then adds any missing requirements and gets rid of anything that isn’t necessary.
go get command updates the module versions in a build, making any consequent upgrades or downgrades automatically.
Finally, the go command requires semantic versioning for modules. It expects that all of these versions accurately describe their compatibility and follow the import compatibility rule. This means that a module definition can only set the minimum required version for its dependencies and not the maximum.
SEE ALSO: Using Go for WebAssembly applications
UPDATE: Go mod changes
As of July 31st,
go mod has seen some pretty significant changes. After some discussion on the changelog, the Go team has decided to split
go mod into multiple subcommands.
go mod command was a multipurpose one that could do basically everything. However, that meant the design was unclear and that all module operations went through
go mod. That’s not exactly what it was designed for.
Additionally, it led to the erroneous understanding that
go mod -require and
go get were functionally the same command. (They’re not, fyi.)
So, to deal with this, the Go developer team decided to split
go mod into multiple subcommands.
go mod edit # old go mod -require ... go mod fix # old go mod -fix go mod graph # old go mod -graph go mod init # old go mod -init go mod tidy # old go mod -sync go mod vendor # old go mod -vendor go mod verify # old go mod -verify
By making these changes, the Go development team has made it easier to read both the documentation and the implementation. The command lines are streamlined and it allows command-specific flags.
In general, the development team tries to avoid subcommands. In this specific case, it has improved the developing experience significantly.
However, creating subcommands does change some things in the core command parsing and help logic. So, as part of changing
go mod init into its own separate command, the CL changes the failure behavior during module initiation to be delayed until modules are actually needed.
See the changelog for more information about this update.
Getting Go modules
Want to try modules for yourself? Go 1.11 will include experimental support for Go modules, plus the new module-aware
go get command.