Package management is one of the things Go has always forgotten. One of the biggest drawbacks of the previous one (before 1.11) go get lack of support for managing dependency versions and enabling repeatable builds. The community has developed package management programs and tools such as Glide, dep and many others serves as the actual solution to the dependencies version.

“I use go get for production buildings. “- no one ever said.

Go’s package management implementation traces its roots to Google (which has a huge monolithic archive for all its source code). Let’s find out what’s wrong with the ‘pre-go module’ package management tools.

  1. Version dependencies.
  2. Supplier dependencies.
  3. Need GOPATH.

Version dependencies

go get does not support the module version by default. The idea for the first version of Go’s package management was – no module versions needed, no need for third-party module repositories, you build everything from your current branch.

In Pre Go 1.11, adding a dependency meant cloning the source repository of that dependency GOPATH. That was about it. There was no idea about the versions. Rather, it always showed the current main branch during cloning. Another important issue arose when different projects needed different versions of the dependency – which was also not possible.

Supplier dependencies

Packet delivery is commonly referred to as the case where dependent packages are stored in the same location as the project. This usually means that your dependencies will be checked against a source management system such as Git.

Consider this case – A uses a dependency B that uses a dependency C feature introduced in version 1.5 of C, B must be able to ensure that the build version of A uses C 1.5 or later. Pre Go 1.5 did not have a mechanism for carrying the dependency code alongside commands without rewriting import paths.

Need GOPATH

GOPATH there are two main reasons:

  1. In Go import the notification refers to the package through a fully approved import route. GOPATH exist so that from any directory inside GOPATH/src the go tool can calculate the absolute import path of that package.
  2. Location to store the dependencies you are looking for go get.

What’s wrong with this?

  1. GOPATH does not allow the project source to be checked in the selected directory, as they are used to in other languages.
  2. In addition, GOPATH does not allow a developer to check more than one copy of a project (or its dependencies) at the same time.

Introducing Go modules

Go 1.11 introduces preliminary support for Go modules. Go to Wiki,

A module is a collection of related Go packages that are versioned as a single entity. The modules store precise dependency requirements and create reproducible structures.

Go modules have three important built-in features:

  1. go.mod file similar to package.json or Pipfile.

  2. Machine Generated Transitive Dependency Description – go.sum.

  3. No more GOPATH restriction. Modules can be on any path.

$ go help mod
Go mod provides access to operations on modules.

Note that support for modules is built into all the go commands,
not just 'go mod'. For example, day-to-day adding, removing, upgrading,
and downgrading of dependencies should be done using 'go get'.
See 'go help modules' for an overview of module functionality.

Usage:

    go mod <command> [arguments]

The commands are:

    download    download modules to local cache
    edit        edit go.mod from tools or scripts
    graph       print module requirement graph
    init        initialize new module in current directory
    tidy        add missing and remove unused modules
    vendor      make vendored copy of dependencies
    verify      verify dependencies have expected content
    why         explain why packages or modules are needed

Use "go help mod <command>" for more information about a command.

Pertinent thread.

Switching to Go modules

If you want to use Go modules, upgrade to Go to version >= 1.11. Since GOPATH is being removed, module support can be activated in one of the following ways:

  • Call go command in the directory GOPATH/src tree, valid go.mod file to the current directory.
  • Go modules will not work if the source is below GOPATH. You can override this behavior by dragging go command GO111MODULE=on a set of environmental variables.

To get started porting, follow these simple steps:

  • Like GOPATH is no longer necessary, move the module out GOPATH.
  • Create the original module definition at the root of the project – go mod init github.com/username/repository. The best is, go mod automatically converts dependencies on existing package managers, such as dep, Gopkg, glide and six others. This will create a file named go.mod module name and dependencies with its versions.
$ cat go.mod
module github.com/deepsourcelabs/cli

go 1.12

