我曾经将特定版本的供应商lib安装到项目文件夹中的环境 (node_modules) ,却被告知要安装该版本的 npm 库和package.json。
$ npm install express@4.0.0
所以我把那个版本的包导入到了我的项目中:
var express = require('express');
现在,我想在go中做同样的事情,我该怎么做呢?是否可以安装特定版本的软件包?如果是,要使用集中式 $GOPATH?又该如何导入一个版本而不是另一个版本?
我也许会这样做:
$ go get github.com/wilk/uuid@0.0.1
$ go get github.com/wilk/uuid@0.0.2
但是,我怎样才能在导入期间做出改变呢?
更新18-11-23:从Go 1.11 mod是官方实验。请参照@krish的回答。
更新19-01-01:从Go 1.12 mod仍然是官方实验。 从Go 1.13开始,模块模式将是所有开发的默认模式
旧式回答:
你可以通过官方设置版本 dep
dep ensure --add github.com/gorilla/websocket@1.2.0
go get是Go软件包管理器。它以完全分散的方式工作,并且在没有中央软件包托管存储库的情况下仍然可以发现软件包。
除了查找和下载软件包外,软件包管理器的另一个重要作用是处理同一软件包的多个版本。 Go采用了所有软件包管理器中最最小和最实用的方法。没有Go包的多个版本。
go get always总是从存储库中默认分支的HEAD提取。总是。这有两个重要含义:
作为软件包的作者,您必须坚持稳定的HEAD哲学。您的默认分支必须始终是软件包的稳定发行版本。您必须在功能分支中进行工作,并且仅在准备发布时才合并。
软件包的新主要版本必须具有自己的存储库。简而言之,包的每个主要版本(遵循语义版本控制)将具有自己的存储库,因此也具有自己的导入路径。
例如github.com/jpoehls/gophermail-v1和github.com/jpoehls/gophermail-v2。
当有人在Go中构建应用程序时,上述理念确实没有缺点。每个导入路径都是一个稳定的API。没有担心的版本号。太棒了!
更多详情 : http://zduck.com/2014/go-and-package-versioning/
</div>
我发现可行的方法是git的子模块系统。使用它,你可以在给定版本的代码和升级/降级是明确和记录-决不是偶然的。
我采取的文件夹结构是:
The folder structure I've taken with this is:
+ myproject
++ src
+++ myproject
+++ github.com
++++ submoduled_project of some kind.
</div>
从1.5开始 "vendor experiment"这有助于你管理依赖项。从第1.6章开始,这不再是一个实验。在Go wiki上还有一些其他的选择….
编辑:正如在这个答案中提到的gopkg一样。对于1.5之前的Github依赖来说,in是一个不错的选择。
You can use git checkout
to get an specific version and build your program using this version.
Example:
export GOPATH=~/
go get github.com/whateveruser/whateverrepo
cd ~/src/github.com/whateveruser/whateverrepo
git tag -l
# supose tag v0.0.2 is correct version
git checkout tags/v0.0.2
go run whateverpackage/main.go
Really surprised nobody has mentioned gopkg.in.
gopkg.in
is a service that provides a wrapper (redirect) that lets you express versions as repo urls, without actually creating repos. E.g. gopkg.in/yaml.v1
vs gopkg.in/yaml.v2
, even though they both live at https://github.com/go-yaml/yaml
This isn't perfect if the author is not following proper versioning practices (by incrementing the version number when breaking backwards compatibility), but it does work with branches and tags.
Glide对于Go来说是一个非常优雅的软件包管理,特别是如果你来自Node的npm或Rust的货物。
它在1.6版中与Godep的新供应商特性非常接近,但要简单得多。您的依赖项和版本被“锁定”在您的projectdir/vendor目录中,而不依赖于GOPATH.
使用brew(OS X)安装
$ brew install glide
初始化glide.yaml文件(类似于package.json)。 这还将从GOPATH中获取项目中现有的已导入软件包,然后将其复制到项目的vendor /目录中。
$ glide init
获取新包
$ glide get vcs/namespace/package
更新并锁定软件包的版本。 这将在项目目录中创建glide.lock文件来锁定版本。
$ glide up
我尝试过Glide,并很高兴将其用于当前项目。
</div>
dep
is the official experiment for dependency management for Go language. It requires Go 1.8 or newer to compile.
To start managing dependencies using dep
, run the following command from your project's root directory:
dep init
After execution two files will be generated: Gopkg.toml
("manifest"), Gopkg.lock
and necessary packages will be downloaded into vendor
directory.
Let's assume that you have the project which uses github.com/gorilla/websocket
package. dep
will generate following files:
Gopkg.toml
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
[[constraint]]
name = "github.com/gorilla/websocket"
version = "1.2.0"
Gopkg.lock
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/gorilla/websocket"
packages = ["."]
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
version = "v1.2.0"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "941e8dbe52e16e8a7dff4068b7ba53ae69a5748b29fbf2bcb5df3a063ac52261"
solver-name = "gps-cdcl"
solver-version = 1
There are commands which help you to update/delete/etc packages, please find more info on official github repo of dep
(dependency management tool for Go).
Go 1.11 will be having a feature called go modules and you can simple add a dependency with a version.
Steps
go mod init .
go mod edit -require github.com/wilk/uuid@0.0.1
Here's more info on that topic: https://github.com/golang/go/wiki/Modules
That worked for me
GO111MODULE=on go get -u github.com/segmentio/aws-okta@v0.22.1
Nowadays you can just use go get
for it. You can fetch your dependency by the version tag, branch or even the commit.
go get github.com/someone/some_module@master
go get github.com/someone/some_module@v1.1.0
go get github.com/someone/some_module@commit_hash
more details here - How to point Go module dependency in go.mod to a latest commit in a repo?
Go get
will also install the binary, like it says in the documentation -
Get downloads the packages named by the import paths, along with their dependencies. It then installs the named packages, like 'go install'.
(from https://golang.org/cmd/go/)
有一个go edit -replace命令,可将特定的提交(甚至来自另一个派生的存储库)追加到当前版本的软件包之上。 这个选项最酷的地方是,你不需要事先知道具体的版本,只需知道提交哈希ID。
例如,我正在使用软件包“ github.com/onsi/ginkgo v1.8.0”的稳定版本。
现在,我想要-不修改go.mod中的必需软件包的这一行-在银杏版本的顶部,从我的叉子上添加一个补丁:
$ GO111MODULE="on" go mod edit -replace=github.com/onsi/ginkgo=github.com/manosnoam/ginkgo@d6423c2
首次构建或测试模块后,GO会尝试提取新版本,然后使用正确的伪版本生成“替换”行。 例如,在我的这种情况下,它将添加在go.mod的底部:
replace github.com/onsi/ginkgo => github.com/manosnoam/ginkgo v0.0.0-20190902135631-1995eead7451
</div>