Go Dependency Package management tool Comparison

Source: Internet
Author: User
Tags k8s
This is a creation in Article, where the information may have evolved or changed.
    • Gopath and Goroot
      • Goroot does not have to be set.
      • Gopath must be set, but not fixed
    • Dependencies within the project
    • Managing external Dependency Packages
      • Using Gopath to manage external dependencies
    • Vendor
      • Godep
      • Glide
      • Govendor
      • Golang official DEP
      • Comparison of the dependency management tools
      • Gvt
    • Vendor's problem

When you start to actually use go to do projects, you inevitably encounter the problem of dependency packs. The dependency management of Go is not the same as that of Java+maven, we begin to understand the idea from Gopath, and then compare the current commonly used dependency package management tool.

Gopath and Goroot

It is easy for beginners to be confused by these two environment variables.

Goroot does not have to be set.

Goroot is not required to be set. See Installing to a custom location, the default go will be installed under/usr/local/go, but also allow custom installation locations, Goroot is to inform the go current installation location, Compile the time from Goroot to find the SDK system Libariry.

For example, I use Ubuntu 16.04, the default go version is 1.6, if I want to upgrade to a newer version, I need to customize the installation, so I set the Goroot: export GOROOT=$HOME/go1.7.4 .

Gopath must be set, but not fixed

The purpose of Gopath is to tell go where to look when code is needed. Note the code here, including this project and the code that references the external project. Gopath can be reset as the project is different.

There will be 3 directories under Gopath: src, bin, pkg.

    • SRC directory: Where to find code when go compiles
    • Bin directory: Go get godep this bin tool when binary files are downloaded to the destination
    • Pkg directory: Where the generated lib files are stored.

Dependencies within the project

Take Kubernetes as an example. The Kubectl.go in the kubernetes/cmd/kubectl/kubectl.go app package is referenced in the code, which reads:

import ("os""k8s.io/kubernetes/cmd/kubectl/app")

So how does go look for this package when compiling?

This is the time for Gopath to play a role. Go compile will go to $gopath/src/directory to find the required code, so as long as the above App/kubectl.go in the $GOPATH/src/k8s.io/kubernetes/cmd/kubectl/ inside, go compile time can be found, then natural, kubernetes/cmd/kubectl/kubectl.go also need to put $GOPATH/src/k8s.io/ in. The code structure in the final $gopath is this:

├── src│   ├── k8s.io│   │   └── kubernetes│   │       ├── cmd│   │       │   ├── kubectl│   │       │   │   ├── app│   │       │   │   │   ├── BUILD│   │       │   │   │   └── kubectl.go│   │       │   │   ├── BUILD│   │       │   │   ├── kubectl.go│   │       │   │   └── OWNERS

Managing external Dependency Packages

Inevitably we will use external dependency packages. Go is very elegant in this area. Go does not use Maven as a Java to manage dependencies, package versions, but instead use Gopath directly to manage external dependencies.

Using Gopath to manage external dependencies

Go allows you to import code from different code libraries, such as github.com, K8s.io, golang.org, and so on, and for code that requires import, you can use the go get command to drop it into the gopath corresponding directory. For example go get github.com/silenceshell/hcache , it will be downloaded to the $GOPATH/src/github.com/silenceshell/hcache , and when other projects are in import github.com/silenceshell/hcache the time to find the corresponding code.

See here also understand, for go, actually not care your code is internal or external, in short, all in Gopath, any import package path is starting from Gopath; the only difference is that the internally dependent package is written by the developer himself, and the externally dependent package is go Get down the.

Vendor

There is a serious problem with relying on gopath to solve the go import: If the project depends on the package has been modified, or simply deleted, it will affect my project. Therefore, prior to the 1.5 release, in order to circumvent this problem, it is common to copy the currently used dependency package.

In order for the project to continue to use these dependent packages, there are several ways to do so:

    • Copy the dependent package into the project source tree and modify the import
    • Copy the dependent package into the project source tree and modify the Gopath
    • Record the version of the dependent package in a file, and then update the dependency package in Gopath to the corresponding version (because the dependency package is actually a git library, you can switch versions)

