From d39c8b7b70c0510c42cb39137084b865806f15fa Mon Sep 17 00:00:00 2001 From: James Fredley Date: Fri, 29 May 2026 16:54:50 -0400 Subject: [PATCH] [Canary] Add Groovy 6 support Adds an early canary groovy-6.0 build variant compiled against org.apache.groovy:groovy:6.0.0-alpha-1, modeled on the Groovy 5 support in #2196 / #2213. The primary goal is to publish a spock-*:2.5-groovy-6.0-SNAPSHOT that the Grails Groovy 6 canary (apache/grails-core#15558) can consume directly, removing the need for the -Dspock.iKnowWhatImDoing.disableGroovyVersionCheck bridge currently used there. Build changes: - gradle.properties: add 6.0 to variantsList - gradle/libs.versions.toml: add groovy6 = 6.0.0-alpha-1 and groovy-v6 alias - build.gradle: add the variant == 6.0 block (min 6.0.0, max 6.9.99, Java 17+ guard) - build-logic SpockBasePlugin: use a JDK 17 compiler for compileJava when variant >= 6.0, because Groovy 6 ships Java 17 (class file v61) bytecode that the pinned JDK 11 javac cannot read; the release level stays at 8, consistent with the other variants. - common.main.kts / release.main.kts: add 6.0 to the CI and publish matrices with Java 17, and regenerate the workflow YAMLs. - allVariants / allVariants.bat: add 6.0. Docs: - README, CONTRIBUTING, and release notes updated for the canary variant. Status: - spock-core and spock-specs compile against Groovy 6.0.0-alpha-1 with no source changes. - The published snapshot bakes minGroovyVersion=6.0.0 / maxGroovyVersion=9.9.99, so the version check accepts Groovy 6 without any bypass flag. - Known issue: 2 GroovySpiesThatAreGlobal specs fail because a global spy on a non-existing property no longer carries the suppressed MissingMethodException under Groovy 6; the MissingPropertyException itself is still thrown correctly. --- .github/codecov.yml | 2 +- .github/workflows/branches-and-prs.yaml | 13 +++++++++++++ .github/workflows/codeql-analysis.yaml | 1 + .github/workflows/common.main.kts | 9 +++++++-- .github/workflows/docs-pr.yaml | 2 +- .github/workflows/release.main.kts | 7 ++++++- .github/workflows/release.yaml | 18 +++++++++++++++++- CONTRIBUTING.adoc | 4 ++-- README.adoc | 8 ++++++-- allVariants | 2 +- allVariants.bat | 2 +- .../gradle/SpockBasePlugin.groovy | 6 +++++- build.gradle | 11 +++++++++++ docs/release_notes.adoc | 1 + gradle.properties | 2 +- gradle/libs.versions.toml | 2 ++ 16 files changed, 76 insertions(+), 14 deletions(-) diff --git a/.github/codecov.yml b/.github/codecov.yml index 358f7b767b..b904cb2c19 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -3,4 +3,4 @@ codecov: comment: layout: "reach, diff, flags, files" - after_n_builds: 24 + after_n_builds: 29 diff --git a/.github/workflows/branches-and-prs.yaml b/.github/workflows/branches-and-prs.yaml index 519640c84f..bca63c6aea 100644 --- a/.github/workflows/branches-and-prs.yaml +++ b/.github/workflows/branches-and-prs.yaml @@ -57,6 +57,7 @@ jobs: - '3.0' - '4.0' - '5.0' + - '6.0' java: - '8' - '11' @@ -78,6 +79,12 @@ jobs: - variant: '5.0' java: '8' os: 'ubuntu-latest' + - variant: '6.0' + java: '8' + os: 'ubuntu-latest' + - variant: '6.0' + java: '11' + os: 'ubuntu-latest' include: - variant: '2.5' java: '8' @@ -91,6 +98,9 @@ jobs: - variant: '5.0' java: '11' os: 'windows-latest' + - variant: '6.0' + java: '17' + os: 'windows-latest' - variant: '2.5' java: '8' os: 'macos-latest' @@ -103,6 +113,9 @@ jobs: - variant: '5.0' java: '11' os: 'macos-latest' + - variant: '6.0' + java: '17' + os: 'macos-latest' steps: - id: 'step-0' name: 'Checkout Repository' diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 11cf36164c..e59b1a2ae1 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -41,6 +41,7 @@ jobs: - '3.0' - '4.0' - '5.0' + - '6.0' steps: - id: 'step-0' name: 'Checkout Repository' diff --git a/.github/workflows/common.main.kts b/.github/workflows/common.main.kts index 96f5b9f8cb..a1b2c5ecc2 100755 --- a/.github/workflows/common.main.kts +++ b/.github/workflows/common.main.kts @@ -141,7 +141,8 @@ val Matrix.Companion.full javaVersions = axes.javaVersions + axes.additionalJavaTestVersions, exclude = { ((variant == "2.5") && (javaVersion!!.toInt() >= 17)) || - ((variant == "5.0") && (javaVersion!!.toInt() < 11)) + ((variant == "5.0") && (javaVersion!!.toInt() < 11)) || + ((variant == "6.0") && (javaVersion!!.toInt() < 17)) }, includes = listOf("windows-latest", "macos-latest") .map { Matrix.Element(operatingSystem = it) } @@ -149,7 +150,11 @@ val Matrix.Companion.full axes.variants.map { element.copy( variant = it, - javaVersion = if (it == "5.0") "11" else axes.javaVersions.first() + javaVersion = when (it) { + "5.0" -> "11" + "6.0" -> "17" + else -> axes.javaVersions.first() + } ) } } diff --git a/.github/workflows/docs-pr.yaml b/.github/workflows/docs-pr.yaml index ee37eb4db5..fe34accb3b 100644 --- a/.github/workflows/docs-pr.yaml +++ b/.github/workflows/docs-pr.yaml @@ -48,7 +48,7 @@ jobs: run: 'sudo apt update && sudo apt install --yes graphviz' - id: 'step-3' name: 'Build Docs' - run: './gradlew --stacktrace asciidoctor asciidoctorMarkdown javadoc "-Dvariant=5.0" "-DjavaVersion=25"' + run: './gradlew --stacktrace asciidoctor asciidoctorMarkdown javadoc "-Dvariant=6.0" "-DjavaVersion=25"' - id: 'step-4' name: 'Archive and upload docs' uses: 'actions/upload-artifact@v7' diff --git a/.github/workflows/release.main.kts b/.github/workflows/release.main.kts index 48b68a4bd8..83ab38b934 100755 --- a/.github/workflows/release.main.kts +++ b/.github/workflows/release.main.kts @@ -122,13 +122,18 @@ workflow( "strategy" to Strategy( matrix = Matrix( operatingSystems = listOf("ubuntu-latest"), - variants = Matrix.axes.variants.filter { it != "5.0" }, + variants = Matrix.axes.variants.filter { it != "5.0" && it != "6.0" }, javaVersions = Matrix.axes.javaVersions.take(1), includes = listOf( Matrix.Element( variant = "5.0", javaVersion = "11", operatingSystem = "ubuntu-latest" + ), + Matrix.Element( + variant = "6.0", + javaVersion = "17", + operatingSystem = "ubuntu-latest" ) ) ) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e54b816621..143e876621 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -37,6 +37,7 @@ jobs: - '3.0' - '4.0' - '5.0' + - '6.0' java: - '8' - '11' @@ -58,6 +59,12 @@ jobs: - variant: '5.0' java: '8' os: 'ubuntu-latest' + - variant: '6.0' + java: '8' + os: 'ubuntu-latest' + - variant: '6.0' + java: '11' + os: 'ubuntu-latest' include: - variant: '2.5' java: '8' @@ -71,6 +78,9 @@ jobs: - variant: '5.0' java: '11' os: 'windows-latest' + - variant: '6.0' + java: '17' + os: 'windows-latest' - variant: '2.5' java: '8' os: 'macos-latest' @@ -83,6 +93,9 @@ jobs: - variant: '5.0' java: '11' os: 'macos-latest' + - variant: '6.0' + java: '17' + os: 'macos-latest' steps: - id: 'step-0' name: 'Checkout Repository' @@ -128,6 +141,9 @@ jobs: - variant: '5.0' java: '11' os: 'ubuntu-latest' + - variant: '6.0' + java: '17' + os: 'ubuntu-latest' steps: - id: 'step-0' name: 'Checkout Repository' @@ -155,7 +171,7 @@ jobs: strategy: matrix: variant: - - '5.0' + - '6.0' java: - '25' os: diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc index ea74ac3eb6..87e9924d43 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -164,9 +164,9 @@ To generate an IDEA project configuration: * `File -> Open` in Intellij, then * select the appropriate `spock-2.5.ipr`. -NOTE: You can provide an optional 'variant' flag to the gradle build `-Dvariant=[2.5|3.0|4.0]` that specifies the version of groovy you wish to use. +NOTE: You can provide an optional 'variant' flag to the gradle build `-Dvariant=[2.5|3.0|4.0|5.0|6.0]` that specifies the version of groovy you wish to use. For example, if we wish to use groovy 3.0, we would run `./gradlew cleanIdea idea -Dvariant=3.0` and import the generated `spock-3.0.ipr` into Intellij. -You can also use the helper script `allVariants`, e.g., `./allVariants idea`, which will create or update the project for all three variants. +You can also use the helper script `allVariants`, e.g., `./allVariants idea`, which will create or update the project for all variants. This should result in a fully functional IDE setup where: diff --git a/README.adoc b/README.adoc index 648cb371c3..74c8e14037 100644 --- a/README.adoc +++ b/README.adoc @@ -30,7 +30,9 @@ https://groovyconsole.dev/[Groovy Web Console]. {spock-release-version}-groovy-3.0, {spock-release-version}-groovy-4.0, {spock-release-version}-groovy-5.0), released on {spock-release-date}. * The current development version is *{spock-snapshot-version}-SNAPSHOT* ({spock-snapshot-version}-groovy-2.5-SNAPSHOT, {spock-snapshot-version}-groovy-3.0-SNAPSHOT, -{spock-snapshot-version}-groovy-4.0-SNAPSHOT), {spock-snapshot-version}-groovy-5.0-SNAPSHOT). +{spock-snapshot-version}-groovy-4.0-SNAPSHOT, {spock-snapshot-version}-groovy-5.0-SNAPSHOT, +{spock-snapshot-version}-groovy-6.0-SNAPSHOT). +* The Groovy 6.0 variant is an early _canary_ build against `org.apache.groovy:groovy:6.0.0-alpha-1` and requires Java 17+. *NOTE:* Spock 2.x is based on the JUnit Platform and requires Java 8+/groovy-2.5+ (Groovy 3.0 or newer is recommended, especially in projects using @@ -116,13 +118,15 @@ variable if they are not in standard places recognized by Gradle, e.g. `JDK11=/p Spock is supported for Java version 8+. Spock is supported for Groovy versions 2.5, 3.0, 4.0, and 5.0. +Groovy 6.0 is additionally available as an early _canary_ variant (built against `6.0.0-alpha-1`). The tests are testing Spock with the specific versions (variants) of Groovy and Java. Default Groovy version is 2.5. The Groovy 3.0 and 4.0 variant should pass on all supported JDK versions, Groovy 2.5 does not work with Java 17+: -Groovy 5.0 and newer does not work with Java <11: +Groovy 5.0 does not work with Java <11: +Groovy 6.0 does not work with Java <17: .... ./gradlew build diff --git a/allVariants b/allVariants index 1c01d235da..6315ac46ae 100755 --- a/allVariants +++ b/allVariants @@ -1,4 +1,4 @@ #!/bin/sh -for var in 2.5 3.0 4.0 5.0; do +for var in 2.5 3.0 4.0 5.0 6.0; do ./gradlew -Dvariant="$var" "$@" done diff --git a/allVariants.bat b/allVariants.bat index cd6d1ef905..dac2c3945b 100644 --- a/allVariants.bat +++ b/allVariants.bat @@ -1,4 +1,4 @@ @echo off -for %%v in (2.5 3.0 4.0 5.0) do ( +for %%v in (2.5 3.0 4.0 5.0 6.0) do ( gradlew.bat -Dvariant=%%v %* ) diff --git a/build-logic/base/src/main/groovy/org/spockframework/gradle/SpockBasePlugin.groovy b/build-logic/base/src/main/groovy/org/spockframework/gradle/SpockBasePlugin.groovy index 42bb24345a..e5232c2fb0 100644 --- a/build-logic/base/src/main/groovy/org/spockframework/gradle/SpockBasePlugin.groovy +++ b/build-logic/base/src/main/groovy/org/spockframework/gradle/SpockBasePlugin.groovy @@ -61,10 +61,14 @@ class SpockBasePlugin implements Plugin { private static void compileTasks(Project project) { project.with { def javaToolchains = extensions.getByType(JavaToolchainService) + def variant = rootProject.extensions.getByType(ExtraPropertiesExtension).get("variant") as BigDecimal + // Groovy 6+ is compiled for Java 17 bytecode, so the Java compiler used to read the Groovy + // classes during `compileJava` must be at least Java 17. Older variants keep the Java 11 compiler. + def compilerVersion = variant >= 6.0g ? JavaLanguageVersion.of(17) : COMPILER_VERSION tasks.withType(JavaCompile).configureEach { comp -> if (comp.name == JavaPlugin.COMPILE_JAVA_TASK_NAME) { comp.javaCompiler.set(javaToolchains.compilerFor { - it.languageVersion.set(COMPILER_VERSION) + it.languageVersion.set(compilerVersion) }) comp.options.release.set(COMPILER_RELEASE_VERSION) } diff --git a/build.gradle b/build.gradle index 35071438f1..395457bc37 100644 --- a/build.gradle +++ b/build.gradle @@ -53,6 +53,17 @@ ext { } javaVersion = 11 } + } else if (variant == 6.0) { + groovyGroup = "org.apache.groovy" + groovyVersion = libs.versions.groovy6.get() + minGroovyVersion = "6.0.0" + maxGroovyVersion = "6.9.99" + if (javaVersion < 17) { + if (System.getProperty("javaVersion") != null) { + throw new InvalidUserDataException("Groovy $variant is not compatible with Java $javaVersion") + } + javaVersion = 17 + } } else { throw new InvalidUserDataException("Unknown variant: $variant. Choose one of: $variants") } diff --git a/docs/release_notes.adoc b/docs/release_notes.adoc index 66acbc5fef..07ef8dc9c9 100644 --- a/docs/release_notes.adoc +++ b/docs/release_notes.adoc @@ -9,6 +9,7 @@ include::include.adoc[] === Enhancements * Improve `TooManyInvocationsError` now reports unsatisfied interactions with argument mismatch details, making it easier to diagnose why invocations didn't match expected interactions spockPull:2315[] +* Add an early _canary_ `groovy-6.0` variant built against `org.apache.groovy:groovy:6.0.0-alpha-1` (requires Java 17+) === Misc diff --git a/gradle.properties b/gradle.properties index 4a5fc43dd6..c68d42e740 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,5 +22,5 @@ org.gradle.caching=true javaVersionsList=8, 11, 17, 21, 25 additionalJavaTestVersionsList= -variantsList=2.5, 3.0, 4.0, 5.0 +variantsList=2.5, 3.0, 4.0, 5.0, 6.0 kotlin.code.style=official diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4903b73e2e..2842971e01 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,6 +4,7 @@ groovy2 = '2.5.23' groovy3 = '3.0.25' groovy4 = '4.0.32' groovy5 = '5.0.6' +groovy6 = '6.0.0-alpha-1' jacoco = '0.8.14' junit5 = '5.14.4' junit6 = '6.1.0' @@ -50,3 +51,4 @@ groovy-v2 = { module = "org.codehaus.groovy:groovy", version.ref="groovy2" } groovy-v3 = { module = "org.codehaus.groovy:groovy", version.ref="groovy3" } groovy-v4 = { module = "org.apache.groovy:groovy", version.ref="groovy4" } groovy-v5 = { module = "org.apache.groovy:groovy", version.ref="groovy5" } +groovy-v6 = { module = "org.apache.groovy:groovy", version.ref="groovy6" }