|
29 | 29 | import java.nio.file.Files; |
30 | 30 | import java.nio.file.Path; |
31 | 31 | import java.nio.file.Paths; |
| 32 | +import java.nio.file.StandardOpenOption; |
32 | 33 | import java.util.ArrayList; |
33 | 34 | import java.util.List; |
34 | 35 |
|
@@ -77,87 +78,112 @@ public static OpenRewriteModel forProjectDirectory(File projectDir, @Nullable Fi |
77 | 78 | */ |
78 | 79 | public static OpenRewriteModel forProjectDirectory(File projectDir, @Nullable File buildFile, @Nullable String initScript) throws IOException { |
79 | 80 | DefaultGradleConnector connector = (DefaultGradleConnector) GradleConnector.newConnector(); |
80 | | - if (System.getProperty("org.openrewrite.test.gradleVersion") != null) { |
81 | | - connector.useGradleVersion(System.getProperty("org.openrewrite.test.gradleVersion")); |
82 | | - } else if (Files.exists(projectDir.toPath().resolve("gradle/wrapper/gradle-wrapper.properties"))) { |
| 81 | + String gradleVersion; |
| 82 | + if (Files.exists(projectDir.toPath().resolve("gradle/wrapper/gradle-wrapper.properties"))) { |
| 83 | + gradleVersion = wrapperGradleVersion(projectDir.toPath().resolve("gradle/wrapper/gradle-wrapper.properties")); |
83 | 84 | connector.useBuildDistribution(); |
84 | 85 | } else { |
85 | | - connector.useGradleVersion(defaultGradleVersion()); |
| 86 | + gradleVersion = System.getProperty("org.openrewrite.test.gradleVersion", "8.14.3"); |
| 87 | + connector.useGradleVersion(gradleVersion); |
86 | 88 | } |
87 | 89 | connector |
88 | 90 | // Uncomment to hit breakpoints inside OpenRewriteModelBuilder in unit tests |
89 | 91 | // Leaving commented out because the exact consequences of this internal API are unclear |
90 | 92 | // .embedded(true) |
91 | 93 | .forProjectDirectory(projectDir); |
92 | 94 | List<String> arguments = new ArrayList<>(); |
93 | | - if (buildFile != null && buildFile.exists()) { |
94 | | - arguments.add("-b"); |
95 | | - arguments.add(buildFile.getAbsolutePath()); |
96 | | - } |
97 | 95 | arguments.add("--init-script"); |
98 | 96 | Path init = projectDir.toPath().resolve("openrewrite-tooling.gradle").toAbsolutePath(); |
99 | 97 | arguments.add(init.toString()); |
| 98 | + Path settings = null; |
| 99 | + boolean settingsWritten = false; |
| 100 | + if (buildFile != null && buildFile.exists()) { |
| 101 | + if (isGradle9OrLater(gradleVersion)) { |
| 102 | + // Gradle 9 dropped -b; for non-conventional build files write a temporary settings.gradle with rootProject.buildFileName. |
| 103 | + File abs = buildFile.getAbsoluteFile(); |
| 104 | + boolean atConventionalLocation = abs.equals(new File(projectDir, "build.gradle").getAbsoluteFile()) || |
| 105 | + abs.equals(new File(projectDir, "build.gradle.kts").getAbsoluteFile()); |
| 106 | + if (!atConventionalLocation) { |
| 107 | + Path projectPath = projectDir.toPath(); |
| 108 | + if (!Files.exists(projectPath.resolve("settings.gradle")) && |
| 109 | + !Files.exists(projectPath.resolve("settings.gradle.kts"))) { |
| 110 | + settings = projectPath.resolve("settings.gradle"); |
| 111 | + Files.write(settings, ("rootProject.buildFileName = '" + buildFile.getName() + "'\n").getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW); |
| 112 | + settingsWritten = true; |
| 113 | + } |
| 114 | + } |
| 115 | + } else { |
| 116 | + arguments.add("-b"); |
| 117 | + arguments.add(buildFile.getAbsolutePath()); |
| 118 | + } |
| 119 | + } |
100 | 120 | try (ProjectConnection connection = connector.connect()) { |
101 | 121 | ModelBuilder<OpenRewriteModelProxy> customModelBuilder = connection.model(OpenRewriteModelProxy.class); |
102 | | - try { |
103 | | - if (initScript == null) { |
104 | | - if (System.getProperty("org.openrewrite.gradle.local.use-embedded-classpath") != null) { |
105 | | - // code path only expected to be taken from within openrewrite/rewrite |
106 | | - String generatedInitScript = generateInitScriptFromManifest(); |
107 | | - Files.write(init, generatedInitScript.getBytes(StandardCharsets.UTF_8)); |
108 | | - } else { |
109 | | - // Use default init.gradle from resources |
110 | | - try (InputStream is = OpenRewriteModel.class.getResourceAsStream("/init.gradle")) { |
111 | | - if (is == null) { |
112 | | - throw new IllegalStateException("Expected to find init.gradle on the classpath"); |
113 | | - } |
114 | | - Files.copy(is, init); |
| 122 | + if (initScript == null) { |
| 123 | + if (System.getProperty("org.openrewrite.gradle.local.use-embedded-classpath") != null) { |
| 124 | + // code path only expected to be taken from within openrewrite/rewrite |
| 125 | + String generatedInitScript = generateInitScriptFromManifest(); |
| 126 | + Files.write(init, generatedInitScript.getBytes(StandardCharsets.UTF_8)); |
| 127 | + } else { |
| 128 | + // Use default init.gradle from resources |
| 129 | + try (InputStream is = OpenRewriteModel.class.getResourceAsStream("/init.gradle")) { |
| 130 | + if (is == null) { |
| 131 | + throw new IllegalStateException("Expected to find init.gradle on the classpath"); |
115 | 132 | } |
| 133 | + Files.copy(is, init); |
116 | 134 | } |
117 | | - } else { |
118 | | - Files.write(init, initScript.getBytes()); |
119 | 135 | } |
120 | | - customModelBuilder.withArguments(arguments); |
121 | | - return OpenRewriteModel.from(customModelBuilder.get()); |
122 | | - } finally { |
123 | | - try { |
124 | | - if (Files.exists(init)) { |
125 | | - Files.delete(init); |
126 | | - } |
127 | | - } catch (IOException e) { |
128 | | - //noinspection ThrowFromFinallyBlock |
129 | | - throw new UncheckedIOException(e); |
| 136 | + } else { |
| 137 | + Files.write(init, initScript.getBytes()); |
| 138 | + } |
| 139 | + customModelBuilder.withArguments(arguments); |
| 140 | + return OpenRewriteModel.from(customModelBuilder.get()); |
| 141 | + } finally { |
| 142 | + try { |
| 143 | + if (Files.exists(init)) { |
| 144 | + Files.delete(init); |
| 145 | + } |
| 146 | + if (settingsWritten) { |
| 147 | + Files.deleteIfExists(settings); |
130 | 148 | } |
| 149 | + } catch (IOException e) { |
| 150 | + //noinspection ThrowFromFinallyBlock |
| 151 | + throw new UncheckedIOException(e); |
131 | 152 | } |
132 | 153 | } |
133 | 154 | } |
134 | 155 |
|
135 | | - /** |
136 | | - * Pick a Gradle distribution compatible with the JVM running the Tooling API client. |
137 | | - * The daemon defaults to the same JVM as the client, so the chosen distribution must support that Java version. |
138 | | - * See <a href="https://docs.gradle.org/current/userguide/compatibility.html">Gradle compatibility matrix</a>. |
139 | | - */ |
140 | | - static String defaultGradleVersion() { |
141 | | - return defaultGradleVersion(javaSpecificationVersion()); |
142 | | - } |
143 | | - |
144 | | - static String defaultGradleVersion(int javaFeatureVersion) { |
145 | | - if (javaFeatureVersion >= 25) { |
146 | | - return "9.1.0"; |
| 156 | + private static boolean isGradle9OrLater(@Nullable String version) { |
| 157 | + if (version == null) { |
| 158 | + return false; |
| 159 | + } |
| 160 | + int dot = version.indexOf('.'); |
| 161 | + try { |
| 162 | + return Integer.parseInt(dot < 0 ? version : version.substring(0, dot)) >= 9; |
| 163 | + } catch (NumberFormatException e) { |
| 164 | + return false; |
147 | 165 | } |
148 | | - return "8.14.3"; |
149 | 166 | } |
150 | 167 |
|
151 | | - private static int javaSpecificationVersion() { |
152 | | - String version = System.getProperty("java.specification.version", "8"); |
153 | | - if (version.startsWith("1.")) { |
154 | | - version = version.substring(2); |
155 | | - } |
| 168 | + private static @Nullable String wrapperGradleVersion(Path wrapperProperties) { |
156 | 169 | try { |
157 | | - return Integer.parseInt(version); |
158 | | - } catch (NumberFormatException e) { |
159 | | - return 8; |
| 170 | + for (String line : Files.readAllLines(wrapperProperties, StandardCharsets.UTF_8)) { |
| 171 | + if (line.startsWith("distributionUrl=")) { |
| 172 | + int idx = line.lastIndexOf("gradle-"); |
| 173 | + if (idx < 0) { |
| 174 | + return null; |
| 175 | + } |
| 176 | + int start = idx + "gradle-".length(); |
| 177 | + int end = start; |
| 178 | + while (end < line.length() && (Character.isDigit(line.charAt(end)) || line.charAt(end) == '.')) { |
| 179 | + end++; |
| 180 | + } |
| 181 | + return end > start ? line.substring(start, end) : null; |
| 182 | + } |
| 183 | + } |
| 184 | + } catch (IOException ignored) { |
160 | 185 | } |
| 186 | + return null; |
161 | 187 | } |
162 | 188 |
|
163 | 189 | /** |
|
0 commit comments