Freitag, 16. März 2018

Gradle Kotlin DSL: Using the Maven Publish Plugin

If you want to publish your libraries built with Gradle to a Maven Repository you need to create the necessary artifacts and a corresponding POM-file. To do that Gradle offers the Maven Plugin and the new incubating Maven Publish Plugin which is used in this post.
Please note that the Maven Publish Plugin does not yet support all the features of the Maven Plugin which it will eventually replace.
plugins {
    ...
    `maven-publish`
}
After declaring the plugin, a publication needs to be defined inside the publishing block. In the Kotlin DSL you have two ways to create an actual publication: as String or as a variable. When using a String to declare a publication the syntax changes slightly:
publishing {
    (publications) {
        "mavenJava"(MavenPublication::class) {
            from(components["java"])
        }
    }
}
The publications function cannot be used since it does not declare the necessary invoke() function on Strings. By putting parenthesis around publications we instead invoke getPublications() which enables the use of Strings as a publication.
When using a variable instead of the String the publications block can be used:
publishing {
    publications {
        val mavenJava by creating(MavenPublication::class) {
            from(components["java"])
        }
    }
}
Additional artifacts can be added to the publication by defining and adding an artifact creating task to it. In this example another JAR file is created containing all the source files from the main source set:
tasks {
    "sourcesJar"(Jar::class) {
        classifier = "sources"
        from(java.sourceSets["main"].allSource)
        dependsOn("classes")
    }  
}

publishing {
    (publications) {
        "mavenJava"(MavenPublication::class) {
            from(components["java"])
            artifact(tasks["sourcesJar"])
        }
    }
}

Gradle Kotlin DSL: Creating additional jars

Sometimes you want to create more than one JAR file for your project. It could for example contain some source code or your compiled test classes. To do that in Gradle you first need create a task that inherits from the Gradle Jar task and will produce your JAR file:

"testJar"(Jar::class) {
    classifier = "tests"
    from(java.sourceSets["test"].output)
    dependsOn("testClasses")
}
Then you add the artifact itself:
artifacts {
    add("archives", tasks["testJar"])
}

Your build will now create an additional JAR file with the specified content which are the compiled class files for tests in this example.

Samstag, 10. März 2018

Gradle Kotlin DSL: Using JUnit 5


Since I ended up spending a lot of time figuring out how to do certain things in the Kotlin DSL for Gradle, I decided to share my findings in a series of small posts.

On todays menu is JUnit 5 and the built-in support in Gradle 4.6. Use the following code snippet to enable JUnit 5 tests in your Gradle build:

tasks {    
    withType<Test>{        
        useJUnitPlatform()
    }
}

UPDATE:
Gradle 4.9 introduced a new API for creating tasks which reflects in the Gradle Kotlin DSL in Gradle 4.10.

Using the new API to configure tasks of type Test looks the following:
tasks {
    withType<Test>().configureEach {
        useJUnitPlatform()
    }
}

Alternatively the test task can be configured directly:
tasks {
    "test"(Test::class) {
        useJUnitPlatform()
    }
}
This is now possible because the invoke() function on Strings was changed to look up existing tasks.