ChatGPT解决这个技术问题 Extra ChatGPT

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

来自 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

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

你不知道,如果你想要这种行为,go get 不是正确的工具。您可以在 Google 周围搜索特定问题的解决方案。
阅读this
stackoverflow.com/questions/30188499/… 这看起来也很有帮助
对于 Go 1.11 或更高版本,请参阅 Go 模块:stackoverflow.com/questions/53682247/…

F
Flimzy

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


go get only 如何做到这一点?我需要将全局 go 二进制文件安装到特定版本
@JamesTan go get github.com/wilk/uuid@0.0.1(与 GO111MODULE=on
问题是使用 go get,而不是 go mod
N
Nik

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

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

gopkg.in/yaml.v1 重定向到 https://github.com/go-yaml/yaml/tree/v1

gopkg.in/yaml.v2 重定向到 https://github.com/go-yaml/yaml/tree/v2

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


我喜欢(并使用)gopkg,但版本控制 does not work correctly 带有子包。只是需要注意的事情。
gopkg.in 未在 git 旧版本中进行全面测试,因此在 git < v1.9 中无法正常工作
此外,它仅适用于主要版本。无法保证可重现的构建。
J
João Paraná

您可以使用 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 并安装
@aliaksei-maniuk 为我们提供了更好的解决方案。使用https://github.com/golang/dep
您将如何在导入本身中定义该版本?
m
monkrus

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

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

具体版本@v1.2.8具体提交@c783230具体分支@master版本前缀@v2比较@>=2.1.5最新@latest

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


我认为#3应该阅读“特定分支@master”
感谢@HairOfTheDog 的更正。
P
Pandemonium

Glide 是一个非常优雅的 Go 包管理工具,特别是如果你来自 Node 的 npm 或 Rust 的 cargo。

它的行为与 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 并愉快地将它用于我当前的项目。


为了完整起见,这里是 glide 的网站:glide.sh 这里是 repo:github.com/Masterminds/glide
不幸的是,Glide 不再“活跃”,在 github 页面上他们建议迁移到官方包管理(现在转到模块)
B
Baptiste Mille-Mathias

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

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

老答案:

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

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

问题是使用 go get,而不是 dep
h
homiak

现在你可以只使用 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

更多详情 - How to point Go module dependency in go.mod to a latest commit in a 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/


C
Community

从 Go 1.5 开始,"vendor experiment" 可帮助您管理依赖项。从 Go 1.6 开始,这不再是一个实验。还有some other options on the Go wiki.

编辑:如 this answer 中所述,gopkg.in 是 1.5 之前固定 github-depdencies 的好选择。


A
Aliaksei Maniuk

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

有一些命令可以帮助您更新/删除/等包,请在 depofficial github repo(Go 的依赖管理工具)上找到更多信息。


Dep 是为 Go 实现包管理器的官方实验。自 2020 年起,Dep 已弃用并存档,转而支持 Go 模块,自 Go 1.11 以来已获得官方支持。有关详细信息,请参阅golang.org/ref/mod
C
Community

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

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

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

作为包作者,你必须坚持稳定的 HEAD 理念。您的默认分支必须始终是您的软件包的稳定发布版本。您必须在功能分支中工作,并且只有在准备好发布时才合并。软件包的新主要版本必须有自己的存储库。简而言之,包的每个主要版本(遵循语义版本控制)都有自己的存储库,因此也有自己的导入路径。例如 github.com/jpoehls/gophermail-v1 和 github.com/jpoehls/gophermail-v2。

作为使用 Go 构建应用程序的人,上述理念确实没有缺点。每个导入路径都是一个稳定的 API。无需担心版本号。惊人的!

更多详情:http://zduck.com/2014/go-and-package-versioning/


您关于 go 工具功能的陈述是正确的,但几乎没有人将版本合并到他们的 git 存储库名称中,而且许多人不将 master/HEAD 视为稳定的 API。我目前有一个小服务,大约有八个依赖项;只有一个有版本号。亚马逊向 github.com/aws/aws-sdk-go 推送了一项重大更改。 go get 的缓存意味着您有一段时间不会注意到,除非您有一个构建服务器,每次都会帮助您更新到最新版本。有第三方包管理器,但它们大多是杂乱无章的。
@faisal_kk 你一定生活在一个梦想的世界里。在精彩的开源社区的真实世界中,每个人都在坚持自己的理念。没有分支发布这样的事情,我很高兴我们有标签。
为每个版本创建一个存储库?太疯狂了
这是根本错误的行为。源代码与已发布的包不同,您不能将包作者放在包的作者身上以确保向后/向前兼容性。不是因为开发人员不称职,而是因为当包依赖项的数量超过一个时,这在理论上是不可能的。因此,Go get 注定要走上与 bower 相同的道路,后者的主要缺陷与此完全相同。语义版本控制也不够强大,二进制校验和确实是唯一的方法。
“无需担心版本号。太棒了!”这必须是SO答案中最荒谬的陈述。版本控制是有原因的。 Go 缺少一个包管理器,它有一个内置的配置或面向命令的机制来对依赖项进行版本控制,这并不意味着版本控制是一件麻烦事。投反对票!
b
buckaroo1177125

我发现可行的方法是git's submodule system。使用它,您可以在给定版本的代码中进行子模块,并且升级/降级是明确和记录的——绝不是随意的。

我采用的文件夹结构是:

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

我也使用这种方法。本质上它遵循与 go get 相同的文件夹结构,但允许您更好地控制您正在获取的版本。
答案未按照所要求的标准回答问题(使用 go get
V
Vadym Tyemirov

这对我有用

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


N
Noam Manos

有一个 go edit -replace 命令可将特定提交(甚至来自另一个分叉存储库)附加到软件包的当前版本之上。此选项的优点在于您无需事先知道确切的 pseudo version,只需 提交哈希 id

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

现在我想要 - 在 go.mod 中不修改这行所需的包 - 从我的 fork 中附加一个补丁,在 ginkgo 版本之上:

$ 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


b
blacha

它可能有用。

只需在 cd your/package/src/ 时将其输入您的命令提示符

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

您可以将相关包的特定修订版直接放入源代码中,以便在导入语句中使用。


S
SomeGuyOnAComputer

当前执行此操作的方法是使用 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