mike-neckのブログ

Java or Groovy or Swift or Golang

precompiled groovy dsl が便利そう

precompiled groovy dslbuildSrc プロジェクトに gradle ファイルを入れておくと、メインの build.gradleプラグイン取り込みの仕組みを使って取り込める機能で、ファイルを分割して apply from <file> としてたビルドファイルを分割していた仕組みの強化版(コンパイルされるので速い)です。

f:id:mike_neck:20150917235151p:plain

precompiled groovy dsl

以下のようなディレクトリーの構造を作ります

root/
├── build.gradle
├── buildSrc
│   ├── build.gradle
│   └── src
│       └── main
│           └── groovy
│               └── example-plugin.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

buildSrc ディレクトリーの build.gradle に次のような記述を追加します

plugins {
  id 'groovy-gradle-plugin'
}

precompiled groovy dsl を利用する場合は、 buildSrc/build.gradle ファイルに groovy-gradle-plugin が必要です。なお kts でやる場合は次のように kotlin-dsl プラグインになります。

plugins {
    `kotlin-dsl`
}

repositories {
    jcenter()
}

次に、 buildSrc/src/main/groovy の下にある example-plugin.gradle というファイルを作り、中にプラグインとして(事前コンパイルして)使う DSL を記述します。

たとえば、次のようなもの本来であれば build.gradle に記述している内容を記述します。

plugins {
  id 'java-library'
}

repositories {
  mavenCentral()
}

dependencies {
  testImplementation 'org.junit.jupiter:junit-jupiter:5.6.1'
}

tasks.withType(Test) {
  useJUnitPlatform()
}

もちろん、ここで記述した内容はそのままではメインのビルドに反映しません。これを取り込む際にはメインの build.gradle に次の記述を追加します。

plugins {
  id 'example-plugin' // buildSrc/src/main/groovy  の下に作った gradle ファイルの名前
}

これにより、 buildSrc/src/main/groovy/example-plugin.gradle に書いた内容がメインのビルドに反映されます。


これのどこが便利か?

この前リリースした ktcheck のビルドでは次のような警告が出ています

The Kotlin Gradle plugin was loaded multiple times in different subprojects, which is not supported and may break the build. 
This might happen in subprojects that apply the Kotlin plugins with the Gradle 'plugins { ... }' DSL if they specify explicit versions, even if the versions are equal.
Please add the Kotlin plugin to the common parent project or the root project, then remove the versions in the subprojects.
If the parent project does not need the plugin, add 'apply false' to the plugin line.

これは複数のビルドで kotlin-jvm プラグインの同じバージョンを利用すると宣言しているため、次のバージョンの Gradle ではビルドが壊れる可能性があると警告を受けています。

これをどう直そうか思案していたところですが、 kotlin-dsl プラグインを使えばうまく解決できそうな感じがします。


また、複数のビルドファイルに分割しているケースで複数ファイルにまたがってプラグインの適用管理をしているケースなどでもうまく機能するかもしれません。

以上