繁体   English   中英

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

[英]How do I import a specific version of a package using go get?

来自Node环境,我曾经通过告诉npmpackage.json甚至直接从控制台安装该版本的 lib 来将供应商库的特定版本安装到项目文件夹 ( 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

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

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

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

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

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

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

Glide是一个非常优雅的 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

我尝试过 glide 并且很高兴将它用于我当前的项目。

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

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

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

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

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

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

编辑:如本答案中所述, gopkg.in是固定 github-depdencies 1.5 之前的不错选择。

现在你可以使用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 模块依赖指向 repo 中的最新提交?

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/

dep是 Go 语言依赖管理的官方实验。 它需要 Go 1.8 或更高版本才能编译。

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

dep init

执行后会生成两个文件: Gopkg.toml (“manifest”)、 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 (Go 的依赖管理工具)的官方 github repo上找到更多信息。

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

除了定位和下载包,包管理器的另一个重要作用是处理同一个包的多个版本。 Go 采用了任何包管理器中最简单、最实用的方法。 没有 Go 包的多个版本这样的东西。

go get总是从存储库中默认分支的 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 的 submodule system 使用它,您可以在给定版本的代码中进行子模块化,并且升级/降级是明确的和记录的 - 从不随意。

我采用的文件夹结构是:

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

那对我有用

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

有一个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 的底部:

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

它可能有用。

只需在cd your/package/src/输入到命令提示符中

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

您将相关包的特定修订版直接添加到源代码中,准备在 import 语句中使用。

目前这样做的方法是使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM