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

Wil*_*ilk 86 package-managers package go

来自Node我曾经安装特定版本的供应商lib的环境到项目文件夹(node_modules),告诉从控制台npm安装该版本的lib,package.json甚至直接从控制台安装,如下所示:

$ npm install express@4.0.0
Run Code Online (Sandbox Code Playgroud)

然后我习惯在我的项目中导入该包的那个版本:

var express = require('express');
Run Code Online (Sandbox Code Playgroud)

现在,我想做同样的事情go.我怎样才能做到这一点?是否可以安装特定版本的软件包?如果是这样,使用集中式$GOPATH,如何导入一个版本而不是另一个版本?

我会做这样的事情:

$ go get github.com/wilk/uuid@0.0.1
$ go get github.com/wilk/uuid@0.0.2
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*oka 37

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

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

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

  • 我喜欢(和使用)gopkg,但版本[无法正常工作](https://github.com/niemeyer/gopkg/issues/9)与子包.只是需要注意的事情. (4认同)

小智 30

Go 1.11将有一个名为go modules的功能,你可以简单地添加一个版本的依赖项.

脚步

  1. go mod init .
  2. go mod edit -require github.com/wilk/uuid@0.0.1

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

  • 问题是使用“go get”,而不是“go mod”。 (9认同)
  • 如何使用 go get only?我需要将全局 go 二进制文件安装到特定版本 (5认同)
  • @JamesTan`去获取github.com / wilk / uuid @ 0.0.1`(带有`GO111MODULE = on`) (3认同)

Joã*_*aná 22

您可以使用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
Run Code Online (Sandbox Code Playgroud)

  • 您如何在导入本身中定义该版本? (2认同)

Pie*_*Pah 13

Glide是一个非常优雅的Go管理包,特别是如果你来自Node的npm或Rust的货物.

它在1.6中与Godep的新供应商功能密切相关,但更容易.您的依赖项和版本在projectdir/vendor目录中"锁定",而不依赖于GOPATH.

使用brew安装(OS X)

$ brew install glide
Run Code Online (Sandbox Code Playgroud)

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

$ glide init
Run Code Online (Sandbox Code Playgroud)

获取新包裹

$ glide get vcs/namespace/package
Run Code Online (Sandbox Code Playgroud)

更新并锁定包的版本.这会在项目目录中创建glide.lock文件以锁定版本.

$ glide up
Run Code Online (Sandbox Code Playgroud)

我尝试滑行并乐意将它用于我当前的项目.


hom*_*iak 12

现在你可以使用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
Run Code Online (Sandbox Code Playgroud)

更多细节在这里 -如何将 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/


mon*_*rus 12

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

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


vit*_*ams 11

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

dep ensure --add github.com/gorilla/websocket@1.2.0
Run Code Online (Sandbox Code Playgroud)

更新18-11-23:来自Go 1.11 mod是官方实验.请参阅@krish答案.

  • 请注意,[dep](https://github.com/golang/dep)是官方的_experiment_,但不是官方的解决方案.事实上,根据dep的[路线图](https://github.com/golang/dep/wiki/Roadmap)dep将不会转换为官方解决方案.相反,有一个关于正式版本化解决方案的新提议:[vgo](https://research.swtch.com/vgo) (8认同)
  • 问题是使用“go get”,而不是“dep”。 (3认同)
  • @Agrim谢谢.给我的新信息.vgo中的注意事项:"对于任何生产工作负载,如果尚未使用dep,请迁移到它.vgo将在Go树中合并,并在以后替换dep,假设提议已被接受." 所以现在我建议使用dep :) (2认同)

lar*_*moa 9

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

编辑:正如在这个答案中 提到的,gopkg.in是一个很好的选择,用于固定1.5之前的github-depdencies.


Ali*_*iuk 8

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

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

dep init
Run Code Online (Sandbox Code Playgroud)

执行后将生成两个文件:(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"
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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


fai*_*_kk 7

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/

  • 您关于go工具功能的陈述是正确的,但几乎没有人将版本合并到他们的git存储库名称中,并且许多人不将master/HEAD视为稳定的API.我目前有一个小服务,大约有八个依赖项; 只有一个版本号.亚马逊推动了对github.com/aws/aws-sdk-go的重大改变.`go get`的缓存意味着你不会注意到一段时间,除非你有一个构建服务器,每次都有助于你更新到最新版本.有第三方包管理员,但他们大多是粗鲁的. (42认同)
  • 为每个版本创建一个存储库?这太疯狂了 (24认同)
  • @faisal_kk你必须生活在一个梦想的世界里.在美妙的开源社区的真实世界中,每个人都在坚持自己的理念.没有分支发布的东西,我很高兴我们有标签. (16认同)
  • 这是根本错误的行为.源代码与已发布的包不同,您不能放在包作者身上以确保向后/向前兼容性.不是因为开发人员不称职,而是因为当数据包依赖性增加超过1时,这在理论上是不可能的.因此,Go get注定要像凉亭一样,其主要缺陷就是这个完全一样.语义版本控制也不够强大,二进制校验和实际上是唯一的方法. (7认同)
  • "没有版本号可以担心.太棒了!" 这必须是SO答案中最荒谬的陈述.版本控制是有原因的.Go缺乏一个包管理器,它具有内置配置或面向命令的机制,用于对每个依赖项进行版本控制并不意味着版本控制是一种麻烦.Downvoting! (4认同)
  • 作为补充评论:如果您需要特定版本的第三方软件包(除了`HEAD`),您可以将其克隆到您自己的git仓库并在代码中引用该克隆. (2认同)
  • "每个导入路径都是一个稳定的API.没有版本号需要担心.太棒了!" 这听起来很天真. (2认同)
  • 绝对误导git和github的力量.Downvoting. (2认同)