Gradle 6 dependencies with strict version and because keyword - gradle

The problem
I'm currently experimenting with Gradle 6.0 and ran into the problem that I would like to combine the because statement with the syntax for e.g. strict and rejected versions.
My buildscript:
dependencies {
testImplementation(group: 'org.junit.jupiter', name: 'junit-jupiter-api') {
version {
strictly '[5.0, 6.0]'
prefer '5.5.2'
reject '5.5.1' // for testing purpose only
}
}
testRuntimeOnly(group: 'org.junit.jupiter', name: 'junit-jupiter-engine') {
version {
strictly '[5.0, 6.0]'
prefer '5.5.2'
reject '5.5.1' // for testing purpose only
}
}
// Force Gradle to load the JUnit Platform Launcher from the module-path
testRuntimeOnly(group: 'org.junit.platform', name: 'junit-platform-launcher') {
version {
strictly '[1.5, 2.0]'
prefer '1.5.2'
}
}
}
What I've tried so far
I've currently tried to add the because statement below or above the versionstatement and adding curly brackets around them, but none of these things seemed to work out.
The question
Is it possible to add the because statement to the last dependency and if yes, how?
It would be interesting too, to know whether I can combine both testRuntimeOnly into one.

Using the Kotlin DSL, you can easily see exactly what is available to you. So converting your sample to use the Kotlin DSL, we have
dependencies {
testImplementation("org.junit.jupiter", "junit-jupiter-api") {
version {
strictly("[5.0, 6.0]")
prefer("5.5.2")
reject("5.5.1") // for testing purpose only
}
}
testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine") {
version {
strictly("[5.0, 6.0]")
prefer("5.5.2")
reject("5.5.1") // for testing purpose only
}
}
// Force Gradle to load the JUnit Platform Launcher from the module-path
testRuntimeOnly("org.junit.platform", "junit-platform-launcher") {
version {
strictly("[1.5, 2.0]")
prefer("1.5.2")
}
}
}
Is it possible to add the because statement to the last dependency and if yes, how?
Yes it is. Since I'm using the Kotlin DSL now, I can easily bring up intelli-sense:
You can see here because is available outside the version block, so:
// Force Gradle to load the JUnit Platform Launcher from the module-path
testRuntimeOnly("org.junit.platform", "junit-platform-launcher") {
version {
strictly("[1.5, 2.0]")
prefer("1.5.2")
}
because("my reason here.")
}

Related

Using Avro to java plugin in gradle kotlin dsl

I've a java project that is built using gradle kotlin dsl.
Now I want to use gradle-avro-plugin like this https://github.com/davidmc24/gradle-avro-plugin#alternate-usage
In kotlin dsl I have written the same logic as below -
plugins {
java
id( "com.github.davidmc24.gradle.plugin.avro") version "1.0.0"
}
dependencies {
implementation ("org.apache.avro", "avro", "1.10.1")
}
val generateAvro = tasks.register<com.github.davidmc24.gradle.plugin.avro.GenerateAvroJavaTask>("generateAvro") {
source("src/avro")
this.setOutputDir(file("dest/avro"))
}
configure<org.gradle.api.tasks.compile.JavaCompile> {
this.source = fileTree(generateAvro)
}
The above code is returning below error when I run grade compileJava-
> * What went wrong:
Extension of type 'JavaCompile' does not exist. Currently registered extension types: [ExtraPropertiesExtension, DefaultArtifactPublicationSet, SourceSetContainer, ReportingExtension, JavaPluginExtension, JavaInstallationRegistry, JavaToolchainService, DistributionContainer, JavaApplication, DefaultAvroExtension]
How can I fix this error?
I had similar issues, what worked for me was:
plugins {
id("com.github.davidmc24.gradle.plugin.avro") version "1.2.0"
}
dependencies {
implementation("org.apache.avro:avro:1.10.1")
}
tasks.withType<com.github.davidmc24.gradle.plugin.avro.GenerateAvroJavaTask> {
setOutputDir(file("src/dest/dir/"))
}
The important thing is I did not registered a new task, just specified a new destination directory for each task with the type GenerateAvroJavaTask

gradle - listing multiple subprojects for 'project'

Is there a way to list multiple projects for a common dependency. I tried as follows, it doesn't work. I don't want to list individually for a better maintenance.
project(':com.example.bundle1', ':com.example.bundle2') {
dependencies {
compile project(':com.example.common')
}
}
you can leverage groovy list support here:
[':com.example.bundle1', ':com.example.bundle2'].each {
project(it) {
dependencies {
compile project(':com.example.common')
}
}
}

How to add a dependency in a multiplatform kotlin / native intellij project?

I have the following build.gradle configuration:
plugins {
id 'org.jetbrains.kotlin.multiplatform' version '1.3.41'
}
repositories {
mavenCentral()
}
kotlin {
linuxX64("linux") {
binaries {
executable {
entryPoint = 'sample.main'
runTask?.args('')
}
}
}
sourceSets {
linuxMain {
dependencies {
api("org.http4k:http4k-core:3.183.0")
}
}
linuxTest {
}
}
}
And the following source file src/linuxMain/kotlin/sample/SampleLinux.kt :
package sample
fun hello(): String = "Hello, Kotlin/Native!"
fun main() {
println(hello())
}
How to add a external library in order to be able to use autocomplete in imports for the library org.http4k:http4k-core:3.183.0?
As you can see, I tried to add the line api("org.http4k:http4k-core:3.183.0") in linuxMain dependencies, but although intellij show the library in External Libraries section, I cannot work with the packages neither classes of http4k in SampleLinux.kt file: any org.http4k..... import attempt is not recognized and generates compilation error.
After a quick look, I am almost sure that http4k is JVM-only library, at least for now. According to this issue, they are still waiting for Native to grow. If you are interested, it would be nice if one can ask the library maintainers again. As far as K/N has grown a lot by the last year, maybe they change their mind.

Gradle Kotlin DSL equivalent for Groovy DSL 'run'?

I am trying to build a simple JavaFX 11 program with Kotlin and Java 11, using Gradle, following the instructions here. However, this page uses Gradle's Groovy DSL, and I am trying to use the Kotlin DSL. Surprisingly, my Google searches have not turned up a document that maps each Groovy construct to its equivalent Kotlin construct or explains in general how to convert Groovy DSL code to equivalent Kotlin DSL code. (This seems like a big oversight in the Gradle documentation!).
In particular, this document contains the following Groovy code:
compileJava {
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'javafx.controls'
]
}
}
run {
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'javafx.controls'
]
}
}
As far as I can tell, the Kotlin equivalent to the first part appears to be:
tasks.withType<JavaCompile> {
options.compilerArgs.addAll(arrayOf(
"--module-path", classpath.asPath,
"--add-modules", "javafx.controls"
))
}
However, I have not been able to figure out what the Kotlin DSL equivalent to the second part is. Note that 'run' is a standard function extension in Kotlin's standard library, so it does not appear that the Kotlin version of this code can use the name 'run' for the same purpose in the Kotlin DSL.
(Note: I considered trying to use a plugin for the JavaFX support (as described by this page, for instance), but the plugin seems quite complicated to use, and I already am having enough problems with the number of complications in this project that I am hesitant to introduce a very-lightly-documented open-source plugin into the mix. I really am trying to produce the simplest possible "Hello, World" program in JavaFX/Gradle at the moment, and this has so far seemed surprisingly difficult.).
Any help would be appreciated.
Using the configuration avoidance APIs, the equivalent to the second block is:
tasks.named<JavaExec>("run") {
doFirst {
jvmArgs = listOf("--module-path", classpath.asPath,"--add-modules", "javafx.controls")
}
}
The key is that run has the JavaExec type, which like any task's type can be discovered by creating a task to print the class of the task that you then run:
tasks.register("getName") {
doFirst {
print("Class name: ${tasks["run"].javaClass}")
}
}
Note that as your JavaFX application grows, you will need to specify additional modules like this:
tasks.named<JavaExec>("run") {
doFirst {
jvmArgs = listOf("--module-path", classpath.asPath,
"--add-modules", "javafx.base,javafx.controls,javafx.graphics")
}
}
Surprisingly, my Google searches have not turned up a document that maps each Groovy construct to its equivalent Kotlin construct or explains in general how to convert Groovy DSL code to equivalent Kotlin DSL code.
Please have a look at https://guides.gradle.org/migrating-build-logic-from-groovy-to-kotlin/ and esp. the Configuring tasks section. According to that, I'd say the Kotlin DSL equivalent is
tasks.named<JavaExec>("run").doFirst {
jvmArgs = listOf('--module-path', classpath.asPath, '--add-modules', 'javafx.controls')
}
With Gradle 5.0 and kotlin-dsl 1.0, tasks that are registered or created by plugins can be statically accessed through the tasks container (TaskContainer. There is this example provided in the release notes:
plugins {
java
}
tasks {
named<Test>("test") {
testLogging.showStacktraces = true
}
}
you can now write:
plugins {
java
}
tasks {
test {
testLogging.showStacktraces = true
}
}
For your example, you are most likely using the application plugin, which registers the run task so you can configure it in a similar matter. One issue to be aware of is that run clashes with the Kotlin stdlib run method so you need to apply some workaround to make sure it gets invoked (see gradle/kotlin-dsl/issues/1175)
tasks {
compileJava {
doFirst {
jvmArgs = listOf("--module-path", classpath.asPath,
"--add-modules", "javafx.base,javafx.controls,javafx.graphics")
}
}
(run) {
doFirst {
jvmArgs = listOf(
"--module-path", classpath.asPath,
"--add-modules", "javafx.controls"
)
}
}
}
The other answers show how you can use the name, type, or combination to query the container for specific tasks.

Don't use later library version from transitive dependency in Gradle

in my Android project I use
compile 'com.squareup.okhttp:okhttp:2.2.0'
I need okhttp in version 2.2.0 for my code to work properly. But I have a problem when I add
compile('io.intercom.android:intercom-sdk:1.1.2#aar') {
transitive = true
}
Because inside intercom-sdk there is okhttp dependency again for later version:
compile 'com.squareup.okhttp:okhttp:2.4.0'
Which results that my code uses that later version 2.4.0 instead of 2.2.0 I want. Is there please any way how in my module I can use 2.2.0 which I specified and let intercom to use its 2.4.0?
You can use something like this:
compile('io.intercom.android:intercom-sdk:1.1.2#aar') {
exclude group: 'com.squareup.okhttp', module: 'okhttp'
}
However pay attention. If the library uses methods that are not present in the 2.2.0 release, it will fail.
You should define a resolution strategy to set a specific version. This will guarantee you will get the correct version you wish no matter what the transitive dependency versions are:
allProjects {
configurations.all {
resolutionStrategy {
eachDependency { DependencyResolveDetails details ->
if (details.requested.name == 'okhttp') {
details.useTarget('com.squareup.okhttp:okhttp:2.2.0')
}
}
}
}
}
In newer versions of Gradle you can use:
allProjects {
configurations.all {
resolutionStrategy.force 'com.squareup.okhttp:okhttp:2.2.0'
}
}

Resources