Go as a modern language, incredibly to use so complex not intuitive and nonstandard method to manage dependence, no wonder in the early days there will be a lot of people are very not optimistic about the future of go.

To solve this problem, go has introduced the Vendor property in version 1.5 (the default is to set the GO environment variable go15vendorexperiment=1) and the vendor attribute is turned on by default in version 1.6.

To put it simply, the vendor property is to let go compile, take precedence from the project source root directory of the vendor directory to find the code (can be understood as cut once gopath), if there is vendor, then no longer go to Gopath to find.

Take KUBE-KEEPALIVED-VIP as an example. The project will call K8s.io/kubernetes's library (Client), but if you compile keepalived with the 1.5 version of Kubernetes code, it will compile:

./controller.go:107: undefined: "k8s.io/kubernetes/pkg/client/unversioned".Client

Check the code to find that the code in version 1.5 has changed, there is no such client. This is what we said earlier to rely on Gopath to solve the problem of go import, the code is wrong.

The KUBE-KEEPALIVED-VIP project uses the vendor directory to solve this problem: The project copies all dependent packages to the vendor directory, and for those who need to compile the project, just clone the code from GitHub to the $GOPATH/src future. You can go into go build (note that the KUBE-KEEPALIVED-VIP project must be copied to the $GOPATH/SRC directory, otherwise go will ignore the vendor directory, still go to $gopath/src to find the dependency package).

But the vendor directory brings new problems:

    • The dependency package in the vendor directory does not have version information. This dependency package is out of version management and is a bit difficult for upgrades and problem tracking.
    • How to conveniently get what packages the project relies on and easily copy them to the vendor directory? Manual is fxxk.

Community in order to solve these (engineering) problems, on the basis of vendor developed a number of management tools, more commonly used GODEP, Govendor, Glide. Go officials are also developing official DEP, which is still in Alpha state.

Here's a look at the more gode, glide and Govendor used.

Godep

Many of GODEP's users, such as docker,kubernetes, CoreOS, etc. go projects use GODEP to manage their dependencies, but the reason may be that there are no early tools to choose from.

GODEP earlier versions do not rely on vendor, so the release of Go is very loose, and the previous version of Go 1.5 can be used, but behaves differently. After the launch of vendor, GODEP also changed to use vendor.

GODEP use is simple: When your project is written, use Gopath's dependent package to test OK, execute:

$ godep save

Take Hcache, for example, to go save do 2 things:

    • Scan the code for this project to record the packages that are dependent on the Hcache project and the version number of the package (that is, git commit) to the Godeps/godeps.json file
    • Copy the dependent code from GOPATH/SRC to the vendor directory (the. Git directory that ignores the original code). For earlier versions that do not support vendor, they are copied to the godeps/_workspace/

An example of a godeps.json.

{    "Importpath": "Github.com/silenceshell/hcache",    "Goversion": "go1.7",    "Godepversion": "v79",    "Deps": [        {               "Importpath": "Github.com/tobert/pcstat",            "Rev": "91A7346E5B462A61E876C0574CB1BA331A6A5AC5"        },          {               "Importpath": "Golang.org/x/sys/unix",            "Rev": "0b25a408a50076fbbcae6b7ac0ea5fbb0b085e79"        }       ]   }

If you want to add a new dependency package:

    1. Run Go get Foo/bar
    2. Edit your code to import Foo/bar.
    3. Run GODEP Save (or GODEP save./...).

If you want to update a dependent package:

    1. Run Go get-u foo/bar
    2. Run GODEP update Foo/bar. (You can use the ... wildcard, for example GODEP update foo/...).

GODEP also supports the godep restore ability to reverse-copy code under vendor to $gopath. But I didn't expect this feature to work under any circumstances.

Glide

