モジュールの公開(Go Modules)
Goではコードを配布する仕組みとしてモジュール(Go Modules)があります。
前ページの『モジュールの作成』で作成したモジュールを公開する方法を説明します。
このページはGo1.13以降の利用を前提とします。
はじめに
モジュールは徐々に成長します。 ここでは、モジュールにバージョンをつけていない状態から始め、 セマンティックバージョニングに従いバージョンアップを重ねていく過程を時系列に沿って説明します。
説明で利用するモジュールexample.com/calc
は架空のモジュールです。
実際にモジュールを公開するには、モジュールパスを実在するリポジトリにしてください。
GitHubの場合はgithub.com/<user>/<repo>
のようにします。
擬似バージョン
手始めにバージョンがついていない状態でモジュールを公開します。
新たにgitリポジトリを作成し、コミットします。 外部に公開する場合はLICENSEファイルを含めます。
# パスは自身の環境に読み替えてください
cd $HOME/calc
git init
git add LICENSE go.mod go.sum calc.go calc_test.go
git commit -m "Initial commit"
git remote add origin xxx
git push origin main
これでモジュールを公開できました。 他の言語では中央集権的なサーバ(たとえばnpm)にモジュールをアップロードすることがありますが、 Goのモジュールではその必要はありません。
続いて、公開したモジュールを利用してみましょう。
# パスは自身の環境に読み替えてください
cd $HOME/myapp
go mod init example.com/myapp
main.go
package main
import (
"fmt"
"example.com/calc"
)
func main() {
fmt.Println(calc.Max(1, 2))
}
依存関係を追加します。
現在はバージョンがついていないため、自動的に擬似バージョンがつけられます。
擬似バージョンはタイムスタンプやコミットハッシュを組み合わせ、v0.0.0-20170915032832-14c0d48ead0c
のように表現します。
go mod tidy
go: finding module for package example.com/calc
go: downloading example.com/calc v0.0.0-20170915032832-14c0d48ead0c
go: found example.com/calc in example.com/calc v0.0.0-20170915032832-14c0d48ead0c
go.mod
に依存関係が追加されたことを確認します。
cat go.mod
module example.com/myapp
go 1.15
require example.com/calc v0.0.0-20170915032832-14c0d48ead0c
calc
パッケージを使ったプログラムを実行します。
go run .
2
これでバージョンのついていないモジュールの公開と利用ができました。
v0
続いて、モジュールが形になってきたら、バージョンをつけて公開します。 最初は不安定なメジャーバージョンを意味するv0で公開します。
gitのタグを用いて、バージョンをつけます。
# パスは自身の環境に読み替えてください
cd $HOME/calc
go mod tidy
go test ./...
git add go.mod go.sum *.go
git commit -m "Release v0.1.0"
git tag v0.1.0
git push origin v0.1.0
モジュールを利用するプロジェクトは依存関係をv0.1.0に更新します。
# パスは自身の環境に読み替えてください
cd $HOME/myapp
go get example.com/calc
go: example.com/calc upgrade => v0.1.0
go: downloading example.com/calc v0.1.0
これでv0.1.0の公開と利用ができました。
今後の公開も次の通りバージョンをつけます。
- 不具合修正をする場合は、パッチバージョンを加算(v0.1.1)
- 互換性のない更新・機能追加・依存関係の更新をする場合は、マイナーバージョンを加算(v0.2.0)
v1
続いて、モジュールが安定していることを確認したら、メジャーバージョンv1をリリースできます。 メジャーバージョンv1内では互換性のない更新はできません。
# パスは自身の環境に読み替えてください
cd $HOME/calc
go mod tidy
go test ./...
git add go.mod go.sum *.go
git commit -m "Release v1.0.0"
git tag v1.0.0
git push origin v1.0.0
モジュールを利用するプロジェクトは依存関係をv1に更新します。
# パスは自身の環境に読み替えてください
cd $HOME/myapp
go get example.com/calc
go: example.com/calc upgrade => v1.0.0
go: downloading example.com/calc v1.0.0
これでv1.0.0の公開と利用ができました。
今後の公開も次の通りバージョンをつけます。
- 不具合修正をする場合は、パッチバージョンを加算(v1.0.1)
- 機能追加・依存関係の更新をする場合は、マイナーバージョンを加算(v1.1.0)
v2以降
続いて、互換性のない更新が必要な場合、次のメジャーバージョンで公開します。
ここで重要となるのが、メジャーバージョンが変わったらモジュールパスも変わるということです。
v2にする場合は、モジュールパスの接尾辞としてv2
をつけます。
今回のサンプルの場合はexample.com/calc/v2
です。
さらに、リポジトリにはv2用のサブディレクトリを作成して開発します。 サブディレクトリの作成する以外の方法もありますが、 この方法はモジュールを認識しないツールと互換性があるため、 公式が推奨する方法となっています。
# パスは自身の環境に読み替えてください
cd $HOME/calc
# これまでのリソースをサブディレクトリv2にコピー
mkdir v2
cp go.mod go.sum *.go v2
# go.modのモジュールパスをv2用に変更
go mod edit -module example.com/calc/v2 v2/go.mod
# 今後はv2ディレクトリを更新
cd v2
go mod tidy
go test ./...
git add .
これでv2用のモジュールが用意できましたが、 正式リリースの前に実験的なバージョンによるリリースをして動作確認します。
git commit -m "Release v2.0.0-alpha.1"
git tag v2.0.0-alpha.1
git push origin v2.0.0-alpha.1
問題がなければv2をリリースします。
git commit -m "Release v2.0.0"
git tag v2.0.0
git push origin v2.0.0
モジュールを利用するプロジェクトはインポートパスと互換性のないAPI利用を修正します。
import (
"example.com/calc/v2"
)
あわせて、依存関係を更新します。
# パスは自身の環境に読み替えてください
cd $HOME/myapp
go mod tidy
go: finding module for package example.com/calc/v2
go: downloading example.com/calc/v2 v2.0.0
go: found example.com/calc/v2 in example.com/calc/v2 v2.0.0
これでv2.0.0の公開と利用ができました。 v3以降も同様に対応してきます。