Gradle Pluginを導入する際、buildscript dependenciesかnew gradle plugin dslに統一したいですよね。 前者は簡単なので、後者の方向けの記事です。
例えばですが、ktlint-gradle pluginを導入する際、root projectにて
plugins {
    id("org.jlleitschuh.gradle.ktlint") version "9.2.0"
}
subprojects {
    apply(plugin = "org.jlleitschuh.gradle.ktlint")
    ktlint {
        verbose.set(true)
        android.set(true)
        outputToConsole.set(true)
        reporters {
            reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE)
        }
        ignoreFailures.set(true)
    }
}
とし、subprojectにて
plugins {
    kotlin("jvm") version "1.3.61"
}
とすると、ビルドに失敗します。
これは、Gradle Plugin自体が別のGradle Pluginに依存しており、かつ先にapplyされてしまった場合、
別のPluginへの依存の解決方法によっては NoClassDefFound となってしまうためです。
では、ktlint-gradleの依存解決方法を見てみましょう。
compileOnly となっていますね。つまり、ktlint-gradleはKotlin Gradle Pluginへの依存をコンパイル時のみ解決し、artifactの依存関係には含めないので、上記のgradle scriptの記述ではKotlin Gradle Pluginに含まれているクラスを解決できない、というわけです。
このような場合、root projectにおいて
plugins {
    kotlin("jvm") version "1.3.61" apply false
    id("org.jlleitschuh.gradle.ktlint") version "9.2.0"
}
subprojects {
    apply(plugin = "org.jlleitschuh.gradle.ktlint")
    ktlint {
        verbose.set(true)
        android.set(true)
        outputToConsole.set(true)
        reporters {
            reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE)
        }
        ignoreFailures.set(true)
    }
}
とし、subprojectにて
plugins {
    kotlin("jvm")
}
とすると、無事にビルドが通ります。
- Pluginをroot projectで解決する
- root projectには必要ないので 
apply falseする 
 - root projectには必要ないので 
 - subprojectでは同Pluginのversionを指定しない
- rootprojectにて指定済の為。指定するとビルドエラーになる。
 - pluginManagement DSLによる解決もありだが、個人的には好みではない。
 
 
このやり方が実質buildscript dependenciesの置き換えになるんでしょうか? 本記事の例はKotlin Gradle Pluginでしたが、Android Gradle PluginやGoogle Services Gradle Pluginを利用していると本記事の修正前の症状に陥りがちで、 やむを得ずbuildscript dependenciesを使用する事がありました。解決できるといいですね。
(追記) Android Gradle PluginとGoogle Services Pluginは相変わらずだめそうでした。 二重でバージョン指定すればエラーになるし、subprojectでバージョンを指定しなければpluginManagement scopeではmodule format errorになるし Gradle 6.0からbuildSrcのオブジェクトをsettings.gradleから参照できなくなったので、現状詰みです。