go getを使用してパッケージの特定のバージョンをインポートするにはどうすればよいですか?


109

次のNodeように、特定のバージョンのベンダーlibをプロジェクトフォルダー(node_modules)にインストールするために使用した環境から、npmそのバージョンのlibをpackage.jsonコンソールから、またはコンソールから直接インストールするように指示します。

$ 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

しかし、どうすればインポート中に変更を加えることができますか?


4
go getこの動作が必要な場合は、適切なツールではありません。特定の問題の解決策を探し回ることができます。
ウェッシー2014



ゴー1.11以上の場合は、ゴーモジュールを参照してください。stackoverflow.com/questions/53682247/...
エバートン

回答:


46

Go 1.11にはgoモジュールと呼ばれる機能があり、バージョンに依存関係を追加するだけです。次の手順を実行します:

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


4
どうやって行くだけでそれを得るのですか?グローバルgoバイナリを特定のバージョンにインストールする必要があった
James Tan

7
@JamesTan go get github.com/wilk/uuid@0.0.1(with GO111MODULE=on
Neil Conway

5
問題はgo get、ではなくを使用していたgo mod
Bernardo Loureiro、

40

gopkg.inについて誰も言及していないことに本当に驚いています

gopkg.in実際にリポジトリを作成せずにバージョンをリポジトリURLとして表現できるラッパー(リダイレクト)を提供するサービスです。例えばgopkg.in/yaml.v1、VS gopkg.in/yaml.v2でも彼らは両方のライブにかかわらず、https://github.com/go-yaml/yaml

これは、作者が適切なバージョン管理の慣例に従っていない場合(下位互換性を損なうときにバージョン番号をインクリメントすることにより)は完璧ではありませんが、ブランチやタグでは機能します。


5
私はgopkgが好き(そして使っています)ですが、バージョン管理サブパッケージでは正しく機能しません。知っておくべきことだけです。
アレックトーマス

gopkg.inはgitの古いバージョンでは完全にテストされていないため、git <v1.9では正常に機能しません
BMW

また、メジャーバージョンでのみ機能します。再現可能なビルドを保証することはできません。
CAFxX 2018年

26

を使用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チェックアウトしてインストールすることです
ptman

@ aliaksei-maniukは、より良いソリューションを提供してくれます。使用https://github.com/golang/dep
ジョアン・パラナ

15

Glideは、特にNodeのnpmまたはRustの貨物から来ている場合、Goの本当にエレガントなパッケージ管理です。

それは1.6のGodepの新しいベンダー機能と密接に動作しますが、はるかに簡単です。依存関係とバージョンは、GOPATHに依存することなく、projectdir / vendorディレクトリ内で「ロック」されます。

brewでインストール(OS X)

$ brew install glide

glide.yamlファイルを初期化します(package.jsonと同様)。これにより、プロジェクト内の既存のインポート済みパッケージがGOPATHから取得され、プロジェクトのvendor /ディレクトリにコピーされます。

$ glide init

新しいパッケージを入手する

$ glide get vcs/namespace/package

パッケージのバージョンを更新してロックします。これにより、プロジェクトディレクトリにglide.lockファイルが作成され、バージョンがロックされます。

$ glide up

私はグライドしてみて、現在のプロジェクトでそれを楽しく使っています。


1
完全を期すために、glideのWebサイトはこちらです。glide.sh そして、ここにリポジトリがあります:github.com/Masterminds/glide
Michael

残念ながら、Glideはもはや「アクティブ」ではありません。githubページで、公式のパッケージ管理(現在はgoモジュール)への移行を提案しています
damoiser

13

アップデート18-11-23:Go 1.11からのmodは公式の実験です。@krish answerをご覧ください。
Update 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

3
問題はgo get、ではなくを使用していたdep
Bernardo Loureiro、


9

depGo言語の依存関係管理の公式実験です。コンパイルするにはGo 1.8以降が必要です。

を使用して依存関係の管理を開始depするには、プロジェクトのルートディレクトリから次のコマンドを実行します。

dep init

実行後、2つのファイルGopkg.toml(「マニフェスト」)が生成され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

あなたの更新/削除/などのパッケージに、詳細見つけてくださいヘルプコマンドがあり、公式のGitHubリポジトリdep(ゴーの依存関係管理ツールが)。


7

最近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モジュールの依存関係をリポジトリの最新のコミットにポイントするにはどうすればよいですか?

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/から)


4

go get はGoパッケージマネージャーです。完全に分散された方法で動作し、中央のパッケージホスティングリポジトリがなくても、パッケージの検出がいかに可能かを示します。

