Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

GradleのbuildSrcとどう付き合うべきか

Gradleで複数サブプロジェクトをもつプロジェクトを作成する - kdnakt blog を見て、buildSrcディレクトリ周りで混乱した記憶が蘇ってきました。

ということで「Gradleの設定やコードをどこに書くべきか」のうち、答えが明確なbuild.gradleファイルとbuildSrcディレクトリの使い分けについて現時点での見解をまとめておきます。

宣言的か命令的か

Gradleのビルドスクリプトを分割統治する手法として、昔はscript pluginと呼ばれる手法が使われていましたが、Gradle 7.1.1時点ではbuildSrcプロジェクトを使ってimperative logicを抽象化することが推奨されています

imperative logicというのはつまり”命令口調”なビルドスクリプトのことですね。ビルドスクリプト自身が極力宣言的(declarative)になるように、命令的なスクリプトをビルドスクリプトとは別のところに書いておこうということです。ビルドスクリプトを宣言的に保つことは、Gradleベストプラクティス堂々の一位に位置づけられており、その重要性が伺えます。

そしてimperative logicを隠しビルドスクリプトを宣言的に保つことは、プラグインの説明に書かれているように、プラグインの設計意図そのままです:

What plugins do (omit) Encapsulates imperative logic and allows build scripts to be as declarative as possible

自分が最近書いた例でいうと、チェックサムをGitHub Releasesに掲載するためのタスク定義はTHE・命令的でした。この定義、あるいは抽象化した定義をプラグインとして書いておいてビルドスクリプトに適用することで、ビルドスクリプトそのものを宣言的に保てるということです。

命令的なコードを置くためのbuildSrcディレクト

通常プラグインはGradle Plugin Portalにpublishして使いますが、プロジェクトごとにpublishしていたらキリがありません。そこでプロジェクト固有のローカルな"命令的"スクリプトを置くための場所として buildSrc プロジェクトが存在します。プロジェクトルートに buildSrc ディレクトリを置くと、中のコードをコンパイルしたものをビルドスクリプトのCLASSPATHに置いてくれるのです。

以上のように、全体像がわかってしまえばbuild.gradleファイルとbuildSrcディレクトリどちらを使うべきかは見えてきます。 宣言的なコードはbuild.gradleファイルに、命令的なコードはbuildSrcディレクトリに置きましょう

buildSrcプロジェクトの書き方はmike-neckさんのブログに詳しいのでオススメです。プラグインテスト手法も確立しているので、ビルド性能だけでなくビルドスクリプト管理の生産性も上がるといいですね。

mike-neck.hatenadiary.com