ResolutionStrategy for Gradle SNAPSHOT plugins - gradle

I have this pluginManagement section in my settings.gradle:
pluginManagement {
plugins {
id "org.springframework.boot" version "3.0.0-SNAPSHOT"
id "org.springframework.boot.aot" version "3.0.0-SNAPSHOT"
}
}
Gradle will now check for every subproject in the configuring phase if there's a new version of the org.springframework.boot and org.springframework.boot.aot plugin, presumably because they have SNAPSHOT versions.
Is there a way to set the resolutionStrategy for plugins to say, only check every 24 hours for a new version?
I currently have this workaround:
// This is needed to prevent gradle from checking for newer versions of the Spring Boot
// plugin on every build in every sub-project
buildscript {
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:3.0.0-SNAPSHOT")
}
configurations.classpath {
resolutionStrategy {
cacheDynamicVersionsFor 24, 'hours'
cacheChangingModulesFor 24, 'hours'
}
}
}

Related

How to setup a multi-module gradle project with Quarkus?

A multi-module gradle project with the Quarkus plugin applied in the root build.gradle.kts fails at the :quarkusBuild step with a NoSuchElementException:
> Task :quarkusBuild FAILED
building quarkus jar
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':quarkusBuild'.
> java.util.NoSuchElementException
The root build.gradle.kts is like so:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.3.72"
id("io.quarkus") version "1.9.1.Final"
}
group = "org.example"
version = "1.0-SNAPSHOT"
allprojects {
repositories {
mavenCentral()
}
}
subprojects {
apply {
plugin("kotlin")
}
dependencies {
implementation(kotlin("stdlib"))
}
}
However move the line id("io.quarkus") version "1.9.1.Final" to the sub projects' build.gradle.kts and the build succeeds. It seems that the quarkus build step is run where the plugin is declared, rather than where it is actually applied.
Ideally I want to declare the plugin once in the root, then apply it to subprojects only, not have it execute against the root project, where there's obviously nothing to build.
Any ideas?
You need to add apply false
plugins {
kotlin("jvm") version "1.3.72" apply false
id("io.quarkus") version "1.9.1.Final" apply false
}
https://docs.gradle.org/current/userguide/plugins.html#sec:subprojects_plugins_dsl
Your build also assumes that every sub-module will be a Kotlin module which may or may not be true. You can do something a little more like this to apply specific configurations to specific tasks:
subprojects { subproject ->
subproject.tasks.withType(JavaCompile).configureEach {
sourceCompatibility = JavaVersion.VERSION_11
}
subproject.tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11
}
}
}

Gradle plugin with custom group id

Gradle 6.1
I am having difficulties to use the new plugin configuration mode in Gradle with a custom plugin coming from a custom repository.
buildscript {
repositories {
maven {
url = uri("https://custom")
}
mavenCentral()
jcenter()
maven {
url = uri("https://plugins.gradle.org/m2/")
}
}
}
plugins {
java
idea
id("com.custom.gradle.plugin.myplugin") version "1.1.0"
}
I get this error:
Plugin [id: 'com.custom.gradle.plugin.myplugin', version: '1.1.0'] was not found in any of the following sources:
- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'com.custom.gradle.plugin.myplugin:com.custom.gradle.plugin.myplugin:1.1.0')
Searched in the following repositories:
Gradle Central Plugin Repository
Gradle will use the plugin id as its group id.
It works if I use the old ways:
buildscript {
repositories {
maven {
url = uri("https://custom")
}
mavenCentral()
jcenter()
maven {
url = uri("https://plugins.gradle.org/m2/")
}
}
dependencies {
classpath("com.custom:com.custom.gradle.plugin.myplugin:1.1.0")
}
}
apply(plugin = "com.custom.gradle.plugin.myplugin")
Is there a way to specify the group id with the 'id' command? Or am I breaking the plugin definition's contract with that old plugin?
In order to use the newer/preferred plugins { } DSL, the custom plugin must publish a plugin marker artifact.
If the custom plugin is able to be modified, then I suggest updating to make use of the Java Gradle Plugin Development plugin which will create the marker for you.
If the plugin is not able to be updated, then you can still use the plugins { } block, but you'll need to manually resolve the plugin:
In the main build.gradle:
plugins {
id("com.custom.gradle.plugin.myplugin") version "1.1.0"
}
Then resolve the plugin manually in settings.gradle:
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.id == "com.custom.gradle.plugin.myplugin") {
useModule("com.custom:com.custom.gradle.plugin.myplugin:${requested.version}")
}
}
}
}
See Plugin Resolution Rules
for more details.

How do I use the native JUnit 5 support in Gradle with the Kotlin DSL?