Glide also came out after the vendor. Glide's dependency packet information is in Glide.yaml and Glide.lock, which records all dependent packages, which record the version information of the dependent package (how good the composition is).

Glide use is not troublesome:

glide create  # 创建glide工程,生成glide.yaml# 生成glide.lock,并拷贝依赖包work, work, workglide update  # 更新依赖包信息,更新glide.lock

Glide Install updates the package information according to Glide.lock, and if not, it will take a glide update build Glide.lock

Finally, a project that uses glide management dependencies will be:

──$GOPATH/src/myProject (Your project)  ├─ glide.yaml  ├─ glide.lock  ├─ main.go (Your main go code can live here)  ├─ mySubpackage (You can create your own subpackages, too)  |    ├─ foo.go  ├─ vendor       ├─ github.com            ├─ Masterminds                  ├─ ... etc.

Glide is more versatile.

    • glide treeCan be very intuitive to see the vendor in the dependency package (will be removed later, feel no use)
    • glide listCan list all packages under vendor
    • Glide support for version Control systems more, in addition to support git, also support SVN, Mercurial (Hg), BZR
    • Most importantly, GLIDE.YAML can specify more information, such as the tag of the dependent package, the repo, the OS of the pack, and arch. Allows specifying repo to resolve the package name, but using a fork-out project.

Govendor

Govendor is after the vendor out, the function is relatively godep a little more, but the core problem of the solution is basically the same. Govendor requires 2 commands when generating the vendor directory:

    • govendor initGenerated vendor/vendor.json , at which point only the information for this project is in the file
    • govendor add +externalUpdate vendor/vendor.json , and copy the code under Gopath into the vendor directory.

Govendor can also directly specify the dependent package version to get the package, which also has a bit version management shadow.

# Setup your project.cd"my project in GOPATH"govendor init# Add existing GOPATH files to vendor.govendor add +external# View your work.govendor list# Look at what is using a packagegovendor list -v fmt# Specify a specific version or revision to fetchgovendor fetch golang.org/x/net/context@a4bbce9fcae005b22ae5443f6af064d80a6f5a55govendor fetch golang.org/x/net/context@v1   # Get latest v1.*.* tag or branch.govendor fetch golang.org/x/net/context@=v1  # Get the tag or branch named "v1".

Compared to GODEP, Govendor a little bit more cumbersome (such as Govendor init what is the use), slightly richer in functionality.

Golang official DEP

Although Golang's DEP is still alpha, it can be used.

$ dep init$ dep ensure -update$ dep ensure github.com/pkg/errors@^0.8.0

There is no special request, a DEP init is enough, if you want to upgrade, or specify a tag version, you can use DEP ensure. DEP also has a very handy feature, DEP prune, which can remove unused package.

Comparison of the dependency management tools

The go official Wiki gives a more comprehensive comparison.

GODEP more intuitive, more users, some personal small projects can be used, glide features richer, closer to Maven (for example, Glide.lock with Maven pom.xml similar, you can specify to get a version), new projects can consider using glide.

Of course, it is also expected that Golang's DEP will be better used to solve the current problem of relying on too much fragmentation of the package management tools.

Gvt

Glide/godep/govendor will only pull the import dependency package, and will not control the dependency package for the dependent package. In this case, all dependencies can be pulled to the vendor directory using GVT. is not very sour, but it is helpful to solve the problem that the golang.org library is inaccessible, and it can also flatten all the dependent packages that the team uses.

Vendor's problem

Overall glide more perfect. However, there are some unpleasant places, such as code copy flooding: A package has a copy in different projects, and its version may not be the same, when the dependent packages are more, the vendor directory will be very large. This is vendor's pot (or Gopath's original sin, not like maven for the same package in the local there are multiple versions, local only one code), there seems to be no way to avoid.

Of course, don't expect go to improve that.

"Through the design of the standard library, great effort is spent on controlling dependencies. It can be better to copy a little code than to pull in a big library for one function. Dependency Hygiene trumps code reuse. "-Go at Google

Copy point code What's wrong, right?

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.