簡體   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