Go Modules は、依存関係管理ツールです。
この記事では、Go Modules の概要と使い方を記載します。
概要
Go Modules (旧名 vgo)は Go v1.12 から正式リリースされている依存関係管理ツールです。
ここでは、その概要を記載します。
Minimal Version Selection
Go Modulesは Semantic Versioning に基づいてモジュールのバージョン管理を行ないます。
GOPATH mode と module-aware mode
Go Modulesは GOPATH mode と module-aware mode という2つのモードがあり、環境変数 GO111MODULE
で切り替えることができます。
GO111MODULE=off
: GOPATH modeGO111MODULE=on
: module-aware modeGO111MODULE=auto
:$GOPATH/src
配下では GOPATH mode 、それ以外では module-aware mode で動作します
GOPATH mode と module-aware mode のそれぞれの特徴は以下の通りです。
GOPATH mode
go get
コマンドで取得したモジュールは $GOPATH/src
に保存されます。
標準 pkg 以外のモジュールはすべてここで管理されることになります。
go get
コマンドで取得するモジュールは基本的に Github などのリポジトリで管理されており、$GOPATH/src
配下に git clone
した形で保存されます。
モジュールのバージョンは、 git clone/pull
したタイミングのバージョン( go1
タグ・ブランチもしくは master
)や、 git checkout
で変更した branches のバージョンになります。
モジュールのバージョンコントロールが面倒な点が、 GOPATH mode の難点です。
module-aware mode
go get
コマンドで取得したモジュールは $GOPATH/pkg/mod
に保存され、さらに、go.mod
ファイルに記録され依存関係管理されます。
標準 pkg 以外のモジュールはすべてここで管理されることになります。
go get
コマンドで取得するモジュールは基本的に Github などのリポジトリで管理されており、$GOPATH/pkg/mod
配下に Semantic Versioning された単位 で保存されます。
Semantic Versioning された単位は、 go.mod
に記載されたモジュールのバージョンに対応します。
go.sum
ファイルは依存モジュールのチェックサムの管理に利用されます。
従来通り $GOPATH
配下でプロジェクトを作成・開発し且つ module-aware mode を利用したい場合には GO111MODULE=on
とする必要があります。
また、 $GOPATH
配下以外でプロジェクトを作成する場合であっても module-aware mode を利用すれば $GOPATH/pkg/mod
配下で依存モジュールが管理されるので、好きな場所で Go プロジェクトを作成することができます。
$GOPATH
$GOPATH
配下の構造がわからないとイメージつかないかもしれませんので、記載しておきます。
$GOPATH
├─bin/ # Goツール類の実行ファイルが格納されるディレクトリ
│
├─pkg/ # ビルドしたパッケージオブジェクトが格納されるディレクトリ
│ ├─darwin_amd64/
│ │ ├─github.com/
│ │ │ └─GitHubアカウント名
│ │ │ ├─`*.a`ファイル[^1]
│ │ │ └─GitHubレポジトリ名/`*.a`ファイル[^2]
│ │ └─pkg.in/
│ │ ├─パッケージ名/
│ │ └─`*.a`ファイル
│ │
│ └─mod/ # Go Modules で取得したモジュール類が格納されるディレクトリ
│ ├─cache/ # download したモジュール類のメタ情報や実態のzipなどのキャッシュ
│ ├─github.com/ # Github リポジトリから取得したモジュール
│ │ └─GitHubアカウント名
│ │ └─GitHubレポジトリ名@バージョン/ # この「@バージョン」部分でバージョンを識別して管理している
│ └─gopkg.in/ # gopkg.in リポジトリから取得したモジュール
│
└─src/ # GOPATH mode: パッケージごとのソースコードを配置するディレクトリ
├─gopkg.in/
│ └─パッケージ名/
│ └─LICENSEとか`*.go`とかREADMEとか
└─github.com/
├─GitHubアカウント名
│ └─GitHubレポジトリ名/
│ └─LICENSEとか`*.go`とかREADMEとか
│
└─<あなたのGitHubユーザ名> # Go Modules OFF の場合
└─GitHubレポジトリ名/ # プロジェクトディレクトリ(複数)
├─go.mod
├─go.sum
├─main.go
└─その他、あなたが開発中のソフトウェアのコード
使い方
ここでは Go 1.16 以降前提に記載します。
go.mod の作成
go mod init
を使用して、作成するプロジェクトのリポジトリを指定します。
Go で作成するプロジェクトは Github などのリポジトリ管理されることが前提で考えられているためです。
$ go mod init github.com/pepese/golang-gin-sample
なお、 GOPATH 配下で go mod init
する場合、自明なのでリポジトリを省略することができます。
$ mkdir -p $GOPATH/src/github.com/<あなたのGithubアカウント名>
$ cd $GOPATH/src/github.com/<あなたのGithubアカウント名>
$ mkdir <golangプロジェクト> # プロジェクトディレクトリの作成
$ cd <golangプロジェクト>
$ export GO111MODULE=on
$ go mod init # `GO111MODULE=on go mod init` のように一行でも
go: creating new go.mod: module github.com/<あなたのGithubアカウント名>/<golangプロジェクト>
go mod init
が完了すると go.mod
が作成されています。
go.mod/go.sum の更新
Go 1.15 までは go build
や go test
などのコマンドで go.mod/go.sum
の内容が勝手に更新されていましたが, 1.16 からは自動では更新されなくなっています。
そのため、何らかの拡張機能を有したコードエディタ上の import で新しいモジュールを追加しても go.mod/go.sum
に追加されない場合があります。
さらに利用のないモジュールが残ったりした場合なども含めて、 go.mod/go.sum
を最適化するために以下のコマンドを利用しましょう。
$ go mod tidy
なお、上記ではモジュールのバージョンは最新化されません。
go get
を使って go.mod/go.sum
に記述されているモジュールのバージョンを変更しましょう。
$ go get golang.org/x/tools/gopls@v0.6.5
バージョン番号サフィックスが有効になっており、 @latest
なども利用できます。
go install/get
go install/get の違いは以下の通りです。
- バイナリのビルドとインストールのための
go install
- go.mod 編集のための
go get
ツールの導入は go install
、 go.mod
の編集は go get
というふうに使い分けましょう。
go.mod
go.mod では以下のディレクティブが使用されます。
ディレクティブ | 例 | 説明 |
---|---|---|
module | module github.com/pepese/golang-gin-sample | モジュール名、 go mod init で指定したリポジトリ |
go | go 1.17 | 有効な Go のバージョン |
require | require other/thing v1.0.2 | インポート・モジュール |
exclude | exclude old/thing v1.2.3 | 除外モジュール |
replace | replace bad/thing v1.4.5 => good/thing v1.4.5 | モジュールの置換 |
retract | retract v1.0.5 | 撤回バージョン |
go ディレクティブの更新
Go のバージョンを変更したい場合は以下のコマンドを実行してください。
$ go mod tidy -go=1.17