I want to use the built-in JUnit 5 with the Gradle Kotlin DSL, because during build I get this warning:
WARNING: The junit-platform-gradle-plugin is deprecated and will be discontinued in JUnit Platform 1.3.
Please use Gradle's native support for running tests on the JUnit Platform (requires Gradle 4.6 or higher):
https://junit.org/junit5/docs/current/user-guide/#running-tests-build-gradle
That links tells me to put
test {
useJUnitPlatform()
}
in my build.gradle, but what is the syntax for build.gradle.kts?
My current build file is
import org.gradle.api.plugins.ExtensionAware
import org.junit.platform.gradle.plugin.FiltersExtension
import org.junit.platform.gradle.plugin.EnginesExtension
import org.junit.platform.gradle.plugin.JUnitPlatformExtension
group = "com.example"
version = "0.0"
// JUnit 5
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath("org.junit.platform:junit-platform-gradle-plugin:1.2.0")
}
}
apply {
plugin("org.junit.platform.gradle.plugin")
}
// Kotlin configuration.
plugins {
val kotlinVersion = "1.2.41"
application
kotlin("jvm") version kotlinVersion
java // Required by at least JUnit.
// Plugin which checks for dependency updates with help/dependencyUpdates task.
id("com.github.ben-manes.versions") version "0.17.0"
// Plugin which can update Gradle dependencies, use help/useLatestVersions
id("se.patrikerdes.use-latest-versions") version "0.2.1"
}
application {
mainClassName = "com.example.HelloWorld"
}
dependencies {
compile(kotlin("stdlib"))
// To "prevent strange errors".
compile(kotlin("reflect"))
// Kotlin reflection.
compile(kotlin("test"))
compile(kotlin("test-junit"))
// JUnit 5
testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
testRuntime("org.junit.platform:junit-platform-console:1.2.0")
// Kotlintest
testCompile("io.kotlintest:kotlintest-core:3.1.0-RC2")
testCompile("io.kotlintest:kotlintest-assertions:3.1.0-RC2")
testCompile("io.kotlintest:kotlintest-runner-junit5:3.1.0-RC2")
}
repositories {
mavenCentral()
mavenLocal()
jcenter()
}
(The following is some blabla because this question 'contains mostly code').
I tried to find documentation on how to customize tasks in the Kotlin DSL, but I couldn't find any. In normal Groovy you can just write the name of the task and then change things in the block, but the Kotlin DSL doesn't recognise the task as such, unresolved reference.
Also, this question is related but asks for creating of new tasks, instead of customize existing tasks: How do I overwrite a task in gradle kotlin-dsl
Here is a solution for normal Gradle.
[Edit april 2019] As Pedro has found, three months after I asked this question Gradle actually created a user guide for the Kotlin DSL which can be visited at https://docs.gradle.org/current/userguide/kotlin_dsl.html
They also added a migration guide from Groovy to Kotlin at https://guides.gradle.org/migrating-build-logic-from-groovy-to-kotlin/
Answer:
The syntax you ask for is
tasks.test {
// Use the built-in JUnit support of Gradle.
useJUnitPlatform()
}
which I figured out from this example file from the Kotlin DSL GitHub, or you can use
tasks.withType<Test> {
useJUnitPlatform()
}
which is used in the this official userguide which was created a couple of months after this answer was written (thanks to Pedro's answer for noting this).
But in any case you actually are still using the buildscript block, which is a bit deprecated itself, use the new plugins DSL instead (docs). New build.gradle.kts becomes
group = "com.example"
version = "0.0"
plugins {
val kotlinVersion = "1.2.41"
application
kotlin("jvm") version kotlinVersion
java // Required by at least JUnit.
// Plugin which checks for dependency updates with help/dependencyUpdates task.
id("com.github.ben-manes.versions") version "0.17.0"
// Plugin which can update Gradle dependencies, use help/useLatestVersions
id("se.patrikerdes.use-latest-versions") version "0.2.1"
}
application {
mainClassName = "com.example.HelloWorld"
}
dependencies {
compile(kotlin("stdlib"))
// To "prevent strange errors".
compile(kotlin("reflect"))
// Kotlin reflection.
compile(kotlin("test"))
compile(kotlin("test-junit"))
// JUnit 5
testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
testRuntime("org.junit.platform:junit-platform-console:1.2.0")
// Kotlintest
testCompile("io.kotlintest:kotlintest-core:3.1.0-RC2")
testCompile("io.kotlintest:kotlintest-assertions:3.1.0-RC2")
testCompile("io.kotlintest:kotlintest-runner-junit5:3.1.0-RC2")
}
repositories {
mavenCentral()
mavenLocal()
jcenter()
}
tasks {
// Use the native JUnit support of Gradle.
"test"(Test::class) {
useJUnitPlatform()
}
}
(Since the Gradle Kotlin DSL has almost no documentation at all except a few (undocumented) example files on GitHub, I'm documenting a few common examples here.)
(Complete example project at GitHub, self-promotion...)
Adding on top of accepted answer, it is also possible to use typed task configuration like:
tasks.withType<Test> {
useJUnitPlatform()
}
Update:
Gradle docs for reference here. Specifically Example 19 which has:
tasks.withType<JavaCompile> {
options.isWarnings = true
// ...
}
this worked for me till now...
plugins {
kotlin("jvm") version "1.7.10"
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
testImplementation(kotlin("test"))
testImplementation("org.junit.jupiter:junit-jupiter:5.9.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.0")
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}

Gradle: manage dependency/plugin versions in multi-project builds

I was working with Maven before Gradle and Maven has such things like dependencyManagement and pluginManagement what allows to keep all versions "DRY" in one place with help of "properties".
Gradle supports project properties, so I can declare versions like:
buildscript {
ext.kotlin_version = '1.1.61'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
But this approach cannot be applied to plugins {} DSL. I cannot write something like this:
plugins {
id 'org.jetbrains.kotlin:kotlin-gradle-plugin' version $kotlin_version
}
As according to docs:
values must be literal (e.g. constant strings, not variables)
Is there a way to workaround this limitation?
The latest versions of Gradle allows you to define your versions in a property file, map that version in a pluginManagement block, and then omit the version from all downstream plugin blocks. The pluginManagement block does not have the only-constant restriction.
In fact, once you use this approach, it is a compile time error to even try to declare a version downstream.
After using this approach, there is a good chance you can completely omit your buildscript.
gradle.properties
kotlinVersion=1.3.50
settings.gradle
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.id == "org.jetbrains.kotlin.jvm") {
useVersion(kotlinVersion)
}
}
}
}
build.gradle
plugins {
id("org.jetbrains.kotlin.jvm")
}
If you are into kotlinscript, get your version from a delegate:
settings.gradle.kts
val kotlinVersion: String by settings
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.id == "org.jetbrains.kotlin.jvm") {
useVersion(kotlinVersion)
}
}
}
}
Of course, you do not need the properties file. You can just hard code the version in your gradle.settings. But by having the property, you can then declare dependencies to the stdlib using it.
I think you can put the ext closure in a separate properties.gradle, and then reference the properties twice in buildscript as well as project build (buildscript block is evaluated at the very beginning, before any other part of groovy script).
For example, in $projectRoot/gradle/properties.gradle as below:
ext {
kotlinVersion = '1.1.61' // NOTE, the naming convention is better with kotlinVersion instead of kotlin_version
}
And your $projectRoot/build.gradle would look like this:
buildscript {
apply from: "gradle/properties.gradle"
repositories {
jcenter()
}
dependencies {
println "In buildscript, kotlinVersion is $kotlinVersion"
}
}
apply plugin: 'java'
apply from: "gradle/properties.gradle"
repositories {
jcenter()
}
dependencies {
println "In project, kotlinVersion is $kotlinVersion"
}
When you run ./gradlew dependencies, it would show you the populated versions:
> Configure project :
In buildscript, kotlinVersion is 1.1.61
In project, kotlinVersion is 1.1.61

How can I force a gradle build to re-download a SNAPSHOT plugin from Maven repository on every build

As shown below, I have a gradle plugin that is built deployed as a SNAPSHOT version in a maven repository.
I am aware that -SNAPSHOT dependencies should automatically be recognised as changing=true
I also know that the resolutionStrategy should allow forcing a new download for all configurations.
However, in this context, the setting has no effect.
Question: Can you provide a corrected sample, based on the one below, that forces a re-download on every run, or explain how such a configuration can be achieved?
buildscript {
repositories { maven { url "http://moomoomoo.com:8081/artifactory/moomoomoo-plugins" } }
dependencies { classpath 'com.moomoomoo:moomootools:1.3-SNAPSHOT' }
}
configurations.all { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' }
apply plugin: 'com.moomoomoo.moomootool'
To configure the resolution strategy of the classpath configuration for the build script you have to configure it inside the buildscript block:
buildscript {
repositories { maven { url "http://moomoomoo.com:8081/artifactory/moomoomoo-plugins" } }
configurations.all { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' }
dependencies { classpath 'com.moomoomoo:moomootools:1.3-SNAPSHOT' }
}
apply plugin: 'com.moomoomoo.moomootool'

Resources