単一プロジェクト内のsubproject間の共通設定をpluginにまとめる方法はgradle init
でプロジェクト作ればそこに例があるし、自分のblogだと gradle initの複数subproject構成を見る(6.8.3)にまとめている。
ここでは複数プロジェクト間の共通設定をpluginにまとめるやり方について。基本的には、大規模プロジェクト構成例の公式リファレンス https://docs.gradle.org/current/userguide/structuring_software_products.html のサンプルコード https://docs.gradle.org/current/samples/sample_structuring_software_projects.html から対象部分を抜粋した形となる。
やり方の概要としては、まずnaming conventionを行うgroovy-gradle-plugin
で記述しpluginディレクトリに配置、includeBuild
でそのディレクトリをincludeし、plugins { id '...'}
でそのpluginを使用する、といったところ。
環境
- java 11
- gradle 7.2
ソースコード
ファイルのレイアウトはおおむね以下となる。
- build-logic - pluginディレクトリとなる、共通設定を記述するpluginファイルの配置箇所。下の例だと
com.example.commons.gradle
がpluginの実体。 - project1 - プロジェクトその1。下の例だとsubprojectに
app
を持っている。 - project2 - プロジェクトその2
build-logic settings.gradle commons build.gradle src/main/groovy com.example.commons.gradle project1 settings.xml app build.gradle project2 settings.xml ...
build-logic
このディレクトリの名前自体は何でもよいが、gradleのサンプルプロジェクトの名前をそのまま使用している。
settings.gradle
dependencyResolutionManagement { repositories { gradlePluginPortal() } } rootProject.name = 'build-logic' include('commons')
一般的なプロジェクト例同様にinclude('commons')
でcommons
ディレクトリをincludeする。
gradlePluginPortal()
のところは今回くらいシンプルだと要らないけど大抵は必要になると思う。
commons/build.gradle
plugins {
id('groovy-gradle-plugin')
}
pluginはnaming conventionを使用して記述するので、そのためのgroovy-gradle-plugin
を記述する。
src/main/groovy/com.example.commons.gradle
groovy-gradle-plugin
の形式に従いsrc/main/groovy
ディレクトリにplugin-name.gradle
を記述する。後述する通りplugin-name
というidで参照可能になる。
println '### com.example.commons.gradle'
中身はデバッグ用のprintfだけ。
project1
settings.xml
pluginManagement { includeBuild('../build-logic') } rootProject.name = 'project1' include('app')
最初のincludeBuild('../build-logic')
でpluginディレクトリをincludeする。includeBuild
でディレクトリというかプロジェクトまるごと取り込むのがポイント。
app/build.gradle
最後にアプリケーションのプロジェクトで対象のpluginを使用する。
plugins {
id('com.example.commons')
}
com.example.commons.gradle
という名前なのでid('com.example.commons')
で使用できる。
実行時の様子
>gradlew build > Configure project :app ### com.example.commons.gradle
plugin内のprintが実行されてるのが分かる。
バリエーション
その他使いそうなplugin定義方法のメモ。
同一ディレクトリ内のplugin使用
例えば、以下のときにcom.example.commons.gradle
からsample.gradle
を参照したい場合。
commons/src/main/groovy com.example.commons.gradle sample.gradle
単純にpluginの名前で参照できる。
plugins { id 'sample' } println '### com.example.commons.gradle'
別のディレクトリを参照する
例えば、以下のようにcommons
とfoobar
があり、前者から後者を参照したい場合。
build-logic commons foobar
まずbuild-logic/settings.xml
にfoobar
を追加する。
include('foobar') include('commons')
foobar
の中身はほとんどcommons
と同じなので省略。次にbuild-logic/foobar/src/main/groovy/foo.bar.gradle
という名前のpluginファイルを作成した、とする。
commons/build.gradle
でfoobar
を取り込む。
plugins { id('groovy-gradle-plugin') } dependencies { implementation(project(':foobar')) }
gradle公式のサンプル見るとspring-bomはimplementation(platform(...))
を使ってる。このへん公式サンプル読み込めてないないんだが取り込む対象の種類によって使い分ける必要があるのだと思う。
最後にcom.example.commons.gradle
でfoo.bar
pluginを使用する。
plugins { id 'sample' id 'foo.bar' } println '### com.example.commons.gradle'
ハマりどころ
apply pluginは使えない
下記のようにnot foundになる。もしかしたら何か方法があるかもしれないがそこまで調べてない。
* What went wrong: A problem occurred evaluating project ':app'. > Plugin with id 'com.example.commons' not found.