パッケージの検索とダウンロードの他に、パッケージマネージャーのもう1つの大きな役割は、同じパッケージの複数のバージョンを処理することです。Goは、パッケージマネージャーの中で最も最小限で実用的なアプローチを採用しています。Goパッケージの複数のバージョンなどはありません。

go getは常にリポジトリのデフォルトブランチのHEADからプルします。常に。これには2つの重要な意味があります。

  1. パッケージ作成者は、安定したHEAD哲学を遵守する必要があります。デフォルトのブランチは、常にパッケージの安定したリリースバージョンである必要があります。機能ブランチで作業し、リリースの準備ができたときにのみマージする必要があります。

  2. パッケージの新しいメジャーバージョンには、独自のリポジトリが必要です。簡単に言えば、パッケージの各メジャーバージョン(セマンティックバージョニングに続く)は独自のリポジトリを持ち、したがって独自のインポートパスを持ちます。

    例:github.com/jpoehls/gophermail-v1およびgithub.com/jpoehls/gophermail-v2。

誰かがGoでアプリケーションを構築する場合、上記の哲学には実際にマイナス面はありません。すべてのインポートパスは安定したAPIです。心配するバージョン番号はありません。驚くばかり!

詳細:http : //zduck.com/2014/go-and-package-versioning/


45
goツールの機能に関する記述は正しいですが、gitリポジトリ名にバージョンを組み込む人はほとんどいないため、多くの人はマスター/ヘッドを安定したAPIとして扱いません。現在、約8つの依存関係を持つ小さなサービスがあります。バージョン番号を持つのは1つだけです。Amazonはgithub.com/aws/aws-sdk-goに重大な変更をプッシュしました。go getのキャッシュは、毎回最新バージョンに更新するのに役立つビルドサーバーがない限り、しばらくの間気付かないことを意味します。サードパーティのパッケージマネージャーがありますが、それらはほとんどがまともです。
dhasenan 2015年

19
@faisal_kkあなたは夢の世界に住んでいる必要があります。素晴らしいオープンソースコミュニティのREALの世界では、誰もが自分の哲学を守っています。リリースを分岐させるようなものはありません。タグがあればうれしいです。

28
すべてのバージョンのリポジトリを作成しますか?クレイジーです
deFreitas

8
これは根本的に間違った動作です。ソースコードはリリースされたパッケージと同じではありません。また、後方/前方互換性を確保するためにパッケージ作成者を置くことはできません。開発者が無能であるからではなく、パッケージの依存関係の数が1を超えた場合、これは理論的に不可能だからです。したがって、ゴーゲットはバウアーと同じように行く運命にありますが、その主な欠陥はまったく同じものでした。セマンティックバージョニングも十分に強力ではありません。バイナリチェックサムが本当に唯一の方法です。
Gudlaugur Egilsson 2016

5
「心配するバージョン番号はありません。素晴らしい!」これは、これまでのSOの回答の中で最も不合理な発言でなければなりません。バージョニングは理由があります。依存関係をバージョン管理するための組み込みの構成またはコマンド指向のメカニズムを備えたGoのパッケージマネージャーの欠如は、バージョン管理が厄介であることを意味するものではありません。反対投票!
Harindaka

2

私が有効だと思ったアプローチは、gitのサブモジュールシステムです。これを使用すると、コードの特定のバージョンでサブモジュールを作成でき、アップグレード/ダウングレードは明示的かつ記録されます-偶然ではありません。

私がこれで取ったフォルダ構造は次のとおりです。

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

私もこのアプローチを使用しています。基本的に、go getと同じフォルダー構造に従いますが、取得するバージョンをより適切に制御できます。
Brad Peabody、

回答は、(を使用してgo get)質問基準に回答していません
バプティストミルマシアス


2

パッケージの現在のバージョンの上に特定のコミットを(別のフォークされたリポジトリからでも)追加するgo edit -replaceコマンドがあります。このオプションの優れている点は、正確な疑似バージョンを事前に知る必要がなく、コミットハッシュIDだけを知っていることです。

たとえば、パッケージ「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は新しいバージョンをプルしようとし、次に、「置換」行を正しい疑似バージョンで生成します。たとえば、私の場合、go.modの下部に追加されます。

github.com/onsi/ginkgo => github.com/manosnoam/ginkgo v0.0.0-20190902135631-1995eead7451を置き換えます


2

モジュールクエリに関するチートシート。

既存のすべてのバージョンを確認するには: go list -m -versions github.com/gorilla/mux

  1. 特定のバージョン @ v1.2.8
  2. 特定のコミット @ c783230
  3. 特定のコミット @master
  4. バージョンプレフィックス @ v2
  5. 比較 @> = 2.1.5
  6. 最新の @ 最新

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.