Pre-release
Pre-release

@eskatos eskatos released this Aug 14, 2018

Assets 2

Gradle Kotlin DSL 1.0 RC3 Release Notes

Gradle Kotlin DSL 1.0 RC3 brings Kotlin 1.2.60, support for configuration avoidance, a Gradle API decorated for Kotlin, enhanced IntelliJ IDEA integration, lots of DSL polish and bug fixes.

At the same time the IntelliJ IDEA Kotlin Plugin fixed important build script editing related issues. It is recommended for everyone to upgrade to the latest and greatest.

This release contains potential breaking changes, see below.

v1.0-RC3 is included in Gradle 4.10 RC3.

To use it, upgrade your Gradle wrapper in the following fashion:

$ cd $YOUR_PROJECT_ROOT
$ gradle wrapper --gradle-version 4.10-rc-3 --distribution-type all

Updates since v1.0-RC1

  • Add missing specialized withType<T>() extensions on NamedDomainObjectCollection (#1034, #1035)

  • Let build-cache be enabled via system property instead of project property (#1032, #1036)

  • Make the build cache keys compatible with the remote build cache (#1023, #1027)

Updates since v0.18.4

  • Documentation (#665, #835, #966, #968, #988)
    All public Gradle Kotlin DSL API members now have proper documentation available in the IDE and in the API reference.

    image

    You might also want to check out the guide to migrating build logic from Groovy to Kotlin and other Gradle guides that now contain samples for the Gradle Kotlin DSL.

  • Script compilation build cache (#963, #978, #987)
    Compiled project scripts can now be cached in a shared Gradle build cache for maximum reuse across builds. The experimental build cache integration must be explicitly enabled via the org.gradle.kotlin.dsl.caching.buildcache Gradle project property set to true.

  • Script compilation now targets JVM 8 (#955, #955)
    As a result, it is now possible to use libraries targeting JVM 8 in your build scripts.

  • IDE integration improvements (#962, #972, #942, #464, #1004)
    When editing build logic in IntelliJ IDEA, changes are now propagated between scripts and between buildSrc and scripts without having to sync the Gradle build, resulting in a much better user experience.

    intellij-gradle kts-buildsrc-change-auto-reload

    The lifecycle of Gradle daemons spawned by IntelliJ IDEA when editing Gradle Kotlin DSL script has been revised to prevent running too many of them. Before that change and under certain circumstances, one Gradle daemon was running per open script, this is now limited, resulting in less pressure on the system and a quicker feedback.

    Moreover, all usages of types relying on kotlin implementation by delegation for a Java interface now show meaningful parameter name hints instead of p0, p1 etc..:

    image

  • Support for configuration avoidance of named domain object containers (#123, #907, #986, #993, #994, #1000)
    Gradle 4.9 introduced new APIs for declaring and configuring Gradle Tasks in build scripts and plugins that allow Gradle to avoid executing unnecessary build logic.
    Gradle 4.10 makes the same API available for all NamedDomainObjectContainer types.

    This release of the Gradle Kotlin DSL promotes these APIs as the preferred way of configuring container elements by

    • reimplementing the String invoke DSL sugar plus the getting and creating delegated properties atop the new APIs ;
    • introducing the new existing and registering delegated properties designed specifically with configuration avoidance in mind which expose NamedDomainObjectProvider<T> instead of the container element type.

    As an example, let's look at wiring a simple task graph using only the new configuration avoidance support.

    /**
     * An example Gradle task.
     */
    open class GreetingTask : DefaultTask() {
    
        val message = project.objects.property<String>()
    
        @TaskAction
        fun greet() = println(message.get())
    }
    
    tasks {
    
        // `hello` is a `TaskProvider<GreetingTask>`
        val hello by registering(GreetingTask::class) {
            message.set("Hello!")
        }
    
        // `goodbye` is a `TaskProvider<GreetingTask>`
        val goodbye by registering(GreetingTask::class)
    
        // Every `NamedDomainObjectProvider<T>` can be lazily configured as follows
        goodbye {
            dependsOn(hello)
        }
    
        // Existing container elements can be lazily configured via the `String` invoke DSL
        "goodbye"(GreetingTask::class) {
            message.set("Goodbye!")
        }
    
        // Regular API members are also available
        register("chat")
    }
    
    // ...
    
    tasks {
    
        // Existing container elements can be lazily brought into scope
        val goodbye by existing
    
        "chat" {
            dependsOn(goodbye)
        }
    }
  • SAM conversion for Kotlin functions (#522, #960)
    SAM (Single Abstract Method) conversion for Kotlin functions allows Kotlin build logic to expose and consume org.gradle.api.Action<T> based APIs. Such APIs can then be used uniformly from both the Kotlin and Groovy DSLs.

    As an example, given the following hypothetical Kotlin function with a Java SAM parameter type:

    fun kotlinFunctionWithJavaSam(action: org.gradle.api.Action<Any>) = TODO()

    SAM conversion for Kotlin functions enables the following usage of the function:

    kotlinFunctionWithJavaSam {
        // ...
    }

    Without SAM conversion for Kotlin functions one would have to explicitly convert the passed lambda:

    kotlinFunctionWithJavaSam(Action {
        // ...
    })
  • Gradle API is decorated for Kotlin (#221, #914)
    The public Gradle API available in Gradle Kotlin DSL scripts and Kotlin sources of projects applying the kotlin-dsl plugin is now decorated with Kotlin extensions mapping java.lang.Class<?> function parameters to kotlin.reflect.KClass<?> parameters.

    As an example, the following settings file:

    buildCache {
        remote(HttpBuildCache::class.java) {
            url = uri("http://example.com/cache")
        }
    }

    can now be written omitting .java:

    buildCache {
        remote(HttpBuildCache::class) {
            url = uri("http://example.com/cache")
        }
    }

For the complete list see the gradle/kotlin-dsl issues for 1.0-RC1, 1.0-RC2 and 1.0-RC3.

Breaking changes

This release contains some potential breaking changes:

  • java.sourceSets now is sourceSets
    The source set container can now be accessed using project.sourceSets, or just sourceSets. Previously it was located at project.java.sourceSets, or just java.sourceSets.

  • Container String invoke now is named() instead of maybeCreate()
    This change in behaviour can cause builds to fail with org.gradle.api.UnknownDomainObjectException. The fix is to explicitly call create or preferably register.

    For a concrete example, the following script which, before this change, would cause a new configuration named mine to be created would now fail with Configuration with name 'mine' not found.:

    configurations {
        "mine" { isVisible = false }
    }

    The fix, as explained above, is to introduce an explicit call to create:

    configurations {
        create("mine") { isVisible = false }
    }
  • SAM conversion for Kotlin functions is now enabled
    The now enabled Kotlin compiler features could cause Gradle Kotlin DSL scripts or code in projects applying the kotlin-dsl plugin that previously compiled successfully to fail. The now stricter type inference semantics might cause types previously inferred as non-null to be inferred as nullable, for example. At the same time, it can cause previously unambiguous call sites to become ambiguous and will need to be disambiguated. See the Kotlin compiler arguments section of the Gradle Kotlin DSL documentation for more information about the enabled Kotlin compiler features.

  • The named containers API signature changed
    As a result, a plugin using e.g. delegated properties providers getting or creating, compiled against this release will fail when run with previous Gradle Kotlin DSL versions.

  • The kotlin-dsl plugin now respect the JSR-305 package annotations
    Just like the Gradle Kotlin DSL scripts do. As a result, annotated Java elements whose types were previously seen as Kotlin platform types, thus non-nullable, will now be seen as effectively either non-nullable or nullable types depending on the JSR-305 annotations. This change could cause compilation errors in projects applying the kotlin-dsl plugin. See Calling Java code from Kotlin in the Kotlin documentation for more information.

  • The kotlin-dsl plugin now requires a repository to be declared
    With Kotlin 1.2.60, the Kotlin Gradle Plugin driving the kotlin compiler requires extra dependencies that aren't required by Gradle Kotlin DSL scripts alone and aren't embedded into Gradle.

    This can be fixed by adding a repository that contains Kotlin compiler dependencies on the project where the kotlin-dsl plugin is applied:

    repositories {
        jcenter()
    }

Avoiding Gradle Kotlin DSL internal APIs

Use of Kotlin DSL internal APIs in plugins and build scripts has the potential to break builds when either Gradle or plugins change.

The Kotlin DSL extends the Gradle public API definition with org/gradle/kotlin/dsl/* excluding any subpackages.