Go Modules is a new feature in Golang 1.11. The go command directly supports using modules, including logging and resolving dependencies on other modules. Modules replaces the old Gopath-based method to specify which source files to use in a given build.

Go Module uses prerequisites

  • Golang version >= 1.11

  • Set the GO111MODULE

GO111MODULE set

The GO111MODULE has three values: off, ON, and auto (default).

  • GO111MODULE=off, the go command line will not support the module function, the way to find dependent packages will be the old version of the vendor directory or GOPATH mode to find.

  • GO111MODULE=on, the go command line will use modules without looking in the GOPATH directory at all.

  • GO111MODULE=auto, default, if you call go in a directory other than $GOPATH/ SRC and use a valid go.mod file in the current directory or any of its parents, go starts modules.

When modules is enabled, the location of dependent packages is changed to $GOPATH/ PKG, allowing multiple versions of the same package to coexist, and multiple projects can share cached Modules.

Go Mod package management tool

Golang provides the Go mod command to manage packages.

The command instructions
download Downloading dependency packages
edit Edit the go. The mod
graph Print the module dependency diagram
init Initialize the mod in the current directory
tidy Pull missing modules and remove unused modules
vendor Copy dependencies to vendor
verify Verify that the dependencies are correct
why Explain why dependencies are needed

How is it used in a project

  • Initialize the

Execute the following command in the project root directory

$ mkdir hello-go
$ cd hello
$ go mod init hello-go
Copy the code

This will generate the go.mod file in the Hello directory

The module example.com/hello go 1.14Copy the code
  • Update the go. The mod

Create sample code server.go to update dependencies in go.mod in two ways

package main import ( "net/http" "github.com/labstack/echo" ) func main() { e := echo.New() e.GET("/", func(c echo.Context) error { return c.String(http.StatusOK, "Hello, World!" ) }) e.Logger.Fatal(e.Start(":1323")) }Copy the code

** Method 1: ** Execute in the project root directory

$ go run server.go
Copy the code

or

$ go run ./...
Copy the code

. /… The pattern matches all packages in the current module

** Method 2: ** Run the go get command to update dependencies

$ go get -u github.com/labstack/echo
Copy the code

Description of the go.mod file

The sample go. Mod

