diff --git a/rewrite-gradle-tooling-model/model/src/main/java/org/openrewrite/gradle/toolingapi/OpenRewriteModelBuilder.java b/rewrite-gradle-tooling-model/model/src/main/java/org/openrewrite/gradle/toolingapi/OpenRewriteModelBuilder.java index 29c07b01777..ea12707f5c8 100644 --- a/rewrite-gradle-tooling-model/model/src/main/java/org/openrewrite/gradle/toolingapi/OpenRewriteModelBuilder.java +++ b/rewrite-gradle-tooling-model/model/src/main/java/org/openrewrite/gradle/toolingapi/OpenRewriteModelBuilder.java @@ -29,6 +29,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.List; @@ -77,12 +78,13 @@ public static OpenRewriteModel forProjectDirectory(File projectDir, @Nullable Fi */ public static OpenRewriteModel forProjectDirectory(File projectDir, @Nullable File buildFile, @Nullable String initScript) throws IOException { DefaultGradleConnector connector = (DefaultGradleConnector) GradleConnector.newConnector(); - if (System.getProperty("org.openrewrite.test.gradleVersion") != null) { - connector.useGradleVersion(System.getProperty("org.openrewrite.test.gradleVersion")); - } else if (Files.exists(projectDir.toPath().resolve("gradle/wrapper/gradle-wrapper.properties"))) { + String gradleVersion; + if (Files.exists(projectDir.toPath().resolve("gradle/wrapper/gradle-wrapper.properties"))) { + gradleVersion = wrapperGradleVersion(projectDir.toPath().resolve("gradle/wrapper/gradle-wrapper.properties")); connector.useBuildDistribution(); } else { - connector.useGradleVersion(defaultGradleVersion()); + gradleVersion = System.getProperty("org.openrewrite.test.gradleVersion", "8.14.3"); + connector.useGradleVersion(gradleVersion); } connector // Uncomment to hit breakpoints inside OpenRewriteModelBuilder in unit tests @@ -90,74 +92,98 @@ public static OpenRewriteModel forProjectDirectory(File projectDir, @Nullable Fi // .embedded(true) .forProjectDirectory(projectDir); List arguments = new ArrayList<>(); - if (buildFile != null && buildFile.exists()) { - arguments.add("-b"); - arguments.add(buildFile.getAbsolutePath()); - } arguments.add("--init-script"); Path init = projectDir.toPath().resolve("openrewrite-tooling.gradle").toAbsolutePath(); arguments.add(init.toString()); + Path settings = null; + boolean settingsWritten = false; + if (buildFile != null && buildFile.exists()) { + if (isGradle9OrLater(gradleVersion)) { + // Gradle 9 dropped -b; for non-conventional build files write a temporary settings.gradle with rootProject.buildFileName. + File abs = buildFile.getAbsoluteFile(); + boolean atConventionalLocation = abs.equals(new File(projectDir, "build.gradle").getAbsoluteFile()) || + abs.equals(new File(projectDir, "build.gradle.kts").getAbsoluteFile()); + if (!atConventionalLocation) { + Path projectPath = projectDir.toPath(); + if (!Files.exists(projectPath.resolve("settings.gradle")) && + !Files.exists(projectPath.resolve("settings.gradle.kts"))) { + settings = projectPath.resolve("settings.gradle"); + Files.write(settings, ("rootProject.buildFileName = '" + buildFile.getName() + "'\n").getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW); + settingsWritten = true; + } + } + } else { + arguments.add("-b"); + arguments.add(buildFile.getAbsolutePath()); + } + } try (ProjectConnection connection = connector.connect()) { ModelBuilder customModelBuilder = connection.model(OpenRewriteModelProxy.class); - try { - if (initScript == null) { - if (System.getProperty("org.openrewrite.gradle.local.use-embedded-classpath") != null) { - // code path only expected to be taken from within openrewrite/rewrite - String generatedInitScript = generateInitScriptFromManifest(); - Files.write(init, generatedInitScript.getBytes(StandardCharsets.UTF_8)); - } else { - // Use default init.gradle from resources - try (InputStream is = OpenRewriteModel.class.getResourceAsStream("/init.gradle")) { - if (is == null) { - throw new IllegalStateException("Expected to find init.gradle on the classpath"); - } - Files.copy(is, init); + if (initScript == null) { + if (System.getProperty("org.openrewrite.gradle.local.use-embedded-classpath") != null) { + // code path only expected to be taken from within openrewrite/rewrite + String generatedInitScript = generateInitScriptFromManifest(); + Files.write(init, generatedInitScript.getBytes(StandardCharsets.UTF_8)); + } else { + // Use default init.gradle from resources + try (InputStream is = OpenRewriteModel.class.getResourceAsStream("/init.gradle")) { + if (is == null) { + throw new IllegalStateException("Expected to find init.gradle on the classpath"); } + Files.copy(is, init); } - } else { - Files.write(init, initScript.getBytes()); } - customModelBuilder.withArguments(arguments); - return OpenRewriteModel.from(customModelBuilder.get()); - } finally { - try { - if (Files.exists(init)) { - Files.delete(init); - } - } catch (IOException e) { - //noinspection ThrowFromFinallyBlock - throw new UncheckedIOException(e); + } else { + Files.write(init, initScript.getBytes()); + } + customModelBuilder.withArguments(arguments); + return OpenRewriteModel.from(customModelBuilder.get()); + } finally { + try { + if (Files.exists(init)) { + Files.delete(init); + } + if (settingsWritten) { + Files.deleteIfExists(settings); } + } catch (IOException e) { + //noinspection ThrowFromFinallyBlock + throw new UncheckedIOException(e); } } } - /** - * Pick a Gradle distribution compatible with the JVM running the Tooling API client. - * The daemon defaults to the same JVM as the client, so the chosen distribution must support that Java version. - * See Gradle compatibility matrix. - */ - static String defaultGradleVersion() { - return defaultGradleVersion(javaSpecificationVersion()); - } - - static String defaultGradleVersion(int javaFeatureVersion) { - if (javaFeatureVersion >= 25) { - return "9.1.0"; + private static boolean isGradle9OrLater(@Nullable String version) { + if (version == null) { + return false; + } + int dot = version.indexOf('.'); + try { + return Integer.parseInt(dot < 0 ? version : version.substring(0, dot)) >= 9; + } catch (NumberFormatException e) { + return false; } - return "8.14.3"; } - private static int javaSpecificationVersion() { - String version = System.getProperty("java.specification.version", "8"); - if (version.startsWith("1.")) { - version = version.substring(2); - } + private static @Nullable String wrapperGradleVersion(Path wrapperProperties) { try { - return Integer.parseInt(version); - } catch (NumberFormatException e) { - return 8; + for (String line : Files.readAllLines(wrapperProperties, StandardCharsets.UTF_8)) { + if (line.startsWith("distributionUrl=")) { + int idx = line.lastIndexOf("gradle-"); + if (idx < 0) { + return null; + } + int start = idx + "gradle-".length(); + int end = start; + while (end < line.length() && (Character.isDigit(line.charAt(end)) || line.charAt(end) == '.')) { + end++; + } + return end > start ? line.substring(start, end) : null; + } + } + } catch (IOException ignored) { } + return null; } /** diff --git a/rewrite-gradle-tooling-model/model/src/test/java/org/openrewrite/gradle/toolingapi/OpenRewriteModelBuilderTest.java b/rewrite-gradle-tooling-model/model/src/test/java/org/openrewrite/gradle/toolingapi/OpenRewriteModelBuilderTest.java deleted file mode 100644 index 9659a60609a..00000000000 --- a/rewrite-gradle-tooling-model/model/src/test/java/org/openrewrite/gradle/toolingapi/OpenRewriteModelBuilderTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2026 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.openrewrite.gradle.toolingapi; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class OpenRewriteModelBuilderTest { - - @Test - void java8UsesGradle814() { - assertThat(OpenRewriteModelBuilder.defaultGradleVersion(8)).isEqualTo("8.14.3"); - } - - @Test - void java24UsesGradle814() { - assertThat(OpenRewriteModelBuilder.defaultGradleVersion(24)).isEqualTo("8.14.3"); - } - - @Test - void java25RequiresGradle91() { - assertThat(OpenRewriteModelBuilder.defaultGradleVersion(25)).isEqualTo("9.1.0"); - } - - @Test - void futureJavaVersionsResolveToLatestKnownDistribution() { - assertThat(OpenRewriteModelBuilder.defaultGradleVersion(99)).isEqualTo("9.1.0"); - } -}