This is a creation in Article, where the information may have evolved or changed.
For developers who are moving from programming languages like Ruby, Python or Node to the go language, there may be a question: How are package dependencies managed in the Go language? Is there any convenient tool to use? I have studied this problem recently, here is my research report.
The package management mechanism provided by the Go language itself
In the go language, we can use go get
commands to install the managed code in the remote repository, unlike the centralized package management mechanism such as Ruby Gem, PyPI, and the Go Language package management system is centrally oriented. Simply put, the go get
command supports any location-managed Git or mercurial repository, whether it's a Github or Google Code package, which can be installed with this command.
We know that the statements in the go language are import
go get
still being introduced using the go-to absolute path for packages that have been installed locally. For example, for Goji installed from GitHub, its path URL on GitHub is https://github.com/zenazn/goji
, so import
it needs to use the following code:
1
|
Import "Github.com/zenazn/goji"
|
Because of this, the Go language can query dependencies by directly parsing the statements in the code import
. go get
when the command executes, it automatically resolves import
to install all dependencies.
Besides go get
, the Go language also provides a Workspace mechanism, which is also a confusing design. Simply by setting the GOPATH
environment variable, GOROOT
you specify the location of the Go code in addition to the specified directory (that is, the location of the Workspace). In general, the GOPATH
directory will contain pkg
, src
and bin
three subdirectories, which are useful for each of the three directories.
bin
The directory is used to place the compiled executable file, so that the executable file here can be easily run and set the variables in the shell PATH
.
src
The directory is used to place the code source file, which import
is used as the root directory when it is in progress. The code you write should also be placed below it.
pkg
The link object that is used to place the installed package. This concept is a bit like a link library, where Go will put the compiled, connected libraries here for easy compile-time linking. Objects of different system and processor architectures are stored in pkg
different folders.
My GOPATH
directory tree looks like this:
1
|
├──bin├──pkg│└──darwin_amd64│ └──github.com│ └──zenazn│ └──goji└──src ├──code. google.com │└──p │ └──go.crypto └──github.com └──zenazn └──goji
|
In general, your own code should not be placed directly src
under the directory, but should be created for the corresponding project folder. The go get
source code of the third party package is also placed in this directory, so it is generally recommended to set two GOPATH
, for example:
1
|
Export Gopath="/usr/local/share/go:$HOME/codes/go"
|
This way the third-party package is placed by default in the first path, and you can write your own code under the second path. Although the Go language itself has provided a fairly powerful package management approach, there are still some deficiencies:
- It is not easy to isolate the environment of different projects
- It is not easy to control the version of a dependent package
- Cannot manage version of Go itself
So we also need some third-party tools to compensate for these flaws.
Third-party management tools
Gopath Management and package management
Because GOPATH
of the mechanisms that exist, we can use multiple GOPATH
methods to implement project isolation. For example, for each project, a different path is assigned as the GOPATH
. Tools that can achieve such a purpose are GVP and so on.
For GVP, to create one for the current directory GOPATH
, just execute it gvp init
. GVP will create a new hidden folder in the current project directory as GOPATH
the location to point to. Use the following two commands to modify environment variables when switching environments. This approach is similar to the virtualenv in Python.
1 2
|
Source inch # Enter the Gopath environment corresponding to the current directory source GVP out # Log out the Gopath environment corresponding to the current directory
|
As for more granular management of the dependent packages, the tools that can be matched are the gpm. gpm
a bit similar to the PIP tool in Python. He can generate a file named Godeps
, which records the URL of each dependent package and the version used (hash tag). A previous article mentioned that you gpm
can only manage dependencies from Github, but the current version already supports non-Git managed dependency packages.
Tools that manage dependent package versions based on the same principles also have GODEP. This tool has a fairly high degree of attention on Github. The resulting Godeps
file is stored in JSON format and is a similar tool to NPM in node. js.
In general, several of these tools have been able to solve the problem of isolating the project environment and controlling the version of the dependent package. But it is not easy to use, in order to be able to automatically switch environment variables when we CD to a directory, we may also need to do some configuration in the shell to enable it cd
to automatically switch environment variables in the project directory.
One of the better options for this is Go Manager (GOM), which produces Gomfile
almost the same format as the Ruby Gem. Gom is probably the most convenient one of these tools, so gom build
go build
you don't have to configure the shell or deal with environment variables as long as you compile with commands instead of the original commands.
Go language version Management
For the Go language, there is generally no need to make multiple language versions coexist. The Go language has not experienced a disruptive version upgrade like Python 2.x to 3.x or Ruby 1.x to 2.x. The old code is normally able to run correctly in the new language version. However, GVM is a good choice when it comes to having multiple versions of a non-concurrent version.
The use of GVM is similar to that of RVM.
1 2
|
# Install GO1 version GVM use go1 # Modify environment variables using GO1 version of Go
|
Summarize
Whether it is necessary to use more than one Workspace is still controversial, such as in the relevant question and answer on this stackoverflow, it has been suggested that only one Workspace can be used to deal with most cases.
In the study of related issues, I found that many Go language users are also with the original programming language thinking, which from the above described in the features of the many tools can be easily seen: gvp
and gpm
is the typical Python package management mode, gvp
corresponding virtualenv
to, gpm
pip
If you were a user of node. js and NPM, GoDeps
it would certainly give you a sense of familiarity, not to mention the last one gom
, which mimics Ruby gems from name to file format.
Developers of different programming backgrounds came to the Go language and each brought their own dependency package management and formed their own communities. This phenomenon, although the developers of their own circles to avoid the choice of phobias, but the resulting solutions are divided and incompatible with the situation also needs to be addressed. At this point we cannot help but ask, what should Go's own solution be? Why doesn't the Go language have an official standard solution?
We can get some answers to some of the words from the Go FAQ:
Versioning is a source of significant complexity, especially in large code bases, and we were unaware of any approach that Works well at scale a large enough varietyof situations to is appropriate to force on all Go users. (Versioning of dependent packages is a very complex issue, especially when the code size is relatively large.) We have not found any way to work well in all situations, so there is no way good enough to force all Go users to use it.
So at this stage, for the Go language package management solution, we can only "look at each other, benevolent see."
Finally, for readers who want to learn more about package management in the go language and more available tools, here are two more related articles: Go Pack Management and a Journey in Golang packages Manager