技術検証 | go.mod でライブラリの依存関係を管理する
Go言語の勉強始めました
その備忘録になります!
go.mod とは
go.mod は、Goプロジェクト内のライブラリの依存関係を管理する仕組みを提供してくれる。他言語の例だと、PHPのComposer、SwiftのSwift Package Manager、Rubyのbundlerが同じ役割かな
どうやって管理するのか
「リポジトリ」「モジュール」「パッケージ」の3つの概念で管理しているとのこと。差分を見ながら挙動を確認してみる。
1. go modコマンドで go.mod を作成する
$ tree
GO-DEMO-1
├── README.md
$ go mod init github.com/jnlmyz/go-demo-1
$ tree
GO-DEMO-1
├── README.md
├── go.mod <- NEW
go.modはリポジトリのルートに置く必要がある
go.modは、モジュール名とGo言語のバージョンが記載されている。現時点では、ライブラリは使用していないため、シンプルな構成になっている
2. main.go を作成する
$ tree
GO-DEMO-1
├── README.md
├── go.mod
$ touch main.go
$ tree
GO-DEMO-1
├── README.md
├── go.mod
├── main.go <- NEW
挙動確認のため、Goの標準ライブラリである fmt と 外部ライブラリの proteus をインポートしてみた。proteusは、使用していないため、コンパイラーに怒られている
3. go mod tidy で必要なモジュールのダウンロードなどを行う
GO-DEMO-1 $ tree
GO-DEMO-1
├── README.md
├── go.mod
├── main.go
GO-DEMO-1 $ go mod tidy
go: finding module for package github.com/jonbodner/proteus
go: downloading github.com/jonbodner/proteus v0.14.0
go: found github.com/jonbodner/proteus in github.com/jonbodner/proteus v0.14.0
go: downloading github.com/jonbodner/multierr v0.0.0-20200223210354-ace728439446
go: downloading github.com/jonbodner/stackerr v1.0.0
go: downloading github.com/rickar/props v0.0.0-20170718221555-0b06aeb2f037
go: downloading github.com/go-sql-driver/mysql v1.5.0
go: downloading github.com/google/go-cmp v0.4.0
go: downloading github.com/lib/pq v1.8.0
GO-DEMO-1 $ tree
GO-DEMO-1
├── README.md
├── go.mod
├── main.go
├── go.sum <- NEW
go mod tidy の トレースを見ると proteus に必要な ライブラリもあわせてダウンロードしてくれる
go.modの内容は自動で上書きされ、requireにはダウンロードしたモジュール名 と バージョンが記載されている。
indirectがあるrequireがある場合、依存関係に以下の問題の可能性があるらしい
モジュールが古くてgo.modをもっていない
go.modにエラーがあり、依存ファイルが見つからない
go.sum は新規で作成され、モジュール、バージョン、チェックサム、go.modのチェックサムで構成されている。
調べたら、チェックサムがある理由がおもしろかった。
Googleは実は、モジュール管理用のプロキシサーバーと、モジュールの改竄防止用のチェックサムデータベースを保守して、開発者の開発体験を良くしてくれている(かっこいい)
go get や、go mod tidy でモジュールをダウンロードするとき、実はソースコードリポジトリではなく、プロキシサーバーからフェッチしている。プロキシサーバーにほしいモジュールがなくても、そのモジュールを探して返してくれる。プロキシサーバーに保存されるので、インターネット上にモジュールが削除されても、開発者は困らない仕組みになっている
チェックサムデータベースには、すべてのモジュールのすべてのバージョン情報、go.sumの内容や周辺情報が記憶されている。go get や go mod tidy する時に、チェックサムをチェックサムデータベースに投げることで、ダウンロード予定のモジュールが改竄されていないか確認することができる。以下のような流れみたい
go mod tidy でモジュールをダウンロードする
ローカルのGoツールで、チェックサムを計算する
計算したチェックサムをGoogleのチェックサムデータベースに投げて、そのモジュールの記憶されたチェックサムと比較する
マッチしない場合は、ダウンロードされない
まとめ
Goのライブラリ管理システムに、愛を感じた