Go 1.11 and 1.12 implemented initial support for package management, and Go’s new dependency management system made dependency version information clear and easy to manage. Using Go Modules – The Go Blog

What’s different about the new package management model?

As a promoter of Go, I am often asked questions about the basic features of the language. The package management aspect of this one embarrsts me because Go’s package management was really “only available” before 1.11 compared to Python, Node, and Java.

Because:

  1. Without the use of additional tools, Go’s dependency packages need to be manually downloaded,
  2. Third party packages have no concept of version, and if the author of a third party package makes an incompatible upgrade, it can make developers uncomfortable
  3. In collaborative development, you need to unify the local development members$GOPATH/srcDependency packages under
  4. The referenced package refers to a package that has been moved, and the author needs to modify the reference himself if he does not change it.
  5. Source code for third-party packages and their own packages is under SRC, which is confusing. Directory storage can be problematic for projects with a mixed technology stack

The new package management mode solves the above problems

  1. Automatically downloads dependency packages
  2. Projects don’t have to be in GOPATH/ SRC anymore
  3. A go.mod file is generated within the project, listing package dependencies
  4. So the third party package will specify the exact version number
  5. For packages that have been moved, replace can be declared without changing the code

Let’s start with a small example to illustrate!

The preparatory work

  1. Upgrade golang version to 1.12 Go download
  2. Add the environment variable GO111MODULE to ON or AUTO
GO111MODULE=auto
Copy the code

Ready, very simple!!

Create a project

First, create a directory in your preferred location outside the $GOPATH/ SRC path. CD goes to the directory and create a new Hello. go file with the following contents

package main

import (
	"fmt"
)

func main(a) {
	fmt.Println("Hello, world!")}Copy the code

Initialize the module

In the current directory, run the go mod init + module name command line to initialize the module

go mod init hello
Copy the code

After running it, a go.mod file is generated in the current project directory. This is a key file that will be used to manage all subsequent packages.

Official note: In addition to go.mod, the go command maintains a file called go.sum, which contains the expected encrypted hash of the content of a particular module version. The go command uses the go.sum file to ensure that future downloads of these modules retrieve the same bits as the first download to ensure that the modules on which the project depends do not make unexpected changes, Whether it was malicious, accidental or otherwise. Both go.mod and go.sum should be checked in for version control. Go.sum doesn’t require manual maintenance, so it’s not a concern.

The generated file contains the module name and the current GO version number

The module hello go 1.12Copy the code

Note: Init is not required in subdirectories, all dependencies in subdirectories are organized in the go.mod file in the root directory

Come on, do something small and see how go.mod works

Next, make your project rely on third-party packages like beego, which most people are familiar with. Modify the Hello.go file:

package main

import "github.com/astaxie/beego"

func main(a) {
    beego.Run()
}

Copy the code

In the past, running hello.go required the go get command to download the Beego package to $GOPATH/ SRC

However, with the new package management, this is no longer necessary

Go run hello.go

Just a moment… Go automatically looks for packages in the code, downloads dependencies, and writes the dependencies and versions to the go.mod and Go.sum files. Check out go.mod and it will look like this:

Module hello go 1.12 require github.com/astaxie/beego v1.11.1Copy the code

The require key is the reference, followed by the package, and finally v1.11.1 is the version number of the reference

This completes a small example of creating a project using Go package management.

So, here’s a couple of little problems

Question 1: Where is the dependent package downloaded? Is it still in GOPATH?

Not here. With Go package management, dependent third-party packages are downloaded to $GOPATH/ PKG /mod.

If you successfully run this example, one such package can be found in your $GOPATH/ PKG /mod github.com/astaxie/[email protected]

Q2: How is the version of the dependent package controlled?

From the previous question, you can see that the package downloaded at $GOPATH/ PKG /mod github.com/astaxie/[email protected] will end up with a version number of 1.11.1, that is, $GOPATH/ PKG /mod can save different versions of the same package.

The version is specified in go.mod.

If not specified in go.mod, the go command will automatically download the latest version of the dependency in the code, as in this case.

If you use the require statement to specify the package and version in go.mod, the go command will download the package according to the specified path and version.

What is the version number of the dependent package? Is the version number marked by the package’s publisher, in the format of vN.n.n (n stands for number). The historical version of Beego in this case can be seen in its repository release Releases Releases Releases Releases Releases Releases · Astaxie/Beego · GitHub

If the package author does not already have a marked version, the default is v0.0.0

Can I place the project under $GOPATH/ SRC?

You can. But go takes different actions depending on the value of GO111MODULE. By default, GO111MODULE=auto

  • autoIn automatic mode, the project is in$GOPATH/srcWill be used in$GOPATH/srcIn $GOPATH/ SRC, use the require package in go.mod
  • onOpen mode, after 1.12, regardless in$GOPATH/srcUse the package required in go.mod, both inside and outside
  • Off: That’s the old rule.

Problem three: What if the address in the dependency packet is invalid? Such as golang.org/x/… What if all the packages under cannot be downloaded?

During the rapid evolution of Go, some of the dependencies changed addresses. Previous practice

  1. Modify the source code to replace the address of import with the new path
  2. Git clone or go get a new package, copy it to the old path of $GOPATH/ SRC, no matter what method it is, it is not easy to maintain, especially in multi-developer.

Mod is easy to use, replacing the package with replace in the go.mod file, for example

replace golang.org/x/text => github.com/golang/text latest

Thus, go would replace golang.org/x/text with github.com/golang/text, Principle is to download the latest version to under $GOPATH/pkg/mod/golang.org/x/text github.com/golang/text.

Q4: What is the use of the module name of go.mod generated by init?

In this case, the first line of the go.mod file generated with go mod init Hello declares module hello

Since our project is no longer in $GOPATH/ SRC, what about referencing itself? Just use the module name + path.

For example, create a tools.go file under the utils directory:

package utils

import"FMT"func PrintText(text string) {
	fmt.Println(text)
}
Copy the code

The hello.go file in the root directory can import “hello/utils” to reference utils

package main

import (
"hello/utils"

"github.com/astaxie/beego"
)

func main(a) {

	utils.PrintText("Hi")

	beego.Run()
}


Copy the code

Q5: How to manage old projects with new packages

  1. If in Auto mode, move the project to$GOPATH/srcoutside
  2. Go to the directory and runGo mod init + Module name
  3. go buildorgo runAt a time

That’s about it for Go 1.12 package management

Officially, starting with Go 1.13, module management mode will be the default mode for Go language development.

So Pick up!

Have a question or need to discuss the friend, can give me a message, learn together, progress together

Xiao Code Official Number: