Gradle Kotlin DSL: get sourceSet of another project

Viewed 3285

Currently, we're trying to migrate our existing build.gradle scripts to the new Kotlin DSL. Right now, we are struggling with the jar task configuration.

Our project is a simple multi-project. Let's say we've Core and Plugin and Plugin uses classes from Core. Now, when building Plugin, the target jar should include any used classes from Core.

This is how it looked like before:

jar {
    from sourceSets.main.output
    from project(':Core').sourceSets.main.output
}

And this is the current solution we've with Kotlin DSL:

val jar: Jar by tasks
jar.apply {
    from(java.sourceSets["main"].allSource)
    from(project(":Core").the<SourceSetContainer>()["main"].allSource)
}

However, the above example just gives me an Extension of type 'SourceSetContainer' does not exist. Currently registered extension types: [ExtraPropertiesExtension] error. I've also tried other code snippets I've found, but none of them have been working so far.

I have also tried this (like suggested in the first answer):

val jar: Jar by tasks
jar.apply {
    from(java.sourceSets["main"].allSource)
    from(project(":Core").sourceSets.getByName("main").allSource)
}

But then the IDE (and also the jar task) argues that sourceSets is not available: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public val KotlinJvmProjectExtension.sourceSets: NamedDomainObjectContainer<DefaultKotlinSourceSet> defined in org.gradle.kotlin.dsl.

I hope that someone can help us, because it is very frustrating to spend hours in configuration instead of writing any usefull code.

Thank you very much in advance.

2 Answers

You can access the SourceSetContainer by

project(":Core").extensions.getByType(SourceSetContainer::class)

it seems <T : Any> Project.the(extensionType: KClass<T>): T looks in the convention of the project, while val Project.sourceSets: SourceSetContainer get() looks in the extensions ExtensionContaier instead. This is somewhat odd, as the documentation for the says "Returns the plugin convention or extension of the specified type."

Note that you may need to do your sourceSet manipulation in gradle.projectsEvaluated, because otherwise the sourceSet in question may not be configured yet if the corresponding project is not yet evaluated.

If you get access to the project, then everything should looks like your actual groovy gradle script:

 project(":Core").sourceSets.getByName("main").allSource

So regarding your actual code:

 val jar: Jar by tasks
 jar.apply {
     from(java.sourceSets["main"].allSource)
     from(project(":Core").sourceSets.getByName("main").allSource)
 }
Related