Go has included support for versioned modules as proposed here - https://golang.org/design/24301-versioned-go since 1.11. The initial prototype vgo was announced - https://research.swtch.com/vgo in February 2018. In July 2018, versioned modules landed in the main Go repository.
Since Go 1.14 - https://golang.org/doc/go1.14, module support is considered ready for production use, and all users are encouraged to migrate to modules from other dependency management systems. If you are unable to migrate due to a problem in the Go toolchain, please ensure that the problem has an open issue - https://github.com/golang/go/wiki/Modules#github-issues filed. (If the issue is not on the Go1.16 milestone, please comment on why it prevents you from migrating so it can be prioritized appropriately). You can also provide an experience report - https://github.com/golang/go/wiki/ExperienceReports for more detailed feedback.
A module is a collection of related Go packages that are versioned together as a single unit.
Modules record precise dependency requirements and create reproducible builds.
Most often, a version control repository contains exactly one module defined in the repository root. (Multiple modules - https://github.com/golang/go/wiki/Modules#faqs–multi-module-repositories are supported in a single repository, but typically that would result in more work on an on-going basis than a single module per repository).
Summarizing the relationship between repositories, modules, and packages:
A repository contains one or more Go modules.
Each module contains one or more Go packages.
Each package consists of one or more Go source files in a single directory.
Modules must be semantically versioned according to semver - https://semver.org/, usually in the form
v(major).(minor).(patch), such as
v1.5.0-rc.1. The leading
v is required. If using Git, tag released commits with their versions. Public and private module repositories and proxies are becoming available (see FAQ - https://github.com/golang/go/wiki/Modules#are-there-always-on-module-repositories-and-enterprise-proxies below).
A module is defined by a tree of Go source files with a
go.mod file in the tree’s root directory. Module source code may be located outside of
GOPATH. There are four directives:
Here is an example go.mod file defining the module
A module declares its identity in its
go.mod via the
module directive, which provides the module path. The
import paths for all packages in a module share the module path as a common prefix. The module path and the relative path from the
go.mod to a package’s directory together determine a package’s import path.
For example, if you are creating a module for a repository
github.com/user/mymod that will contain two packages with import paths
github.com/user/mymod/bar, then the first line in your
go.mod file typically would declare your module path as module
github.com/user/mymod, and the corresponding on-disk structure could be:
In Go source code, packages are imported using the full path including the module path. For example, if in our example above, we declared the module identity in
go.mod as module
github.com/user/mymod, a consumer could do:
This imports package bar from the module
replace directives only operate on the current (“
replace directives in modules other than the main module are ignored when building the main module. The
exclude statements, therefore, allow the main module complete control over its own build, without also being subject to complete control by dependencies. (See FAQ - https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive below for a discussion of when to use a replace directive).
mkdir -p go-mod-example
go mod init
go mod init command initializes and writes a new
go.mod file in the current directory, in effect creating a new module rooted at the current directory. The
go.mod file must not already exist.
init accepts one optional argument, the module path for the new module. See Module paths for instructions on choosing a module path. If the module path argument is omitted, init will attempt to infer the module path using import comments in
.go files, vendoring tool configuration files, and the current directory (if in GOPATH).
go mod init [module-path]
Initialize a new module:
You can replace
cloudolife.com/examples/go-mod-example with your preferred content.
go mod init cloudolife.com/examples/go-mod-example
Write your code:
cat <<EOF > hello.go
go mod tidy
go mod tidy [-e] [-v]
go mod tidy ensures that the
go.mod file matches the source code in the module. It adds any missing module requirements necessary to build the current module’s packages and dependencies, and it removes requirements on modules that don’t provide any relevant packages. It also adds any missing entries to
go.sum and removes unnecessary entries.
Build and run:
go build -o hello
The go.mod file was updated to include explicit versions for your dependencies, where
v1.5.2 here is a semver tag:
go mod vendor
go mod vendor [-e] [-v]
go mod vendor command constructs a directory named
vendor in the main module’s root directory that contains copies of all packages needed to support builds and tests of packages in the main module. Packages that are only imported by tests of packages outside the main module are not included. As with go mod tidy and other module commands, build constraints except for ignore are not considered when constructing the vendor directory.
When vendoring is enabled, the go command will load packages from the vendor directory instead of downloading modules from their sources into the module cache and using packages those downloaded copies. See Vendoring for more information.
Note there was no go get required in the example above.
Your typical day-to-day workflow can be:
importstatements to your
.gocode as needed.
Standard commands like
go testwill automatically add new dependencies as needed to satisfy imports (updating
go.modand downloading the new dependencies).
When needed, more specific versions of dependencies can be chosen with commands such as
go get [email protected],
go get foo@master(foo@default with mercurial),
go get foo@e3702bed2, or by editing
A brief tour of other common functionality you might use:
go list -m all— View final versions that will be used in a build for all direct and indirect dependencies (details)
go list -u -m all— View available minor and patch upgrades for all direct and indirect dependencies (details)
go get -u ./...or go
get -u=patch ./...(from module root directory) — Update all direct and indirect dependencies to latest minor or patch upgrades (pre-releases are ignored) (details)
go build ./...or go
test ./...(from module root directory) — Build or test all packages in the module (details)
go mod tidy— Prune any no-longer-needed dependencies from go.mod and add any dependencies needed for other combinations of OS, architecture, and build tags (details)
gohack— Use a fork, local copy or exact version of a dependency (details)
go mod vendor— Optional step to create a vendor directory (details)