Using the Groovy DSL with multiple sub projects, I could apply plugins in the subprojects block in the root project without having the plugin applied on the root project (to be able to set common stuff in the subprojects block, like setting the 'java' and 'application' plugins, dependency management stuff, etc).
With the Kotlin DSL, I can't apply plugins in the subprojects block in the root project without them being included in the plugins block. Unfortunately, this also applies the plugin on the root project and can cause some issues when trying to run tasks that are present in all subprojects (in my case distTar from the application plugin).
We should be able to apply built-in plugins on sub-projects only like when using the Groovy DSL.
External plugins work fine since we can do apply false in the plugins block to prevent the plugin from being applied there, but built-in plugins won't let us to this (throwing an exception telling us it would be a no-op : > Plugin 'org.gradle.application' is a core Gradle plugin, which is already on the classpath. Requesting it with the 'apply false' option is a no-op.).
I've made 2 demo projects here which I believe are the equivalent Groovy/Kotlin implementations of the same thing.
cd groovy./gradlew[.bat] clean distTarapp1/build/distributions and app2/build/distribution will have the built packagescd ../kotlin./gradlew[.bat] clean distTarNo value has been specified for property 'mainClassName' (for :startScripts task)
This also has impact on static accessors for subprojects.
Imagine, I want to have an implementation-scoped dependency in all the subprojects, but not in the root one. What I want to do is:
plugins {
java.apply(false) // This plugin contributes `implementation` scope
kotlin("jvm").version("1.2.41").apply(false)
}
subprojects {
apply {
plugin<JavaPlugin>()
plugin<KotlinPluginWrapper>()
}
repositories {
jcenter()
}
dependencies {
implementation(kotlin("stdlib-jdk8", "1.2.41"))
}
}
But I cannot do that:
Plugin 'org.gradle.java' is a core Gradle plugin, which is already on the classpath. Requesting it with the 'apply false' option is a no-op.
Actualy no-op is what I want indeed!
Without having java in plugins block static accessors are not generated by Kotlin DSL, so I have to fall back to "implementation"(kotlin("stdlib-jdk8", "1.2.41")) which is ugly.
I think that the problem with this is that in order to generate the accessors, the plugin is applied to the project before compiling in order to generate the accessors.
In order for apply(false) to work, the compiler would have to apply the plugin to a fake project, figure out what accessors are generated and then throw away that project.
Am I capturing the problem correctly @bamboo @eskatos?
Using apply false on a core built-in plugin doesn't make sense, it's already on the classpath and there's nothing more the Kotlin DSL can do. In fact this is a Gradle core matter, you get the very same behavior with the Groovy DSL.
@FredDeschenes simply remove the core application plugin from your root project plugins {} block.
@madhead simply remove java.apply(false) from your build script
@eskatos, how do I get access function for dependency configuration (implementation, compile) generated for root project so I can use this accessor in subprojects block?
@madhead if your root project doesn't have those configurations, then no accessors for them will be available in your root project build script.
You need to reference them by name:
subprojects {
dependencies {
"implementation"("some:dep:1.0")
}
}
You can also bring a reference into scope if you prefer or need to reference the configurations several times:
subprojects {
val implementation by configurations
dependencies {
implementation("some:dep:1.0")
}
}
@eskatos, nice trick, thanks!
However, it would be could to have the ability to just reference it, like it works for third-party plugins (when you apply(false) them on the root projects accessors became available).
@eskatos : Well I can't remove the application plugin from the root project's plugins block otherwise I get errors in the subproject block. How am I supposed to write the java or application (or whatever else) blocks in subprojects?
Most helpful comment
This also has impact on static accessors for subprojects.
Imagine, I want to have an
implementation-scoped dependency in all the subprojects, but not in the root one. What I want to do is:But I cannot do that:
Actualy no-op is what I want indeed!
Without having
javainpluginsblock static accessors are not generated by Kotlin DSL, so I have to fall back to"implementation"(kotlin("stdlib-jdk8", "1.2.41"))which is ugly.