Go: module modeでのgo.mod, go.sumファイルを用いた依存ライブラリ管理、及びcontributionの方法&手順
Summary
Go1.13がリリースされてGo Modulesのmodule modeがデフォルトになってからの、go mod
コマンドを駆使した依存ライブラリ管理、及び第三者のOSSプロジェクトへのcontributionの方法&手順について
- Module-awareモードに最適化した手順を把握・実践する
- ライブラリの追加手順
- ライブラリのバージョン更新手順(個別 or 全ライブラリ一括)
- ライブラリの削除手順
- Happy Contributing!!
- 参考リンク(参考というか、答えは下記リンク先に全て書いてあります)
前提条件
|
|
はじめに
Githubの"contributing ドキュメントについて
githubにプロジェクトを公開する際に、
- ルート
docs
.github
の3つの内いずれかのディレクトリに contributing*
というパターン名(大文字でも可)が付いたファイルを置いておくと、pull-request作成時に「ここにガイドラインがあるよ」と通知してくれるようになります。慣例としてこのファイルは CONTRIBUTING.md という名前で用意されている事が多いです。
このファイルには主に環境構築・テストの実行方法・pull-requestの送り方 などを記載しますが、Goプロジェクトでは「最初に $GOPATH
下にソースを持ってくる」事が前提になっている手順をよく見かけます(自作プロジェクトでもそうしていました)。
GoプロジェクトにおけるCONTRIBUTING.mdはどうあるべきか?
Go ModulesのModule-awareモードがデフォルト挙動になるGo1.13以降では、ソースをcloneしてくるディレクトリは何処でも良い=必ずしも$GOPATH
下にソースを持ってくる必要は無くなりますし、依存ライブラリの追加・削除・バージョン変更を行いたい時の流れも変わります。なので、 CONTRIBUTING.mdに書く内容もそれに合わせておくとcontributorに親切なガイドラインを提示できそうです。
引き続き$GOPATHベースでの開発を推奨するプロジェクトもあるかも知れませんし、内容や粒度はプロジェクトの運営方針や想定読者レベルによっても変わるとは思いますが、この記事ではModule-awareモードのレールに乗る前提で、CONTRIBUTING.mdに書くべき内容と、合わせてmodule modeでのGoプロジェクトにおけるライブラリ管理プラクティスを整理してみます。
1. module modeでのGo製プロジェクトの初期環境構築
想定手順
cd 任意のディレクトリ
git clone foo
cd foo
make
CONTRIBUTING.mdの冒頭は「自分のorganizationにforkしてgit clone」と書かれている事が多いですが、clone先のディレクトリは$GOPATH
に拘らず何処でも良くなりましたよという事が伝われば、それこそ git clone 任意のディレクトリ
と明記しておくだけでも良いと思います。
git clone後にmake
(或いは make setup
のような名前のターゲット)を叩けば依存ライブラリを取り込んでくれるようなmakeターゲットを用意しておくと初期の敷居を下げられそうです。
|
|
例えば go build
でもgo.modファイルの内容を元にした依存ライブラリの取り込みが動いてくれるので、go build
をmakeのデフォルトターゲットとして用意しておくのも良さそうです。
2. module modeで依存ライブラリを追加したい時の手順
想定手順
- コードを編集・import文を追加
go build
orgo run
orgo test
を実行する(これでgo.mod, go.sumも最新化される)
Go Modulesでは、import文を追加・保存してgo build
すればそのタイミングで必要なライブラリ取得&go.modの更新が実行されます。「コードを書いてbuildを動かすという流れの中で(lazyに)依存ライブラリ取得が走ってくれる」というGo Modulesの配慮が伺える設計になっています。
|
|
|
|
|
|
+incompatible
と出力されるのはどういう時か?
たまたま今回使わせてもらったppで +incompatible
というsuffixがgo.modに出力されましたが、これは 「ライブラリがGo Modulesに未対応で、且つMAJORバージョンが2以上」の場合に発生します(が、開発への悪影響がある訳ではありません)
3. module modeでライブラリのMINORバージョン又はPATCHバージョン(或いはその両方)を更新する手順
想定手順
go list -u -m PACKAGE
- PACKAGEで利用可能な最新バージョンが存在するか確認go list -u -m -versions PACKAGE | tr ' ' '\n'
← 利用可能な全バージョンを確認したい場合
go get PACKAGE@VERSION
- 指定バージョンを取得go get foo@latest
- 現在取得可能な最新バージョンgo get foo@v1.6.2
- 指定したバージョンgo get foo@e3702bed2
- 指定したcommit hash(のリビジョン)go get foo@'<v1.6.2'
- 指定した条件に合致する最新バージョンgo get foo@master
- masterブランチの内容
go build
orgo run
orgo test
を実行する(これでgo.mod, go.sumも最新化される)
go get
に代わるもう1つの手段として「go.mod のバージョン指定を直接編集する」事も可能なのですが、go.modに記述できるバージョン形式はPseudo-versions形式であり、go get foo@'<v1.6.2'
のようなモジュールクエリの形式で書く事は出来ません。
モジュールクエリ形式でバージョンを指定してgo get
を実行すると、条件にマッチして選択されたバージョンそのものがgo.modに反映されます。
|
|
4. 全てのライブラリを最新versionに更新する手順
想定手順
go list -u -m all
- 全依存ライブラリに更新可能バージョン(があればそれ)を付けて一覧表示・確認go get -u
go build
orgo run
orgo test
を実行する(これでgo.mod, go.sumも最新化される)
contributorがこれを行うケースはあまり無さそうではありますが、公式Wikiの Daily Workflow にも書かれている通りパッケージ指定なしでgo get -u
を実行すると全依存ライブラリの最新のminor versionが、go get -u=patch
を実行すると全依存ライブラリの最新のpatch versionが取得されます。
|
|
5. 使わなくなったライブラリを削除する手順を書く
想定手順
- コードを編集・import文を削除
go mod tidy
go build
orgo run
orgo test
を実行する(これでgo.mod, go.sumも最新化される)
go build
や go test
はまだ取得していないライブラリの取得は自動でやってくれますが、未使用ライブラリの削除は自動ではやってくれません。削除も含めてライブラリ依存関係を整理するのにgo mod tidy
コマンドを実行します。
公式Wikiでは、依存関係を整理しても互換性が担保されている事を(直接・間接いずれの依存に関わらず)テストしたいなら go test all
を実行すると良い、と紹介されていますが、全依存ライブラリのテストが実行されるのでもしやるなら開発PCのリソースに余裕がある時が良いです。
Thanks to
- Modules · golang/go Wiki
- The Go Blog - Using Go Modules / Go Modulesを使う(和訳) - Qiita
- Go Modulesの概要とGo1.12に含まれるModulesに関する変更 #golangjp #go112party - My External Storage
- 最近のGo Modulesプラクティス ~ ghqユーザーの場合も添えて | おそらくはそれさえも平凡な日々
- Setting guidelines for repository contributors - GitHub Help
- GitHubのIssue・Pull Requestのテンプレート機能を使おう - Qiita