如何使用 goget 导入特定版本的包?

来自于一个 Node环境,我曾经通过告诉 npmpackage.json或者直接从控制台安装一个特定版本的供应商库到项目文件夹(node_modules) ,就像这样:

$ 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

但是,我怎样才能在导入过程中有所作为呢?

224663 次浏览

Go get 是 Go 包管理器。它以一种完全分散的方式工作,如何在没有中央包托管存储库的情况下仍然可以发现包。

除了定位和下载软件包之外,软件包管理器的另一个重要角色是处理同一软件包的多个版本。Go 采用了所有包管理器中最简单、最务实的方法。不存在 Go 包的多个版本。

总是从存储库中默认分支的 HEAD 中获取 ,总是,这有两个重要的含义:

  1. 作为一个包作者,您必须坚持稳定的 HEAD 哲学。您的默认分支必须始终是包的稳定发布版本。您必须在特性分支中进行工作,并且只有在准备发布时才进行合并。

  2. 软件包的新主要版本必须有自己的存储库。简单地说,包的每个主要版本(遵循语义版本控制)都有自己的存储库,因此也有自己的导入路径。

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

作为一个在 Go 中构建应用程序的人,上述哲学真的没有缺点。每个导入路径都是一个稳定的 API。没有版本号需要担心。太棒了!

详情请浏览: http://zduck.com/2014/go-and-package-versioning/

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

我使用的文件夹结构是:

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

在 Go 1.5中,有一个 “供应商实验”可以帮助您管理依赖关系。从 Go 1.6开始,这就不再是一个实验了。还有 Go wiki 上的其他选项。

编辑: 正如在 这个答案 Gopkg.in中提到的,在1.5之前固定 github 依赖性是一个很好的选择。

您可以使用 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

没人提到 Gopkg.in真是奇怪。

gopkg.in是一个提供包装(重定向)的服务,它允许您将版本表示为 repo URL,而不需要实际创建 repo。例如 gopkg.in/yaml.v1gopkg.in/yaml.v2,即使它们都生活在 https://github.com/go-yaml/yaml

如果作者没有遵循正确的版本控制实践(在破坏向后兼容性时增加版本号) ,这并不完美,但它确实可以用于分支和标记。

Glide 对于 Go 来说是一个非常优雅的包管理,特别是如果您来自 Node 的 npm 或 Rust 的货物。

它的表现与 Godep 在1.6中的新供应商特性非常接近,但要简单得多。您的依赖项和版本被“锁定”在 projectdir/卖主目录中,而不依赖于 GOPATH。

使用 brew (OSX)安装

$ brew install glide

初始化 glide.yaml 文件(类似于 package.json)。这还会从 GOPATH 获取项目中现有的导入包,然后复制到项目的供应商/目录。

$ glide init

拿新包裹

$ glide get vcs/namespace/package

更新并锁定软件包的版本。这将在项目目录中创建 glide.lock 文件来锁定版本。

$ glide up

我尝试了 Glide,并很高兴地将它用于我目前的项目。

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"

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

有一些命令可以帮助您更新/删除/等软件包,请查找更多关于 dep官方的 Github 回购协议(Go 的依赖管理工具)的信息。

更新18-11-23 : From Go 1.11 mod 是官方实验,请看@krish 的回复。
更新19-01-01 : From Go 1.12 mod 仍然是官方的实验。 从 Go 1.13开始,模块模式将是所有开发的默认模式。
更新19-10-17 : From Go 1.13 mod 是官方软件包管理器。

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

老答案:

您可以通过官方 Dep设置版本

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

Go 1.11将有一个称为 Go 模块的特性,您可以简单地添加一个版本的依赖项。遵循以下步骤:

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

这招对我管用

GO111MODULE=on go get -u github.com/segmentio/aws-okta@v0.22.1

现在你只需要使用 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/)

有一个 去编辑-替换命令在当前版本的包之上追加一个特定的提交(甚至来自另一个分支存储库)。 这个选项的酷之处在于,您不需要事先知道确切的 伪版本,只需要知道 提交哈希 ID即可。

例如,我使用的是稳定版本的软件包“ github.com/onsi/ginkgo v1.8.0”。

现在,我希望——不需要修改 go.mod 中这一行必需的软件包——在我的 fork 上添加一个补丁,添加到银杏版本的顶部:

$ 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-1995 eead7451

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

检查所有现有版本: 例如 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

可能会有用。

cd your/package/src/时,只需在命令提示符中键入此命令

go get github.com/go-gl/mathgl@v1.0.0

您可以在源代码中获得有问题的包的特定修订,以便在导入语句中使用。

目前的方法是使用 go install

Https://golang.org/doc/go-get-install-deprecation

从 Go 1.17开始,不推荐使用 Go get 安装可执行文件。可以使用 Go install。

go install github.com/someone/some_module

具体版本

go install github.com/someone/some_module@v1.1.0

具体提交

go install github.com/someone/some_module@commit_hash