Skip to content
This repository has been archived by the owner on Aug 19, 2020. It is now read-only.

Can't not install built-in plugins on root project if I want to use it in subprojects block in root project #916

Closed
FredDeschenes opened this issue Jun 6, 2018 · 7 comments

Comments

@FredDeschenes
Copy link

Expected Behavior

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).

Current Behavior

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).

Context

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.).

Steps to Reproduce (for bugs)

I've made 2 demo projects here which I believe are the equivalent Groovy/Kotlin implementations of the same thing.

  • Checkout the project
  • cd groovy
  • ./gradlew[.bat] clean distTar
  • app1/build/distributions and app2/build/distribution will have the built packages
  • cd ../kotlin
  • ./gradlew[.bat] clean distTar
  • Gradle error output : No value has been specified for property 'mainClassName' (for :startScripts task)

Your Environment

  • Build scan URL:
    I couldn't get the buildscan plugin to work with the Kotlin DSL (it still outputs the Groovy DSL stuff to add to the project).
@madhead
Copy link

madhead commented Jun 12, 2018

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.

@JLLeitschuh
Copy link
Contributor

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?

@eskatos
Copy link
Member

eskatos commented Jun 20, 2018

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

@madhead
Copy link

madhead commented Jun 20, 2018

@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?

@eskatos
Copy link
Member

eskatos commented Jun 20, 2018

@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")
  }
}

@madhead
Copy link

madhead commented Jun 20, 2018

@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).

@FredDeschenes
Copy link
Author

@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?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants