BazelでGoプロジェクトのビルド。Gazelleのgo_repositoryで外部ライブラリの依存とBazelのgo_testでテスト。
BazelをつかったGoプロジェクトのビルドをまとめている。前回のエントリではバイナリのビルドとDockerイメージのビルドをまとめた。
GoとKotlinのマルチプロジェクトをBazelでビルドする - 平日インプット週末アウトプットぶろぐ
今回は外部ライブラリをGoプロジェクトに依存させる方法とテストの方法をまとめていく。
Gazelleのgo_repositoryで外部のライブラリを依存させる
外部ライブラリの依存はGazelleのgo_repositoryをつかう。
bazel-gazelle/repository.rst at master · bazelbuild/bazel-gazelle · GitHub
依存させるライブラリはDIツールのwireを選んだ。
WORKSPACE
WORKSPACEにgo_repositoryを有効にしてruleを追加する。
|
|
name
はWORKSPACE内の固有をつける。commit
はgoogle/go-cloud 0.5.0 バージョンのハッシュ値を設定する。import_path
はGoコードでwireを利用するときにimport文のパスをセットする。
wireをつかってDIするコードを用意する。
簡易的なstruceのインスタンスをDIするコードを用意する。
|
|
上記のコードを追加してgazelleコマンドを実行する。
1
|
(bazel-multiprojects) $ bazel run gazelle |
コマンドを実行するとGazelleはWORKSPACEに追加したgo_repositoryの依存とgreet_usecase.goのwireの利用を理解して次のようなBUILD.bazelファイルを生成してくれる。
|
|
greet_usecase.goをソースにしたライブラリのruleが定義されている。depsにはWORKSPACEで定義したcom_github_google_cloud
のレポジトリが参照されている。
Gazelleの魅力
Bazel + Gazelleの魅力はこのようにWORKSPACEで定義した依存とコードの中間の役割のBUILDファイルを自動で生成してくれるところだ。
最終的にはmainパッケージからusecaseパッケージを参照することになる。wireで生成したwire_gen.goコードは次のようになる。
|
|
mainパッケージにusecaseが依存した状態で再度、gazelleコマンドを実行するとmainパッケージのBUILD.bazelは次のような差分になる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
diff --git a/pkg/public_go/BUILD.bazel b/pkg/public_go/BUILD.bazel index 06f7a04..b50739a 100644 --- a/pkg/public_go/BUILD.bazel +++ b/pkg/public_go/BUILD.bazel @@ -2,10 +2,16 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") go_library( name = "go_default_library", - srcs = ["main.go"], + srcs = [ + "main.go", + "wire_gen.go", + ], importpath = "github.com/soushin/bazel-multiprojects/pkg/public_go", visibility = ["//visibility:private"], - deps = ["//pkg/common_go/util:go_default_library"], + deps = [ + "//pkg/common_go/util:go_default_library", + "//pkg/public_go/usecase:go_default_library", + ], ) go_binary( |
depsに//pkg/public_go/usecase:go_default_library
が追加されている。usecaseパッケージに定義しているgo_library
を参照している。
Gazelleは各パッケージの依存とWORKSPACEの外部依存を理解してBUILDファイルを生成するだけでなくパッケージ間の依存も理解をしてくれる。
Bazelのgo_testでテスト
テストのビルドもBazelで行う。
次のようなstringのテストコードを用意する。
|
|
このテストコードを配置した状態でgazelleコマンドを実行するとutilパッケージのBUILD.bazelは次のような差分になる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
diff --git a/pkg/common_go/util/BUILD.bazel b/pkg/common_go/util/BUILD.bazel index ce90025..d48f3ca 100644 --- a/pkg/common_go/util/BUILD.bazel +++ b/pkg/common_go/util/BUILD.bazel @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", @@ -6,3 +6,9 @@ go_library( importpath = "github.com/soushin/bazel-multiprojects/pkg/common_go/util", visibility = ["//visibility:public"], ) + +go_test( + name = "go_default_test", + srcs = ["string_test.go"], + embed = [":go_default_library"], +) |
Gazelleがパッケージ内のテストコードを解釈してgo_test
のruleを追加してくれる。このgo_testは次のように実行する
1 2 3 4 5 6 7 8 9 10 11 12 13 |
(bazel-multiprojects) $ bazel run //pkg/common_go/util:go_default_test INFO: Analysed target //pkg/common_go/util:go_default_test (4 packages loaded). INFO: Found 1 target... Target //pkg/common_go/util:go_default_test up-to-date: bazel-bin/pkg/common_go/util/darwin_amd64_stripped/go_default_test INFO: Elapsed time: 0.244s, Critical Path: 0.01s INFO: 0 processes. INFO: Build completed successfully, 1 total action INFO: Build completed successfully, 1 total action exec ${PAGER:-/usr/bin/less} "$0" || exit 1 Executing tests from //pkg/common_go/util:go_default_test ----------------------------------------------------------------------------- PASS |
まとめ
- Gazelleを使ったGoプロジェクトの外部ライブラリ依存とテストの方法をまとめた。
- GoプロジェクトにおいてはGazelleの働きが素晴らしくビルドルールの追加からビルドまでストレスフリーで開発が行える印象。
- KotlinプロジェクトにおいてもGazelleが生成するBUILDファイルに沿ってルールの追加をしていくと捗りそう。