動機
gradle勉強のためgradle init
が生成する複数のsubproject構成を見る。基本的には https://docs.gradle.org/6.8.3/samples/sample_building_java_applications_multi_project.html と書いてる事は変わらない。
複数のsubprojectを作る場合はネットをぐぐるとallprojects
やsubprojects
を使う方法が多く出てくる。対してgradle init
はプラグインによる設定共有でこれを実現している。なのでその辺を学ぶのが目的。
環境
6.8.3
ソースコード
まずsettings.gradle
を見る。
rootProject.name = 'sample' include('app', 'list', 'utilities')
各プロジェクト間の関係は後々それぞれのbuild.gradle
で見るが以下になっている。
app -> utilities -> list
次にbuildSrc/src/main/groovy
を見る。ここには、このプロジェクト内で使用するgradleのプラグインが配置されている。プラグインに共通設定を記述し、各プロジェクトからそのプラグインを使用する、という構成となっている。
まずは各プラグインファイルの中身を見る。
sample.java-common-conventions.gradle
plugins { id 'java' } repositories { jcenter() } dependencies { constraints { implementation 'org.apache.commons:commons-text:1.9' } testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' } tasks.named('test') { useJUnitPlatform() }
sample.java-application-conventions.gradle
plugins { id 'sample.java-common-conventions' id 'application' }
sample.java-library-conventions.gradle
plugins { id 'sample.java-common-conventions' id 'java-library' }
プラグイン自体にも参照関係があり以下になっている。これも後に各プロジェクトのbuild.gradle
で見るが、どのプロジェクトがどのプラグイン使うのかはファイル名からなんとなく予想がつく。
application -+
|-common
ilbrary-----+
common
は全プラグインの共通設定がある。id 'java'
とかjcenter()
とかどのプロジェクトでも使用するdependencies
とかそのあたり。
application
はmainのあるプロジェクトを想定しているので、common
にプラスでid 'application'
を含む。
library
はapplication
とは対照的にcommon
プラスid 'java-library'
を含む。
buildSrc/build.gradle
には以下の記述がある。
plugins {
id 'groovy-gradle-plugin'
}
repositories {
gradlePluginPortal()
}
id 'groovy-gradle-plugin'
はconvention pluginsというもので、名前の通り、上記で見たプラグインファイルを命名規則に従って自動的に登録してくれる。なのでbuild.gradle
に適切なプラグイン名さえ書けばビルド時によしなにやってくれる。
というわけで各プロジェクトのbuild.gradle
を見ていく。ポイントはplugins {...}
のところ。
app
plugins { id 'sample.java-application-conventions' } dependencies { implementation 'org.apache.commons:commons-text' implementation project(':utilities') } application { // Define the main class for the application. mainClass = 'sample.app.App' }
utilities
plugins { id 'sample.java-library-conventions' } dependencies { api project(':list') }
list
plugins {
id 'sample.java-library-conventions'
}
app
はmainを置くアプリケーション本体なのでそれ用の設定が書かれたプラグインid 'sample.java-application-conventions'
を使用する。
utilities
, list
は被使用側のプロジェクトなのでプラグインはid 'sample.java-library-conventions'
を使用する。
まとめ
といった感じで、gradle init
が生成するプロジェクトは、そのプロジェクト用のプラグインを作成してそこに共通設定を記述、そして各プロジェクトからそれを参照、という作りになっている。
なお、更に複雑なプロジェクトの場合は https://docs.gradle.org/6.8.3/userguide/structuring_software_products.html という方法もあるらしい。
なんにしてもプロジェクトの複雑度に応じて方法を使い分けてね、という事なんだと思う。