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ファイルに沿ってルールの追加をしていくと捗りそう。