如何使用go get导入特定版本的软件包?


109

来自一个Node我曾经node_modules通过告诉npmpackage.json甚至直接从控制台安装那个版本的lib到我的项目文件夹()中安装供应商lib的特定版本的环境,例如:

$ 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

但是,如何在导入过程中有所作为?


4
go get如果您不希望这样做,那不是正确的工具。您可以在Google周围搜索特定问题的解决方案。
Wessie 2014年



对于Go 1.11或更高版本,请参阅Go模块:stackoverflow.com/questions/53682247/…–
Everton

Answers:


46

Go 1.11将具有一个称为go modules的功能,您只需添加一个版本的依赖项即可。跟着这些步骤:

go mod init .
go mod edit -require github.com/wilk/uuid@0.0.1` 
go get -v -t ./...   
go build
go install 

这是有关该主题的更多信息-https: //github.com/golang/go/wiki/Modules


4
用go如何做到这一点呢?我需要将全球通用二进制文件安装到特定版本
James Tan,

7
@JamesTan go get github.com/wilk/uuid@0.0.1(with GO111MODULE=on
Neil Conway

5
问题是使用go get,不是go mod
贝尔纳多·洛雷罗

40

真的没有人提到gopkg.in感到惊讶。

gopkg.in是一项提供包装程序(重定向)的服务,使您可以将版本表示为存储库URL,而无需实际创建存储库。例如,gopkg.in/yaml.v1VS gopkg.in/yaml.v2,尽管他们都住在https://github.com/go-yaml/yaml

如果作者未遵循正确的版本控制做法(通过在向后兼容时增加版本号),这不是完美的选择,但它确实适用于分支和标记。


5
我喜欢(并使用)gopkg,但是版本控制不能与子软件包一起正常工作。只是要注意的事情。
亚历克·托马斯

gopkg.in未在git旧版本中进行全面测试,因此无法在git <v1.9下正常工作
BMW

此外,它仅适用于主要版本。不能保证可复制的构建。
CAFxX

26

您可以使用 git checkout用来获取特定版本,并使用该版本来构建程序。

例:

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

解决方案将是git checkout并安装
ptman

@ aliaksei-maniuk为我们提供了更好的解决方案。使用https://github.com/golang/dep
若奥·巴拉那州

15

滑行对于Go来说是一个非常优雅的包裹管理,尤其是当您来自Node的npm或Rust的货物时。

它的行为与Godep 1.6中的新供应商功能十分接近,但更加容易。您的依赖项和版本被“锁定”在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

我尝试过滑行,并很高兴将其用于当前项目。


1
为了完整起见,这里是glide的网站:glide.sh 和这里的仓库
Michael Franzl

不幸的是,Glide不再处于“活动”状态,他们在github页面上建议迁移到官方软件包管理(现在转到模块)
damoiser

13

更新18-11-23:从Go 1.11 mod开始是官方实验。请参阅@krish答案。
更新19-01-01:从Go 1.12 mod仍是官方实验。从Go 1.13开始,模块模式将是所有开发的默认模式。
更新19-10-17:从Go 1.13 mod开始是官方程序包管理器。

https://blog.golang.org/using-go-modules

旧答案:

您可以通过官方设定的版本DEP

dep ensure --add github.com/gorilla/websocket@1.2.0

3
问题是使用go get,不是dep
贝尔纳多·洛雷罗


9

dep是Go语言依赖管理的正式实验。需要Go 1.8或更高版本才能进行编译。

要使用开始管理依赖项dep,请从项目的根目录运行以下命令:

dep init

执行后,将生成两个文件:(Gopkg.toml“清单”),Gopkg.lock并将必要的软件包下载到vendor目录中。

假设您有使用github.com/gorilla/websocket包的项目。dep将生成以下文件:

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"

# 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

有哪个帮你更新/删除/等的包,请找到更多信息的命令正式GitHub库dep(对于围棋依赖管理工具)。


7

如今,您可以使用go get它。您可以通过版本标记,分支甚至提交来获取依赖关系。

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

此处有更多详细信息- 如何将go.mod中的Go模块依赖项指向存储库中的最新提交?

Go get还将安装二进制文件,如文档中所述-

Get downloads the packages named by the import paths, along with their dependencies. It then installs the named packages, like 'go install'.

(来自https://golang.org/cmd/go/


4

go get 是Go软件包管理器。它以完全分散的方式工作,并且在没有中央软件包托管存储库的情况下仍然可以进行软件包发现。

除了查找和下载软件包外,软件包管理器的另一个重要作用是处理同一软件包的多个版本。Go采用了所有软件包管理器中最最小和最务实的方法。没有Go包的多个版本。

go get always总是从存储库中默认分支的HEAD提取。总是。这有两个重要含义:

  1. 作为软件包的作者,您必须坚持稳定的HEAD哲学。您的默认分支必须始终是软件包的稳定发行版本。您必须在功能分支中进行工作,并且仅在准备发布时才合并。

  2. 软件包的新主要版本必须具有自己的存储库。简而言之,包的每个主要版本(遵循语义版本控制)将拥有自己的存储库,因此也拥有自己的导入路径。

    例如github.com/jpoehls/gophermail-v1和github.com/jpoehls/gophermail-v2。

当有人在Go中构建应用程序时,上述理念确实没有缺点。每个导入路径都是一个稳定的API。没有担心的版本号。太棒了!

有关更多详细信息:http: //zduck.com/2014/go-and-package-versioning/


45
您关于go工具功能的陈述是正确的,但是几乎没有人将版本纳入其git存储库名称中,并且许多人并不将master / HEAD视为稳定的API。我目前有一个小服务,大约有八个依赖项。只有一个具有版本号。亚马逊对github.com/aws/aws-sdk-go进行了重大更改。go get的缓存意味着您将不会注意到一段时间,除非您拥有一个可每次都将您更新到最新版本的构建服务器。有第三方程序包管理器,但大多数都是粗鲁的。
dhasenan

19
@faisal_kk您必须生活在梦想中。在精彩的开源社区的真实世界中,每个人都秉承自己的哲学。没有分支发布的东西,我很高兴我们有标签。

28
为每个版本创建存储库?

8
这从根本上是错误的行为。源代码与已发布的软件包不同,并且您不能放置软件包作者来确保向后/向前兼容性。不是因为开发人员没有能力,而是因为从理论上讲,当程序包依赖项的数量增加到一个以上时,这是不可能的。因此,去得到注定要和凉亭走同样的路,凉亭的主要缺陷就是这一点。语义版本控制也不够强大,二进制校验和确实是唯一的方法。
Gudlaugur Egilsson

5
“无需担心版本号。太棒了!” 那一定是SO答案中最荒谬的说法。存在版本控制是有原因的。Go缺少一个具有内置配置或面向命令的机制来对依赖项进行版本控制的程序包管理器,但这并不意味着版本控制是令人讨厌的事情。不好意思!
哈林达卡'17

2

我发现可行的方法是git的子模块系统。使用它,您可以在给定版本的代码中子模块,并且显式记录并记录升级/降级-绝不会偶然。

我采取的文件夹结构是:

+ myproject
++ src
+++ myproject
+++ github.com
++++ submoduled_project of some kind.

我也使用这种方法。本质上,它遵循与go get相同的文件夹结构,但是允许您更好地控制要获取的版本。
Brad Peabody 2015年

答案未按要求的标准回答问题(使用go get
Baptiste Mille-Mathias


2

有一个go edit -replace命令,可将特定的提交(甚至来自另一个派生的存储库)追加到当前版本的软件包之上。这个选项最酷的地方是,您不需要事先知道确切的伪版本,只需知道commit hash 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的底部:

替换github.com/onsi/ginkgo => github.com/manosnoam/ginkgo v0.0.0-20190902135631-1995eead7451


2

关于模块查询的一些备忘单。

要检查所有现有版本:例如 go list -m -versions github.com/gorilla/mux

  1. 特定版本 @ v1.2.8
  2. 具体提交 @ c783230
  3. 具体提交 @master
  4. 版本前缀 @ v2
  5. 比较 @> = 2.1.5
  6. 最新 @ 最新

例如 go get github.com/gorilla/mux@v1.7.4

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.