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

huangapple go评论110阅读模式
英文:

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

问题

在Node环境中,我习惯通过告诉npm从package.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

但是,导入时我该如何区分它们呢?

英文:

coming from a Node environment I used to install a specific version of a vendor lib into the project folder (node_modules) by telling npm to install that version of that lib from the package.json or even directly from the console, like so:

$ npm install express@4.0.0

Then I used to import that version of that package in my project just with:

var express = require('express');

Now, I want to do the same thing with go. How can I do that?
Is it possible to install a specific version of a package? If so, using a centralized $GOPATH, how can I import one version instead of another?

I would do something like this:

$ go get github.com/wilk/uuid@0.0.1
$ go get github.com/wilk/uuid@0.0.2

But then, how can I make a difference during the import?

答案1

得分: 79

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 1.11 will have a feature called go modules and you can simply add a dependency with a version. Follow these steps:

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

Here's more info on that topic - https://github.com/golang/go/wiki/Modules
<!---->

答案2

得分: 45

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

gopkg.in是一个提供包装器(重定向)的服务,它允许您将版本表示为存储库URL,而无需实际创建存储库。例如,gopkg.in/yaml.v1gopkg.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

如果作者没有遵循适当的版本控制实践(通过增加版本号来打破向后兼容性),这并不完美,但它可以与分支和标签一起使用。

英文:

Really surprised nobody has mentioned gopkg.in.

gopkg.in is a service that provides a wrapper (redirect) that lets you express versions as repo urls, without actually creating repos. E.g. gopkg.in/yaml.v1 vs gopkg.in/yaml.v2, even though they both live at https://github.com/go-yaml/yaml

This isn't perfect if the author is not following proper versioning practices (by incrementing the version number when breaking backwards compatibility), but it does work with branches and tags.

答案3

得分: 39

模块查询的小提示。

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

英文:

A little cheat sheet on module queries.

To check all existing versions: e.g. go list -m -versions github.com/gorilla/mux

  1. Specific version @v1.2.8
  2. Specific commit @c783230
  3. Specific branch @master
  4. Version prefix @v2
  5. Comparison @>=2.1.5
  6. Latest @latest

E.g. go get github.com/gorilla/mux@v1.7.4

答案4

得分: 28

你可以使用git checkout命令获取特定版本,并使用该版本构建你的程序。

示例:

export GOPATH=~/ 
go get github.com/whateveruser/whateverrepo 
cd ~/src/github.com/whateveruser/whateverrepo 
git tag -l 
# 假设标签v0.0.2是正确的版本 
git checkout tags/v0.0.2 
go run whateverpackage/main.go
英文:

You can use git checkout to get an specific version and build your program using this version.

Example:

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

答案5

得分: 17

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

更多详细信息请参考这里 - https://stackoverflow.com/questions/53682247/how-to-point-go-module-dependency-in-go-mod-to-a-latest-commit-in-a-repo/53682399

go get还会像文档中所说的那样安装二进制文件。

Get会下载由导入路径指定的包及其依赖项。然后,它会像'go install'一样安装指定的包。

