Go 1.10 リリース記念のパーティがあり、ちょうどインターン期間中で参加できそうだったので参加してきた。
tenntenn さんたちに誘われ、トークもした。20 分のトークは初めてだったのと、他のスピーカーが Go 界隈の有名人しかいなくてかなり緊張した。それでもトークで話した自作 gRPC クライアントが広く使われるようになったので参加して本当に良かったと思う。
Martin Fowler がいる ThoughtWorks のエンジニアが書いたアーキテクチャに関する本。タイトルに惹かれてなんとなく買った本だけど、多くの学びがあって面白かった。継続的な進化を続けるために、評価基準を定義し、それを評価するための適用度関数を用意するという試みはとても興味深かった。その他にも、モノリスからマイクロサービスまでの範囲でアプリケーション・モジュールの粒度が様々なアーキテクチャたちが紹介されていて、これも個人的には新鮮だった。当たり前だけど、世の中にはモノリスとマイクロサービス以外の選択も十分存在するということを思い出させてくれた。
Go 1.11 以前のバージョンでは、go get は go1 タグ or ブランチがない限り最新のソースコードを取得します。(go1 については budougumi0617 さんの記事 が詳しいです。)
ただ、ほとんどのリポジトリでは上記のようなタグ or ブランチが用意されていないため、あまり有用ではないと感じています。
同様の理由で go get の対象パッケージの依存パッケージ群のバージョンも管理できません。(ただし、リモートリポジトリに vendorディレクトリがある場合はそちらに配置されているパッケージが優先的に使われます。)
ツールの統一的なインストール方法がない
Go ツールのインストールは主に go get によって行われます。ツールセットをインストールしようとする場合、例えばあるプロジェクトでは README.md に記述された go getスニペットをコピペして実行したり、またあるプロジェクトでは Makefile に記述したりと様々な方法があり、ツールセットをインストールするための方法にばらつきがあります。
Go 1.11 では Russ Cox により提案された Go Modules が実験的に導入されました。
Go Modules では、関連のある複数のパッケージをまとめたものをモジュールとして定義し、それらをセマンティックバージョニングで管理し、セマンティックインポートバージョニングによって依存解決を行います。
ライブラリだけでなくツールもモジュール単位になりうるため、セマンティックバージョニングでモジュールを管理するだけでその恩恵を受けることができます。
詳細を解説すると、このポストの本題から外れてしまうので省略します。Go Modules に関する情報はすべて以下の Wiki にまとめられています。
ラッパーツールと銘打っている通り、dept 内部では go コマンドのサブコマンドである go get や、go build、go mod などのコマンドを実行しています。
例えば、新しいツールを依存に追加する dept get であれば、go get、go build などを叩いたりします。また、これらのコマンドは Go Modules を使うために常に modules-aware mode で実行されます。
このあたりの操作は多少の違いはあれど、上記で紹介した tools.go を用意する方法とほとんど同様です。
これらのコマンドから使われる Go Modules のマニフェストファイル、go.mod は、以下のような理由からプロジェクトで使用される go.mod とは別に管理しています。