Golang's package management has always been a criticism, from the vendor mechanism introduced by golang1.5 to the quasi-official tool dep, so far there is no simple solution.
But now go modules with the release of golang1.11 to meet with us, this is officially advocated by the new package management, and even the project management mechanism, can no longer need the existence of Gopath.
Go modules Initialization
Now modules mechanism is still in the early stage, so Golang provides an environment variable "go111module", the default value is auto, if there is go.mod file in the current directory, use Go modules, otherwise use the old Gopath and vendor mechanism, Because go get will only download go modules in the modules mechanism, this behavior will be the default value in later version, here we keep auto, if you want to use modules directly without excessive gopath, then the "Go111module" Set to ON.
Unlike traditional Gopath, modules does not need to include subdirectories such as Src,bin, where a source code directory or even an empty directory can be used as a module, as long as it contains go.mod files.
We'll use an empty directory to create our first module:
To initialize the modules, you need to use the following command (assuming the configuration is already installed golang1.11):
Go mod init [module name]
Our module is called Test, so it is:
Go mod init test
After the initial completion, a Go.mod file is generated in the directory with only one line of "module test".
Package Management
So how do we manage the package? Don't worry, when we use Go build,go test and go list, go automatically updates the Go.mod file and writes dependencies to it.
If you want to handle dependencies manually, then use the following command:
Go mod tidy
This command automatically updates the dependencies and puts the package download into the cache.
Here we use a simple example of CHROMEDP as the experimental code main.go, and see how go modules handles the dependencies of the package.
We run the Go mod tidy manually:
Find and download Packages
We found one more go.sum, and we looked at what it was:
Yes, as you've already guessed, this is the version record that we've directly quoted for the package and its own needs, and that's where go modules to find the packages.
Incidentally, if we do not make any changes, we will use the latest version of the package by default, if the package has been tagged, then the latest tag corresponding version will be used.
Let's use go build to compile our code:
Go Build
It is worth noting that a new compilation option "-mod" is added, which has the following optional values:
Go build-mod=readonly
Any situation that causes dependency changes in this mode will cause build to fail, as mentioned in the previous build to find and update dependencies, and use this option to check for changes in dependencies.
Go Build-mod=vendor
This means ignoring the package in the cache, using only the version in the vendor directory.
After the build is complete, the directory structure is as follows:
Our code was built successfully, and package management was done for us by go modules.
Version control of the package
Another important feature of package management is the version control of the package. Modules can do the same.
Before we introduce versioning, we need to make it clear that if there is the same package rule in the go.mod of the upper and lower directories, then the upper directory is unconditionally covered in the downlevel directory for the purpose of building the main module without being affected by the dependent package.
So let's see what go.mod looks like:
Module Testrequire GITHUB.COM/CHROMEDP/CHROMEDP v0.1.2
If there are multiple dependencies, this can be true:
Module Github.com/chromedp/chromedprequire (Github.com/chromedp/cdproto V0.0.0-20180713053126-e314dc107013github.com/disintegration/imaging V1.4.2github.com/gorilla/websocket V1.2.0github.com/knq/sysutil V0.0.0-20180306023629-0218e141a794github.com/mailru/easyjson V0.0.0-20180606163543-3fdea8d05856golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81)
The first part is the name of the package, that is, the import needs to write the part, and the space after the version number, the version number follows the following rules:
Vx.y.z-pre.0.yyyymmddhhmmss-abcdefabcdefvx.0.0-yyyymmddhhmmss-abcdefabcdefvx.y. (z+1) -0.yyyymmddhhmmss-abcdefabcdefvx.y.z
That is, version number + timestamp +hash, we specify the version only need to set the version number, no version of the tag will need to find the corresponding commit time and hash value.
The latest version of the package is used by default.
Now we have to modify the dependency, we want to use the v0.1.0 version of CHROMEDP, how to do?
Only the following commands are required:
Go mod edit-require="github.com/chromedp/chromedp@v0.1.0"
Add the version number you want after @. The Go.mod has been modified:
Module Testrequire GITHUB.COM/CHROMEDP/CHROMEDP v0.1.0
We also need to let go modules update dependencies, here we have manual go mod tidy:
Notice that the darker two lines, we have switched to the v0.1.0 version.
Go modules is a big topic and I'll introduce it later.
Because go1.11 just released soon, this paper as a pathfinder, there will be errors and omissions, welcome to correct me!