Go 1.11 Modules

Go 1.11 will add preliminary support for versioned modules as proposed here.

Installing

To use modules, install the Go toolchain from source on the master branch, or install the vgo binary from the vgo subrepository (and replace go with vgo in the commands below).

You can activate module support in one of three ways:

  • Invoke the 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).
  • Invoke the go command with GO111MODULE=on in the command environment.
  • Invoke the vgo binary (built from the subrepository) as a binary named vgo.

New Concepts

Major Versions

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; see issue 26238 for discussion.

Modules

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.

  1. Create a 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.
  2. Update the go.mod file to include a /v2 at the end of the module path. Tag the release with v2.0.0.
    • To avoid confusion with this approach, consider putting the v2.*.* commits on a separate v2 branch.

Packages are imported relative to the full module path: import "me.io/mymod/v2/pkg1" for package pkg1 in module me.io/mymod/v2, or import "me.io/mymod/pkg1" for package pkg1 in module me.io/mymod (v1 or v0).

Version Selection

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.)

New Project Setup

To create a go.mod for an existing project, follow the following steps.

  1. 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>
    
  2. Create the initial module definition and write it to the go.mod file.

    $ go mod -init
    

    This step converts any existing from a dep Gopkg.lock file or other supported dependency format.

    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
    
  3. Fill in requirements for any missing or unconverted dependencies, and remove modules that are not needed to satisfy any imports.

    $ go mod -sync
    
  4. Test the module as configured to ensure that it works with the selected versions.

    $ go test ./...
    
  5. (Optional) Run the tests for all imported modules to check for incompatibilities.

    $ go test ...
    

Updating Dependencies

To update all transitive dependencies of the current module to the latest version, run go get -u.