ethan

ethan

新知,热爱生活,码农,读书
twitter
email
github

go mod package management tool

At the earliest time, all third-party libraries that Go language depends on were placed under the GOPATH directory, which resulted in only one version of the code being saved for the same library. How should different projects that depend on different versions of the same third-party library be resolved?
Go module is the version management tool officially introduced by Go language since version 1.11, and starting from version 1.13, go module has become the default dependency management tool for Go language.

The commonly used go mod commands are shown in the following table:

CommandFunction
go mod downloadDownload dependencies to local (default to GOPATH/pkg/mod directory)
go mod editEdit go.mod file
go mod graphPrint module dependency graph
go mod initInitialize the current folder and create go.mod file
go mod tidyAdd missing packages and remove unused packages
go mod vendorCopy dependencies to the vendor directory
go mod verifyDependency verification
go mod whyExplain why dependencies are needed

GOPROXY#

Proxy means proxy server. As we all know, there is a firewall in the domestic network, which makes it impossible for us to directly obtain some third-party packages of Go language through the go get command. GOPROXY is a way provided by the official Go language to provide package download services for users through intermediate proxy vendors. To use GOPROXY, you only need to set the environment variable GOPROXY.
Currently, the addresses of publicly available proxy servers are:

  • goproxy.io;
  • goproxy.cn: (recommended) provided by Qiniu Cloud in China.
    The command to set GOPROXY under MacOS or Linux is:
export GOPROXY=https://goproxy.cn

After Go language 1.13, the default value of GOPROXY is https://proxy.golang.org. In China, there may be slow downloads or inaccessible situations, so it is highly recommended to set GOPROXY to goproxy.cn in China.

Downloading specific versions of dependencies using the go get command#

Execute the go get command to download dependencies and specify the version of the dependency package at the same time.

  • Running the go get -u command will upgrade the packages in the project to the latest minor version or patch version;
  • Running the go get -u=patch command will upgrade the packages in the project to the latest patch version;
  • Running the go get [package name]@[version] command will download the specified version of the corresponding package or upgrade the corresponding package to the specified version.
    Note: The version number in the go get [package name]@[version] command can be in the form of x.y.z, such as go get foo@v1.2.3, or it can be a branch or tag on Git, such as go get foo@master, or it can be a hash value when committing on Git, such as go get foo@e3702bed2.

How to use in a project#

[Example 1] Create a new project:

  1. Create a new directory outside of GOPATH and use go mod init to initialize and generate the go.mod file.

go mod init hello
go: creating new go.mod: module hello

Once the go.mod file is created, its content will be fully controlled by the go toolchain. The go toolchain will modify and maintain the go.mod file when various commands are executed, such as go get, go build, go mod, etc.

go.mod provides four commands: module, require, replace, and exclude:

  • The module statement specifies the name (path) of the package;
  • The require statement specifies the dependent module;
  • The replace statement can replace the dependent module;
  • The exclude statement can ignore the dependent module.

The go.mod file generated by initialization is as follows:

module hello

go 1.13

  1. Add dependencies.

Create a new main.go file and write the following code:

1.  package main

3.  import (
4.      "net/http"
5.      "github.com/labstack/echo"
6.  )

8.  func main() {
9.      e := echo.New()
10.      e.GET("/", func(c echo.Context) error {
11.          return c.String(http.StatusOK, "Hello, World!")
12.      })
13.      e.Logger.Fatal(e.Start(":1323"))
14.  }

Running go run main.go will automatically find and download dependencies:

go run main.go
go: finding github.com/labstack/echo v3.3.10+incompatible
go: downloading github.com/labstack/echo v3.3.10+incompatible
go: extracting github.com/labstack/echo v3.3.10+incompatible
go: finding github.com/labstack/gommon v0.3.0
......
go: finding golang.org/x/text v0.3.0

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v3.3.10-dev
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                        O\
http server started on [::]:1323

Now check the content of go.mod:

module hello

go 1.13

require (
    github.com/labstack/echo v3.3.10+incompatible // indirect
    github.com/labstack/gommon v0.3.0 // indirect
    golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 // indirect
)

The principle of go module installation package is to first pull the latest release tag. If there is no tag, it will pull the latest commit. For details, please refer to the Modules Official introduction.

Go will automatically generate a go.sum file to record the dependency tree:

github.com/davecgh/go-spew v1.1.0/go.mod h1/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/labstack/echo v3.3.10+incompatible h1=
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/gommon v0.3.0 h1=
github.com/labstack/gommon v0.3.0/go.mod h1+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
... omitted many lines

Run the script go run main.go again and you will find that the check and installation of dependencies are skipped.

You can use the command go list -m -u all to check the packages that can be upgraded, and use go get -u need-upgrade-package to upgrade. The new dependency version will be updated to go.mod. * You can also use go get -u to upgrade all dependencies.

[Example 2] Refactor an existing project.

The project directory structure is:

├─ main.go

└─ api
└─ apis.go

The source code of main.go is:

1.  package main

3.  import (
4.      api "./api"  // Use relative path here
5.      "github.com/labstack/echo"
6.  )

8.  func main() {
9.      e := echo.New()
10.      e.GET("/", api.HelloWorld)
11.      e.Logger.Fatal(e.Start(":1323"))
12.  }

The source code of api/apis.go is:

1.  package api

3.  import (
4.      "net/http"

6.      "github.com/labstack/echo"
7.  )

9.  func HelloWorld(c echo.Context) error {
10.      return c.JSON(http.StatusOK, "hello world")
11.  }
  1. Use go mod init *** to initialize go.mod.

go mod init hello
go: creating new go.mod: module hello

  1. Run go run main.go.
go run main.go
go: finding golang.org/x/crypto latest
build _/D_/code/src/api: cannot find module for path _/D_/code/src/api

First, it will still find and download dependencies, and then run the main.go script. Here, an error is thrown:

build /D/code/src/api: cannot find module for path /D/code/src/api

But go.mod has been updated:

module hello

go 1.13

require (
    github.com/labstack/echo v3.3.10+incompatible // indirect
    github.com/labstack/gommon v0.3.0 // indirect
    golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 // indirect
)

So why does this error occur?

This is because the way main.go uses internal packages is different from before. Since go.mod will scan all packages in the same working directory and change the import method, hello needs to be used as the prefix of the path. In other words, it needs to be written as import hello/api. The import ./api allowed by the GOPATH/dep mode in the past is no longer valid.

  1. Update the old package import method.

So main.go needs to be rewritten as:

1.  package main

3.  import (
4.      api "hello/api" // Use relative path here
5.      "github.com/labstack/echo"
6.  )

8.  func main() {
9.      e := echo.New()
10.      e.GET("/", api.HelloWorld)
11.      e.Logger.Fatal(e.Start(":1323"))
12.  }

Note: When using go mod under Go language version 1.11, you may encounter errors like go build github.com/valyala/fasttemplate: module requires go 1.12. If you encounter such problems that need to be upgraded to 1.12, just upgrade to Go language version 1.12 or above.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.