A go module is a collection of related Go packages. A single unit that defines the minimum requirements that must be satisfied by their dependencies.
go.mod file is placed in the root of the project. This location is known as the module root and contains all Go packages and subdirectories.
go.modfiles and will excluded when performing operations affecting all packages within a module, e.g.,
go test ./...
We used to have GOPATH, but instead we now have the concept of a main module
gocommands will try to determine if the current working directory is the module root, i.e., location of the
go.modfile. If not, it’ll keep looking up one directory until either a
go.modfile is found or none.
1.11, module support is not enabled by default and is controlled by the env variable
GO111MODULE=auto (or unset)
default: go modules only supported outside the GOPATH
GOPATH mode: disable go module support, as if you’re on
module-aware mode: go commands will use go modules and never consult GOPATH to resolve imports
go.mod file defines the precise set of packages available for use by go commands.
If the project is using a third-party dependency manager, e.g., dep, godep, glide, etc., then
go mod init will add requirements based on the existing configuration, e.g., Gopkg.lock.
To start a new module go to the root of your project (must not already contain a
go.mod) and run:
go mod init # The module name is guessed from import comments or vcs config # To override, add the module path like so go mod init github.com/mfridman/srfax
this will create a
go.mod file in the current directory. Now run:
go get -d # The -d flag instructs go to download packages, but not install them. cat go.mod module github.com/mfridman/srfax require ( github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699 github.com/pkg/errors v0.8.0 )
A few things to note:
In module-aware mode downloaded dependencies are still downloaded to
GOPATH/pkg/mod and installed commands to
GOPATH/bin, unless otherwise set.
If a dependency is tagged
v2.0.0 or higher and contains no
go.mod file it is suffixed with
+incompatible (likewise for pseudo-versions, e.g.,
Dependencies of imported packages are marked with
Out of the box your favorite go commands such as
test, etc. will just work.
As you run them, the
go.mod file will automatically be updated and new dependencies will be downloaded to satisfy imports.
From here on we’re assuming module-aware mode, which you can achieve in one of two ways:
GO111MODULE=onand continue working in your GOPATH. (option 1 is preferred)
go get -d github.com/pkg/[email protected] go get -d github.com/pkg/[email protected] # records v.0.7.1 go get -d github.com/pkg/[email protected] # records v0.8.1-0.20180311214515-816c9085562c go get -d github.com/pkg/[email protected] # v0.8.0
go get -d github.com/pkg/[email protected]
replacements and exclusions only apply when building module directly; they are ignored when the module is incorporated into a larger build.
go mod edit -exclude github.com/pkg/[email protected] # entry added to go.mod # exclude github.com/pkg/errors v0.7.0
go mod edit -dropexclude github.com/pkg/[email protected]
# -replace=old[@v]=new[@v] go mod edit -replace github.com/pkg/[email protected]=github.com/pkg/[email protected] # entry added to go.mod # replace github.com/pkg/errors v0.6.0 => github.com/pkg/errors v0.7.0
# -dropreplace=old[@v] go mod edit -dropreplace github.com/pkg/[email protected]
with no package arguments, ‘go get’ applies to the main module
minor or patch:
# update all dependencies to newer minor or patch releases go get -u # update single dependency to newest minor or patch release go get -u github.com/pkg/errors # v0.6.0 -> v0.8.0
# update all dependencies to newer patch go get -d -u=patch # update single dependency to newest patch go get -d -u=patch github.com/pkg/errors # records v0.7.0 -> v0.7.1
There are a few of low-level commands available, but we’ll explore those later on:
go mod graph # prints module requirements go mod tidy # keeps go.mod in sync with the module; adds modules required to build current module's packages and deps, removes unused modules. Also keeps go.sum updated go mod verify # checks deps of current module, which are stored in local downloaded cache, have not been modified since last download $GOPATH/pkg/mod/cache/download go mod vendor # builds a vendor dir, includes all packages required to build and test all the current module's packages go mod fix # unlikely you need this because many go commands run this command under the hood
To use the vendor dir:
This operation is will recreate the vendor dir. If you’re using another package manager that already has vendor, everything will be wiped and rebuilt by this command.
go build -mod=vendor # note the -mod flag also applies to go clean, get, install, list, run, and test
Lastly, I have some ideas about using the following command, which provides information about modules and their dependencies. It can also return JSON with the
-json flag which is useful for downstream tools.
go list all # in module-mode = all packages in the main module and their dependencies. all # in GOPATH-mode = ALL packages on local system <- CAREFUL, this may take a long time