Search code examples
javakotlingradlegradle-plugingradle-kotlin-dsl

Kotlin Gradle Plugin: How to access `Project` extensions such as `sourceSets`?


In a regular build script you can easily use extensions on Project like Project.sourceSets, for example build.gradle.kts:

sourceSets {
    main {
        ...
    }
}

But when I am developing a Gradle plugin in my buildSrc module, I cannot access these. For example:

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.*

class ExamplePlugin : Plugin<Project> {
    override fun apply(target: Project) {
        target.sourceSets { // error because `sourceSets` can't be resolved.
        }
    }
}

This is happening despite including the kotlin-gradle-plugin module in my buildSrc dependencies:

plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31")
}

So, how can I access these extensions from within my Gradle plugin?


Solution

  • class ExamplePlugin : Plugin<Project> {
        override fun apply(target: Project) {
            target.configure<JavaPluginExtension> {
                sourceSets {
                    println(names)
                }
            }
        }
    }
    

    See additional notes here: https://docs.gradle.org/current/userguide/kotlin_dsl.html#project_extensions_and_conventions

    Basically for plugins, or other times when the plugins applied are not known, the accessors (sourceSets, configurations, etc) of extensions added by other plugins will need to go through a method call which sort of 'retrieves' that scope or object. Further down the link there is also an example of how to get tasks created by other plugins:

    val test by target.tasks.existing(Test::class)
    test.configure { useJUnitPlatform() }
    // or
    val test by target.tasks.existing(Test::class) { 
        useJUnitPlatform()
    }
    

    note that if the 'sourceSet' object does not exist on the project (because the java plugin was not applied), an exception will be thrown . tested with gradle version 7.2, kotlin-dsl version 2.1.6