Go 1.11 will add preliminary support for versioned modules as proposed here.
Go modules will be an experimental opt-in feature in Go 1.11, with the hope of incorporating feedback and finalizing the feature for Go 1.12. Even though the details may change, future releases will support modules defined using Go 1.11 or vgo.
vgo tool, but on 2018-07-12 support for versioned Go modules landed in the main Go repository.vgo.To use modules, you currently have three install options:
master branch.go with go1.11beta2 in the commands below).vgo binary from the vgo subrepository (and replace go with vgo in the commands below).As of July 23, 2018, there are some recommendations (e.g., here) to currently prefer installing from source or the latest beta over using vgo.
Once installed, you can then activate module support in one of three ways:
go command in a directory outside of the $GOPATH/src tree, with a valid go.mod file in the current directory or any parent of it and the environment variable GO111MODULE unset (or explicitly set to auto).go command with GO111MODULE=on in the command environment.vgo (if you have installed vgo from the subrepository).Go modules must be semantically versioned in the form v(major).(minor).(patch) (for example, v0.1.0, v1.2.3, or v3.0.1). If using Git, tag released commits with their versions. (Stand-alone distributed module repositories, such as Project Athens, are in the works.)
The major version of a module must for now be included in both the module path and the package import path if the major version is v2 or higher. Module versions of v1 and v0 must not be included in the path. Modules with different paths are different modules. Thus me.io/mymod is different then me.io/mymod/v2 and may import packages from one major version to another major version.
The behavior of modules for existing packages with post-v1 tags is still in flux; an important related recent change was issue 26238, which substantially improved the behavior for existing packages with post-v1 tags.
Go packages now live in modules. The path of a module is a URL path where it may be found, and may include a major version at the end of the path (but nowhere else). Module source code moutside of $GOPATH. Two example modules are rsc.io/goversion and github.com/kardianos/vtest/v3.
Modules are defined by a go.mod file that lives in the root of the module. Module files may include comments and will look familiar to a go programmer. Here is an example go.mod file:
module github.com/kardianos/vmain/v3
require (
github.com/kardianos/vtest/v2 v2.0.2
)
There are 4 directives: “module”, “require”, “exclude”, “replace”. Module paths may be quoted but are not required to be.
Including major versions in import paths will produce incompatibilities with old versions of Go. To work around this prior versions of the go tool have been updated and released to continue building as before. (See issue 25069.)
exclude and replace directives only operate on the current (“main”) module. exclude and replace directives in modules other than the main module are ignored.
TODO: show example exclude and replace directives.
There are two ways to release a v2 (or higher) module version.
v2 directory and place a new go.mod file in that folder. The module path must end with /v2. Tag the release with v2.0.0.go.mod file to include a /v2 at the end of the module path. Tag the release with v2.0.0.v2.*.* commits on a separate v2 branch.Packages are imported relative to the full module path, for example:
import "me.io/mymod/v2/pkg1" for package pkg1 in module me.io/mymod/v2import "me.io/mymod/pkg1" for package pkg1 in module me.io/mymod (v1 or v0).The version of each module used in a build is always the semantically highest of the versions explicitly required by the module or one of its dependencies. This effectively locks versions into place until the module author or user chooses a new version explicitly. Use go list -m to list selected module versions.
Different major versions are distinct modules. A /v2 module will never be compared with a /v3 module, even if the rest of the module path is the same, but me.io/mymod may be included alongside me.io/mymod/v2. (This allows a v1 module to be implemented in terms of its v2 replacement or vice-versa.)
To create a go.mod for an existing project, follow the following steps.
Navigate to the root of the module's source tree and activate module mode in the go command.
$ cd $GOPATH/src/<project path> $ export GO111MODULE=on
or
$ cd <project path outside $GOPATH/src>
Create the initial module definition and write it to the go.mod file.
$ go mod -init
This step converts from any existing dep Gopkg.lock file or from any of the other nine total supported dependency formats, adding require statements to match the existing configuration.
If go mod cannot determine an appropriate package path, or if you need to override that path, use the -module flag:
$ go mod -init -module example.com/path/to/my/module/v2
The -sync flag synchronizes the go.mod file with the source code in the module (filling in requirements for any missing or unconverted dependencies, and removing modules that are not needed to satisfy any imports):
$ go mod -sync
Test the module as configured to ensure that it works with the selected versions.
$ go test ./...
(Optional) Run the tests for all imported modules to check for incompatibilities.
$ go test all
Day-to-day adding, removing, upgrading, and downgrading of dependencies should be done using ‘go get’, which will automatically update the go.mod file.
In addition, go commands like ‘go build’, ‘go test’, or even ‘go list’ will automatically add new dependencies as needed to satisfy imports (updating go.mod and downloading the new dependencies).
To upgrade to the latest version for all transitive dependencies of the current module:
go get -u to use newer minor or patch releasesgo get -u=patch to use newer patch releasesTo upgrade or downgrade to a more specific version, ‘go get’ allows version selection to be overridden by adding an @version suffix or “module query” to the package argument, such as go get github.com/gorilla/mux@v1.6.2, go get github.com/gorilla/mux@e3702bed2, or go get github.com/gorilla/mux@'<v1.6.2'. See the “Module queries” and “Module-aware go get” sections of the tip documentation for more information.
After upgrading or downgrading any dependencies, you may then want to run the tests again for all imported modules to check for incompatibilities:
$ go test all
Best practices for creating a release of a module are expected to emerge as part of the initial modules experiment. Many of these might end up being automated by a future ‘go release’ tool.
Some current suggested best practices to consider doing prior to tagging a release:
Run go test all to test your module (including your direct and indirect dependencies) as a way of validating that the currently selected packages versions are compatible.
go test all has been re-defined to be more useful to include all the packages in the current module, plus all the packages they depend on through a sequence of one or more imports, while excluding packages that don't matter in the current module.Run go mod -sync to ensure your current go.mod reflects all possible build tags/OS/architecture combinations (as described here) and possibly prune any extraneous requirements (as described here).
vgo by Russ Cox (first posted February 20, 2018)vgo blog series, along with some of the history and process behind the proposal