require (
    github.com/certifi/gocertifi v0.0.0-20190410005359-59a85de7f35e
    github.com/getsentry/raven-go v0.2.0
    github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9
  • Run go build create a go.sum a file that contains the expected encryption checksums for the contents of certain module versions. This ensures that future downloads of these modules retrieve the same bits as the first download. Note that go.sum is not a lock file.
$ cat go.sum
github.com/certifi/gocertifi v0.0.0-20190410005359-59a85de7f35e h1:9574pc8MX6rF/QyO14SPHhM5KKIOo9fkb/1ifuYMTKU=
github.com/certifi/gocertifi v0.0.0-20190410005359-59a85de7f35e/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9 h1:dIsTcVF0w9viTLHXUEkDI7cXITMe+M/MRRM2MwisVow=
github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

Version Note: To maintain backward compatibility, if the module is version v2 or later, the main version of the module must included a /vN at the end of the module paths go.mod files (e.g. module github.com/username/repository/v2

Everyday commands

List the dependencies

go list -m all lists the current module and all its dependencies.

$ go list -m all
github.com/deepsourcelabs/cli
github.com/certifi/gocertifi v0.0.0-20190410005359-59a85de7f35e
github.com/getsentry/raven-go v0.2.0
github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9

in go list output, the current module, also known as main module, is always the first line, after which the dependencies are sorted by the module path.

List of available versions of the package

go list -m -versions github.com/username/repository a list of available versions of the package.

$ go list -m -versions github.com/getsentry/raven-go
github.com/getsentry/raven-go v0.1.0 v0.1.1 v0.1.2 v0.2.0

Addiction

Adding addiction is indirect. Once you have imported the dependency into the code, running go build or go test the command gets the latest version of the module and adds it go.mod file. If you want to add a dependency explicitly, rungo get github.com/username/repository.

Update / reduce dependency

go get github.com/username/repository@vx.x.x download and set a specific version of dependencies and updates go.mod file.

$ go get github.com/getsentry/raven-go@v0.1.2
go: finding github.com/getsentry/raven-go v0.1.2
go: downloading github.com/getsentry/raven-go v0.1.2
go: extracting github.com/getsentry/raven-go v0.1.2
$ cat go.mod
module github.com/deepsourcelabs/marvin-go

go 1.12

require (
    github.com/certifi/gocertifi v0.0.0-20190410005359-59a85de7f35e
    github.com/getsentry/raven-go v0.1.2
    github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9
)
$ cat go.sum
github.com/certifi/gocertifi v0.0.0-20190410005359-59a85de7f35e h1:9574pc8MX6rF/QyO14SPHhM5KKIOo9fkb/1ifuYMTKU=
github.com/certifi/gocertifi v0.0.0-20190410005359-59a85de7f35e/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/getsentry/raven-go v0.1.2 h1:4V0z512S5mZXiBvmW2RbuZBSIY1sEdMNsPjpx2zwtSE=
github.com/getsentry/raven-go v0.1.2/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9 h1:dIsTcVF0w9viTLHXUEkDI7cXITMe+M/MRRM2MwisVow=
github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

Supplier dependencies

When using modules, the go command completely overrides the vendor directories. Check for compatibility with older versions of Go, or make sure all the files used in the build are saved in a single file tree.go mod vendor.

This will create a directory named vendor to the root directory of the main module and store all packages of dependency modules there.

Note: To build the main module using the top-level vendor directory, run ‘go build -mod=vendor“.

Delete unused dependencies

go mod tidy cuts unused dependencies and updates go.mod file.

FAQ

Is GOPATH no longer needed?

Not goodbye GOPATH.

Which version is pulled by default?

The Go.mod file and the go command generally use semantic versions as a standard form to describe module versions so that versions can be compared to determine which one should be considered sooner or later than the other. Module version, such as v1.2.3 will be enabled by tagging the version in the source repository below. Unrecognized versions can be referred to in a manner similar to the “virtual version” v0.0.0-yyyymmddhhmmss-abcdefabcdef, where time is the binding time in UTC and the last suffix is ​​the binding hash prefix.

Should go.sum is checking for version control?

Yeah.

.

LEAVE A REPLY

Please enter your comment!
Please enter your name here