📔

【Go Dependencies コマンド】go install,go get,go mod download,go mod tidy

2022/12/04に公開

Goの開発をする際に、外部のモジュールやパッケージが必要になることが多いです。
Goにはモジュールやパッケージをダウンロード、インストールするためのコマンドが多く用意されていて、それぞれの振る舞いの違いや用途について理解するのに苦労しました。
本記事では、私が普段使うコマンドを列挙し、振る舞いや用途について言及していけたらと思います。

前提

  • Go Modulesに関するコマンドはGoのバージョンに大きく依存するため、バージョンには注意する必要があります
  • 本記事はGo 1.19を対象としています

go get <package-name>

  • go getはgo.modファイルに記載された依存関係を更新し、go.modファイルを更新します
  • この過程で、指定したパッケージとその依存関係を含むモジュールを$GOMODCACHE(モジュールキャッシュの格納先)にダウンロードします

go install <package-name>

  • go installは指定したパッケージをダウンロード後にビルドし、実行可能なファイルを$GOBINへ格納します
  • ビルド時の内容、つまり、ソースコード、コンパイラ、コンパイラオプションなどの変更が$GOCACHE(ビルドキャッシュの格納先)へ反映されます
  • パッケージにバージョン指定がある場合は、go.modファイルに記載されている対象のバージョンを無視し、指定したバージョンをインストールします
  • パッケージにバージョン指定がない場合は、go.modファイルに記載されている対象のバージョンし指定したバージョンをインストールします

go mod

go mod download <module-name>

  • go mod downloadは指定したモジュールのみを$GOMODCACHEにダウンロードします
  • 指定したモジュールに依存するモジュールはダウンロードされません
  • 引数にモジュールの指定がない場合は、go.modファイルに記載されたすべてのモジュールをダウンロードします

go mod tidy

  • go mod tidyはgo.modファイルを整理するコマンドです
  • go.modファイルが含まれるモジュールのソースコードとの一致を保証します
  • ソースコード内のimportで指定されているモジュールをgo.modファイルへ反映し、一方でimportで指定されていないモジュールはgo.modファイルから削除します
  • また、go.sumファイルに不足している情報を追加し、不要な情報を削除します
  • ちなみに、tidyは綺麗やさっぱりといった意味でcleanと同義のようです

各コマンドの用途まとめ

  • go getはソースコードからimportされるかどうかに関わらず、モジュールをダウンロードしgo.modファイルへモジュールの情報を反映する際に利用します。主に、go.modファイルの管理用途です
  • go mod downloadはソースコードからimportされるかどうかに関わらず、go.modファイルへ記載されたモジュールをダウンロードするため利用します
  • go mod tidyはimportされていないモジュールをgo.modファイルから削除する、importされているがgo.modファイルへ反映されていないモジュールはgo.modファイルへ追加したうえで、モジュールをダウンロードする際に利用します
  • go installは実行可能なファイルをインストールする際に利用します

go get, go mod download, go mod tidyはそれぞれ似ている点がありますが、開発の際はgo mod tidyが必要なモジュールの追加をしつつ、不要なモジュールの削除できるため便利に感じています。

よくあるエラー

go: cannot find module for path <package-name>

go installコマンドを実行する際に、次のようなエラーになることがあります。

go: cannot find module for path <package-name>

これは、 go.modファイルが存在しないか、go.modファイルがあっても、指定したモジュールがgo.modファイルに記述されていない場合に起こります。

go.modファイルが存在しない場合は、次のようにモジュールを初期化しgo.modファイルを作成します。

go mod init <module-name>

go.modファイルがあるが依存しているモジュールの情報が記述されていない場合は、次のようにモジュールの情報をgo.modファイルへ反映することで解決できます。

go get <package-name>

go: module <module-name> not a known dependency

go mod downloadコマンドを実行する際に、次のようなエラーになることがあります。

go: module <module-name> not a known dependency

これは指定したモジュールがgo.modファイルに反映されていない際に起こります。

次のコマンドを実行し、go.modファイルへ反映することで解決できます。

go get <module-name>

参照

Discussion