(来源:https://golang.org/cmd/go/)

英文:

Nowadays you can just use go get for it. You can fetch your dependency by the version tag, branch or even the commit.

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

more details here - https://stackoverflow.com/questions/53682247/how-to-point-go-module-dependency-in-go-mod-to-a-latest-commit-in-a-repo/53682399

Go get will also install the binary, like it says in the documentation -

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

(from https://golang.org/cmd/go/)

答案6

得分: 16

Glide 是一个非常优雅的 Go 语言包管理工具,特别适合那些来自 Node.js 的 npm 或 Rust 的 cargo 的开发者。

它的行为与 Godep 在 1.6 版本中引入的新的 vendor 特性非常相似,但使用起来更加简单。你的依赖包和版本会被“锁定”在项目目录下的 vendor 目录中,而不依赖于 GOPATH。

在 macOS 上使用 brew 安装:

$ brew install glide

初始化 glide.yaml 文件(类似于 package.json)。这还会从 GOPATH 中获取项目中已导入的包,并将它们复制到项目的 vendor/ 目录中。

$ glide init

获取新的包:

$ glide get vcs/namespace/package

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

$ glide up

我尝试过 Glide,并且在我的当前项目中一直很愉快地使用它。

英文:

Glide is a really elegant package management for Go especially if you come from Node's npm or Rust's cargo.

It behaves closely to Godep's new vendor feature in 1.6 but is way more easier. Your dependencies and versions are "locked" inside your projectdir/vendor directory without relying on GOPATH.

Install with brew (OS X)

$ brew install glide

Init the glide.yaml file (akin to package.json). This also grabs the existing imported packages in your project from GOPATH and copy then to the project's vendor/ directory.

$ glide init

Get new packages

$ glide get vcs/namespace/package

Update and lock the packages' versions. This creates glide.lock file in your project directory to lock the versions.

$ glide up

I tried glide and been happily using it for my current project.

答案7

得分: 14

更新 18-11-23:从 Go 1.11 开始,模块(module)是官方的实验性功能。请参考 @krish 的回答。
更新 19-01-01:从 Go 1.12 开始,模块仍然是官方的实验性功能。从 Go 1.13 开始,模块模式将成为所有开发的默认模式。
更新 19-10-17:从 Go 1.13 开始,模块成为官方的包管理器。

你可以通过官方的 dep 来设置版本:

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

Update 18-11-23: From Go 1.11 mod is official experiment. Please see @krish answer.
Update 19-01-01: From Go 1.12 mod is still official experiment.
Starting in Go 1.13, module mode will be the default for all development.
Update 19-10-17: From Go 1.13 mod is official package manager.

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

Old answer:

You can set version by offical dep

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

答案8

得分: 11

从Go 1.5开始,有一个名为"vendor实验"的功能,可以帮助你管理依赖项。从Go 1.6开始,这不再是一个实验性功能。在Go维基上还有一些其他选项。

编辑:如此答案中提到的,gopkg.in是一个在1.5之前固定github依赖项的好选择。

英文:

From Go 1.5 there's the "vendor experiment" that helps you manage dependencies. As of Go 1.6 this is no longer an experiment. Theres also some other options on the Go wiki..

Edit: as mentioned in this answer gopkg.in is a good option for pinning github-depdencies pre-1.5.

答案9

得分: 10

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

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

dep init

执行后,将生成两个文件:Gopkg.toml("manifest")和 Gopkg.lock,必要的包将被下载到 vendor 目录中。

假设你的项目使用了 github.com/gorilla/websocket 包,dep 将生成以下文件:

Gopkg.toml

# Gopkg.toml 示例
#
# 详细的 Gopkg.toml 文档请参考 https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
#
# 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 的依赖管理工具)。

英文:

dep is the official experiment for dependency management for Go language. It requires Go 1.8 or newer to compile.

To start managing dependencies using dep, run the following command from your project's root directory:

dep init

After execution two files will be generated: Gopkg.toml ("manifest"), Gopkg.lock and necessary packages will be downloaded into vendor directory.

Let's assume that you have the project which uses github.com/gorilla/websocket package. dep will generate following files:

Gopkg.toml

# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = [&quot;github.com/user/thing/cmd/thing&quot;]
# ignored = [&quot;github.com/user/project/pkgX&quot;, &quot;bitbucket.org/user/project/pkgA/pkgY&quot;]
#
# [[constraint]]
#   name = &quot;github.com/user/project&quot;
#   version = &quot;1.0.0&quot;
#
# [[constraint]]
#   name = &quot;github.com/user/project2&quot;
#   branch = &quot;dev&quot;
#   source = &quot;github.com/myfork/project2&quot;
#
# [[override]]
#  name = &quot;github.com/x/y&quot;
#  version = &quot;2.4.0&quot;


[[constraint]]
  name = &quot;github.com/gorilla/websocket&quot;
  version = &quot;1.2.0&quot;

Gopkg.lock

# This file is autogenerated, do not edit; changes may be undone by the next &#39;dep ensure&#39;.


[[projects]]
  name = &quot;github.com/gorilla/websocket&quot;
  packages = [&quot;.&quot;]
  revision = &quot;ea4d1f681babbce9545c9c5f3d5194a789c89f5b&quot;
  version = &quot;v1.2.0&quot;

[solve-meta]
  analyzer-name = &quot;dep&quot;
  analyzer-version = 1
  inputs-digest = &quot;941e8dbe52e16e8a7dff4068b7ba53ae69a5748b29fbf2bcb5df3a063ac52261&quot;
  solver-name = &quot;gps-cdcl&quot;
  solver-version = 1

There are commands which help you to update/delete/etc packages, please find more info on official github repo of dep (dependency management tool for Go).

答案10

得分: 4

go get 是Go语言的包管理器。它以完全去中心化的方式工作,即使没有中央包托管仓库,也能实现包的发现。

除了定位和下载包之外,包管理器的另一个重要作用是处理同一个包的多个版本。Go语言采取了最简洁和实用的方法。在Go语言中,不存在多个版本的包。

go get 总是从仓库的默认分支的最新版本拉取代码。这有两个重要的含义:

  1. 作为包的作者,你必须遵循稳定的最新版本原则。你的默认分支必须始终是稳定的、发布的版本。你必须在功能分支上进行开发,并在准备发布时才进行合并。

  2. 包的新主要版本必须有自己的仓库。简单来说,每个主要版本的包(遵循语义化版本规范)都应该有自己的仓库,因此有自己的导入路径。

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

作为使用Go语言构建应用程序的人,上述原则实际上没有什么不好的地方。每个导入路径都是一个稳定的API。不需要担心版本号。太棒了!

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

英文:

go get is the Go package manager. It works in a completely decentralized way and how package discovery still possible without a central package hosting repository.

Besides locating and downloading packages, the other big role of a package manager is handling multiple versions of the same package. Go takes the most minimal and pragmatic approach of any package manager. There is no such thing as multiple versions of a Go package.

go get always pulls from the HEAD of the default branch in the repository. Always. This has two important implications:

  1. As a package author, you must adhere to the stable HEAD philosophy. Your default branch must always be the stable, released version of your package. You must do work in feature branches and only merge when ready to release.

  2. New major versions of your package must have their own repository. Put simply, each major version of your package (following semantic versioning) would have its own repository and thus its own import path.

    e.g. github.com/jpoehls/gophermail-v1 and github.com/jpoehls/gophermail-v2.

As someone building an application in Go, the above philosophy really doesn't have a downside. Every import path is a stable API. There are no version numbers to worry about. Awesome!

For more details : http://zduck.com/2014/go-and-package-versioning/

答案11

得分: 3

我找到可行的方法是使用git的子模块系统。使用该系统,您可以将代码的特定版本作为子模块引入,并且升级/降级是明确且记录的,不会出现偶然情况。

我采用的文件夹结构如下:

  • myproject
    ++ src
    +++ myproject
    +++ github.com
    ++++ 某种类型的子模块项目。
英文:

The approach I've found workable is git's submodule system. Using that you can submodule in a given version of the code and upgrading/downgrading is explicit and recorded - never haphazard.

The folder structure I've taken with this is:

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

答案12

得分: 3

那对我来说有效

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

英文:

That worked for me

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

答案13

得分: 2

有一个go edit -replace命令可以将特定的提交(甚至来自另一个派生的存储库)附加到当前版本的软件包之上。

这个选项的酷之处在于,你不需要事先知道确切的伪版本,只需要知道提交哈希值

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

现在,我想在不修改go.mod文件中所需软件包的情况下,将我的分支中的一个补丁附加到ginkgo版本之上:

$ GO111MODULE="on" go mod edit -replace=github.com/onsi/ginkgo=github.com/manosnoam/ginkgo@d6423c2

在第一次构建或测试模块之后,GO将尝试拉取新版本,然后生成正确伪版本的"replace"行。例如,在我的情况下,它将在go.mod的底部添加以下内容:

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

英文:

There's a go edit -replace command to append a specific commit (even from another forked repository) on top of the current version of a package.
What's cool about this option, is that you don't need to know the exact pseudo version beforehand, just the commit hash id.

For example, I'm using the stable version of package "github.com/onsi/ginkgo v1.8.0".

Now I want - without modifying this line of required package in go.mod - to append a patch from my fork, on top of the ginkgo version:

$ GO111MODULE=&quot;on&quot;  go mod edit -replace=github.com/onsi/ginkgo=github.com/manosnoam/ginkgo@d6423c2

After the first time you build or test your module, GO will try to pull the new version, and then generate the "replace" line with the correct pseudo version. For example in my case, it will add on the bottom of go.mod:

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

答案14

得分: 0

这可能会有用。

只需在命令提示符中键入以下内容,同时确保你已经切换到 your/package/src/ 目录下:

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

这将获取特定版本的所需包,并将其直接放入你的源代码中,可以在导入语句中直接使用。

英文:

It might be useful.

Just type this into your command prompt while cd your/package/src/

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

You get specific revision of package in question right into your source code, ready to use in import statement.

答案15

得分: 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
英文:

The current way to do this is to use go install

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

> Starting in Go 1.17, installing executables with go get is deprecated. go install may be used instead.

go install github.com/someone/some_module

Specific version

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

Specific commit

go install github.com/someone/some_module@commit_hash

huangapple
  • 本文由 发表于 2014年7月21日 05:28:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/24855081.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定