Module example.com/hello the require (github.com/labstack/echo v3.3.10 + incompatible / / indirect github.com/labstack/gommon V0.2.8 // indirect github.com/mattn/go-colorable v0.1.1 // indirect github.com/mattn/go-isatty v0.0.7 // indirect Github.com/valyala/fasttemplate v1.0.0 / / indirect golang.org/x/crypto v0.0.0-20190313024323 - a1f597ede03a / / indirect) Go to 1.14Copy the code

Commands in the go.mod file

Mod provides the following commands: module, require, replace, and exclude:

  • The module statement specifies the package name (path)

  • Dependency module specified by the require statement

  • The REPLACE statement replaces dependency modules

  • The exclude statement can ignore dependency modules

Go Semver (Semantic version)

Golang officially recommends a best practice called Semver, which is an abbreviation that, when fully written, is Semantic Versioning, i.e., V0.1.1, in version format: major version number. The second version number. The increment rule is as follows:

Major version number: When you make incompatible API changes,

Minor version number: When you make a backward-compatible feature addition,

Revision number: When you make a backward compatible problem fix.

  • Benefits of semantic versions

Semver’s simplified version of the specification is obvious, but that alone is a bit of a weak argument. Strict versioning by Semver maximized backward compatibility and avoided the “breaking changes” golang was looking for. The two clicked, so Go Modules offers support for semantic versions.

If you use and distribute packages without a version tag or in v1.x, you probably won’t see much difference. The main difference is in v2.0.0 and later packages. According to the convention of semantic version, the occurrence of V2.0.0 must indicate a significant change and may not guarantee backward compatibility. How to handle this situation? The answer is simple: we simply append version information to the end of the package import path, for example:

Module my-module/v2 require (some/ PKG /v2 v2.0.0 some/ PKG /v2 v2.0.0 my/ PKG /v3 v3.0.1)Copy the code

The format is summarized as pkgpath/vN, where N is the major version number greater than 1. This version information also needs to be attached to the import code, such as import “some/ PKG /v2”. This changes the import path of the package without worrying about the restriction of backward compatibility for objects with the same name, since Golang believes that different import paths mean different packages.

But here are a few exceptions to this rule:

  1. The equivalent require gopkg.in/some/pkg.v2 v2.0.0 can be used when using the gopkg.in format

  2. The version information is not required to specify /vN by adding +incompatible, e.g., require some/ PKG v2.0.0+incompatible

  3. Setting GO111MODULE=off when using GO1.11 will remove this restriction, but not in Go1.12

In other cases, using the V2 + version directly will cause go mod errors.

Packages of v2+ version are allowed to coexist with other packages of different larger versions (provided /vN is added), and they will be treated as separate packages. In addition, /vN doesn’t affect your repository, you don’t need to create a repository for V2, it’s just an additional information added by the Go Modules. Of course, if you don’t want to conform to the specification or need to be compatible with existing code, specifying +incompatible can be a reasonable choice. But as it literally means, go Modules don’t recommend this behavior.

To summarize the go package upgrade process:

When you release a v2+ version of the library, you need to do the following:

  • Change module my-module to module my-module/v2

  • Change source code from import “my-module” to import “my-module/v2”

  • Double check that all versions of my-Module packages in your code are consistent and fix incompatibables

  • List all breaking changes carefully in Changelog

** Note: ** If you find the previous four steps too cumbersome, note that your user needs to specify +incompatible as a temporary solution.

Two dependent version formats in go.mod

  • Semver git tag
Github.com/labstack/gommon v0.2.8Copy the code
  • Pseudo version

If a Module does not have a valid semver version, go.mod will record the version through something called a “pseudo-version”.

The usual form for “pseudo-version” is vx.0.0-YYYYMMDDHhmmss -abcdefabcdef. Such as:

- a1f597ede03a golang.org/x/crypto v0.0.0-20190313024323Copy the code

V0.0.0 indicates the version number of Semver, and 20170915032832 indicates the version time. 14c0d48ead0c indicates the submitted Git hash.

How to solve the problem of dependency download failure

Not all packages download successfully for known reasons, such as the packages under Golang.org

Use the replace command in the go.mod file

Modules can be replaced with the corresponding github library using the replace directive in the go.mod file, such as:

Replace (golang.org/x/crypto v0.0.0-20190313024323-a1F597eDE03a => github.com/golang/crypto V0.0.0-20190313024323 - a1f597ede03a)Copy the code

Set the GOPROXY

Go added Go Proxy support in 1.13

export GOPROXY=https://goproxy.io

or

export GOPROXY=https://goproxy.cn

  • GOPROXY instructions

GOPROXY indicates the ascending and obtaining order of images. Image urls are separated by commas (,) and sorted in order of priority. **direct** indicates the source site.

Default value:

GOPROXY="https://proxy.golang.org,direct"

Here’s the official line:

The default setting for GOPROXY is

“proxy.golang.org,direct”, which means to try the

Go module mirror run by Google and fall back to a direct connection

if the proxy reports that it does not have the module (HTTP error 404 or 410).

Note: GOPROXY=off means “do not download any dependencies from the Internet”, GOPROXY=direct means “all dependencies will be downloaded from the source site”.

Understanding of the go.sum file

You probably know the power of NPM’s package-lock.json, which records the exact version, source, and checksum of all libraries to help developers use the correct version of the package. Usually we don’t ship with it, because package.json is sufficient, and package-lock.json being too detailed can have a negative impact on version control, change logging, etc.

If you look at the go.sum file, you might think that it is a lock file like package-lock.json, which is a big mistake. Go.sum is not a lock file.

More precisely, go.sum is a build status tracking file. It records all top-level and indirect dependencies of the current Module, as well as checksums of those dependencies, providing a 100% reproducible build process and security for the built objects.

Go.sum also retains version information about packages used in the past for possible version rollback at a later time, which is also different from regular lock files. So go.sum is not a lock file for the package manager.

So we should add go.sum and go.mod to the version control tool’s tracking list, and release them with your modules. If you publish a module that does not include this file, users will report errors while building, and there may be security risks (go.sum provides security checks).

How do I use the vendor directory in Go Modules

Golang has always provided freedom in tool selection, and if you don’t like the way Go Mod is cached, you can use Go Mod Vendor to go back to the vendor directory used by Godep or GoVendor for package management.

Of course, this command doesn’t allow you to migrate to go modules from a tool like godep. It simply downloads all the dependencies in Go. sum into the vendor directory. If you use it to migrate to Godep, you’ll find that the package rounds specified in the Vendor directory by Godep are quite different. So please don’t do it.

  • How to compile

Use go build-mod =vendor to build the project. Because go Build is shielded from vendor mechanism in Go Modules mode, the specific parameter -mod=vendor is required to restart the vendor mechanism.

Some common commands

  • Go get -u github.com/some/pkg Update the version number. Because the major version number is incompatible, the major version number will not be updated.

  • Go get -u= Patch Update number

  • Go list -m all Displays all dependent modules and their versions

  • Go list -u -m all Views available minor and revision numbers for updates

  • Go mod Tidy Removes unused modules from go.mod

reference

  • https://www.cnblogs.com/apocelipes/p/10295096.html

  • __https://juejin.cn/post/6844903791502819341

  • https://zhuanlan.zhihu.com/p/59549613

  • https://segmentfault.com/a/1190000020450159