Skip to content

Commit 146ef03

Browse files
authored
Enable configuration cache (test tasks) (#15384)
* Enable configuration cache for :help (as a test). * Enable configuration cache for :showTestsSeed. * Refactor ModularPathsExtension to enable configuration cache (compileJava works). * Make the test task support the configuration-cache.
1 parent 27abe1c commit 146ef03

File tree

5 files changed

+225
-171
lines changed

5 files changed

+225
-171
lines changed

build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ModularPathsExtension.java

Lines changed: 93 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,11 @@
1717
package org.apache.lucene.gradle.plugins.java;
1818

1919
import java.io.File;
20-
import java.nio.file.Path;
21-
import java.util.AbstractMap;
2220
import java.util.ArrayList;
2321
import java.util.Arrays;
24-
import java.util.Collections;
2522
import java.util.Iterator;
2623
import java.util.List;
2724
import java.util.Map;
28-
import java.util.concurrent.Callable;
2925
import java.util.function.Consumer;
3026
import java.util.function.Function;
3127
import java.util.stream.Collectors;
@@ -35,7 +31,7 @@
3531
import org.gradle.api.artifacts.ConfigurationContainer;
3632
import org.gradle.api.attributes.LibraryElements;
3733
import org.gradle.api.file.FileCollection;
38-
import org.gradle.api.logging.Logger;
34+
import org.gradle.api.file.FileSystemLocation;
3935
import org.gradle.api.provider.Provider;
4036
import org.gradle.api.tasks.SourceSet;
4137
import org.gradle.process.CommandLineArgumentProvider;
@@ -72,18 +68,25 @@ public enum Mode {
7268
/** More verbose debugging for paths. */
7369
private boolean debugPaths;
7470

71+
final boolean hasModuleDescriptor;
72+
7573
/**
7674
* A list of module name - path provider entries that will be converted into {@code
7775
* --patch-module} options.
7876
*/
79-
private final List<Map.Entry<String, Provider<Path>>> modulePatches = new ArrayList<>();
77+
private final List<Map.Entry<String, Provider<? extends FileSystemLocation>>> modulePatches =
78+
new ArrayList<>();
8079

8180
public ModularPathsExtension(Project project, SourceSet sourceSet) {
8281
this.project = project;
8382
this.sourceSet = sourceSet;
8483

8584
// enable to debug paths.
8685
this.debugPaths = false;
86+
this.hasModuleDescriptor =
87+
sourceSet.getAllJava().getSrcDirs().stream()
88+
.map(dir -> new File(dir, "module-info.java"))
89+
.anyMatch(File::exists);
8790

8891
ConfigurationContainer configurations = project.getConfigurations();
8992

@@ -159,8 +162,23 @@ public ModularPathsExtension(Project project, SourceSet sourceSet) {
159162
* Adds {@code --patch-module} option for the provided module name and the provider of a folder or
160163
* JAR file.
161164
*/
162-
public void patchModule(String moduleName, Provider<Path> pathProvider) {
163-
modulePatches.add(new AbstractMap.SimpleImmutableEntry<>(moduleName, pathProvider));
165+
public void patchModule(String moduleName, Provider<? extends FileSystemLocation> pathProvider) {
166+
modulePatches.add(Map.entry(moduleName, pathProvider));
167+
}
168+
169+
public void patchModule(String moduleName, FileCollection singleFileCollection) {
170+
patchModule(
171+
moduleName,
172+
singleFileCollection
173+
.getElements()
174+
.map(
175+
elements -> {
176+
if (elements.size() != 1) {
177+
throw new RuntimeException(
178+
"Expected a single file as an argument for patchModule.");
179+
}
180+
return elements.iterator().next();
181+
}));
164182
}
165183

166184
private FileCollection getCompilationModulePath() {
@@ -172,7 +190,7 @@ private FileCollection getCompilationModulePath() {
172190

173191
private FileCollection getRuntimeModulePath() {
174192
if (mode == Mode.CLASSPATH_ONLY) {
175-
if (hasModuleDescriptor()) {
193+
if (hasModuleDescriptor) {
176194
throw new GradleException(
177195
"Source set contains a module but classpath-only dependencies requested: "
178196
+ project.getPath()
@@ -186,28 +204,34 @@ private FileCollection getRuntimeModulePath() {
186204
}
187205

188206
private FileCollection removeNonExisting(FileCollection fc) {
189-
return fc.filter(File::exists);
207+
return fc.filter(file -> file.exists());
190208
}
191209

192210
public FileCollection getCompilationClasspath() {
211+
var compileClasspath = sourceSet.getCompileClasspath();
212+
193213
if (mode == Mode.CLASSPATH_ONLY) {
194214
return removeNonExisting(sourceSet.getCompileClasspath());
195215
}
196216

197-
// Lazy computation to subtract module-path artifacts (and patches) from compile classpath.
198217
return removeNonExisting(
199-
project.files(
200-
(Callable<Object>)
201-
() ->
202-
sourceSet
203-
.getCompileClasspath()
204-
.minus(compileModulePathConfiguration)
205-
.minus(modulePatchOnlyConfiguration)));
218+
compileClasspath.minus(compileModulePathConfiguration).minus(modulePatchOnlyConfiguration));
206219
}
207220

208221
public CommandLineArgumentProvider getCompilationArguments() {
209-
return () -> {
210-
FileCollection modulePath = getCompilationModulePath();
222+
return new CompilationArgumentsProvider(
223+
getCompilationModulePath(), hasModuleDescriptor, modulePatches);
224+
}
225+
226+
/** Keep this class static to avoid references to the outer class. */
227+
public record CompilationArgumentsProvider(
228+
FileCollection modulePath,
229+
boolean hasModuleDescriptor,
230+
List<Map.Entry<String, Provider<? extends FileSystemLocation>>> modulePatches)
231+
implements CommandLineArgumentProvider {
232+
233+
@Override
234+
public Iterable<String> asArguments() {
211235
if (modulePath.isEmpty()) {
212236
return List.of();
213237
}
@@ -216,7 +240,7 @@ public CommandLineArgumentProvider getCompilationArguments() {
216240
extraArgs.add("--module-path");
217241
extraArgs.add(joinPaths(modulePath));
218242

219-
if (!hasModuleDescriptor()) {
243+
if (!hasModuleDescriptor) {
220244
// We're compiling what appears to be a non-module source set so we'll
221245
// bring everything on module path in the resolution graph,
222246
// otherwise modular dependencies wouldn't be part of the resolved module graph and this
@@ -229,20 +253,16 @@ public CommandLineArgumentProvider getCompilationArguments() {
229253
extraArgs.addAll(getPatchModuleArguments(modulePatches));
230254

231255
return extraArgs;
232-
};
256+
}
233257
}
234258

235259
public FileCollection getRuntimeClasspath() {
260+
var runtimeClasspath = sourceSet.getRuntimeClasspath();
261+
236262
if (mode == Mode.CLASSPATH_ONLY) {
237-
return sourceSet.getRuntimeClasspath();
263+
return runtimeClasspath;
238264
}
239-
return project.files(
240-
(Callable<Object>)
241-
() ->
242-
sourceSet
243-
.getRuntimeClasspath()
244-
.minus(getRuntimeModulePath())
245-
.minus(modulePatchOnlyConfiguration));
265+
return runtimeClasspath.minus(getRuntimeModulePath()).minus(modulePatchOnlyConfiguration);
246266
}
247267

248268
/**
@@ -255,27 +275,32 @@ public FileCollection getRuntimeClasspath() {
255275
* indirectly added by gradle internal logic.
256276
*/
257277
public FileCollection getTestRuntimeClasspath() {
278+
var runtimeClasspath = sourceSet.getRuntimeClasspath();
279+
258280
if (mode == Mode.CLASSPATH_ONLY) {
259-
return sourceSet.getRuntimeClasspath();
281+
return runtimeClasspath;
260282
}
261-
return project.files(
262-
(Callable<Object>)
263-
() ->
264-
sourceSet
265-
.getRuntimeClasspath()
266-
.minus(getRuntimeModulePath())
267-
.minus(modulePatchOnlyConfiguration)
268-
.plus(
269-
sourceSet
270-
.getRuntimeClasspath()
271-
.filter(file -> file.getName().contains("junit"))));
283+
return runtimeClasspath
284+
.minus(getRuntimeModulePath())
285+
.minus(modulePatchOnlyConfiguration)
286+
.plus(runtimeModulePathConfiguration.filter(file -> file.getName().contains("junit")));
272287
}
273288

274289
public CommandLineArgumentProvider getRuntimeArguments() {
275-
return () -> {
276-
FileCollection modulePath = getRuntimeModulePath();
290+
return new RuntimeArgumentsProvider(getRuntimeModulePath(), hasModuleDescriptor, modulePatches);
291+
}
292+
293+
/** Keep this class static to avoid references to the outer class. */
294+
public record RuntimeArgumentsProvider(
295+
FileCollection modulePath,
296+
boolean hasModuleDescriptor,
297+
List<Map.Entry<String, Provider<? extends FileSystemLocation>>> modulePatches)
298+
implements CommandLineArgumentProvider {
299+
300+
@Override
301+
public Iterable<String> asArguments() {
277302
if (modulePath.isEmpty()) {
278-
return Collections.emptyList();
303+
return List.of();
279304
}
280305

281306
List<String> extraArgs = new ArrayList<>();
@@ -285,32 +310,24 @@ public CommandLineArgumentProvider getRuntimeArguments() {
285310
extraArgs.add(joinPaths(modulePath));
286311

287312
// Ideally, we should only add the sourceset's module here, everything else would be resolved
288-
// via the
289-
// module descriptor. But this would require parsing the module descriptor and may cause JVM
290-
// version conflicts
291-
// so keeping it simple.
313+
// via the module descriptor. But this would require parsing the module descriptor and may
314+
// cause JVM version conflicts so keeping it simple.
292315
extraArgs.add("--add-modules");
293316
extraArgs.add("ALL-MODULE-PATH");
294317

295318
// Add module-patching.
296319
extraArgs.addAll(getPatchModuleArguments(modulePatches));
297320

298321
return extraArgs;
299-
};
300-
}
301-
302-
public boolean hasModuleDescriptor() {
303-
return sourceSet.getAllJava().getSrcDirs().stream()
304-
.map(dir -> new File(dir, "module-info.java"))
305-
.anyMatch(File::exists);
322+
}
306323
}
307324

308325
private static List<String> getPatchModuleArguments(
309-
List<Map.Entry<String, Provider<Path>>> patches) {
326+
List<Map.Entry<String, Provider<? extends FileSystemLocation>>> modulePatches) {
310327
List<String> args = new ArrayList<>();
311-
for (Map.Entry<String, Provider<Path>> e : patches) {
328+
for (var e : modulePatches) {
312329
args.add("--patch-module");
313-
args.add(e.getKey() + "=" + e.getValue().get());
330+
args.add(e.getKey() + "=" + e.getValue().get().getAsFile());
314331
}
315332
return args;
316333
}
@@ -326,43 +343,32 @@ private static String toList(FileCollection files) {
326343
.collect(Collectors.joining("\n"));
327344
}
328345

329-
private static String toList(List<Map.Entry<String, Provider<Path>>> patches) {
346+
private static String toList(
347+
List<Map.Entry<String, Provider<? extends FileSystemLocation>>> patches) {
330348
if (patches.isEmpty()) {
331349
return " [empty]";
332350
}
333351
return patches.stream()
334-
.map(e -> " " + e.getKey() + "=" + e.getValue().get())
352+
.map(e -> " " + e.getKey() + "=" + e.getValue().get().getAsFile())
335353
.collect(Collectors.joining("\n"));
336354
}
337355

338-
public void logCompilationPaths(Logger logger) {
339-
String value =
340-
"Modular extension, compilation paths, source set="
341-
+ (sourceSet.getName() + (hasModuleDescriptor() ? " (module)" : ""))
342-
+ (", mode=" + mode + ":\n")
343-
+ (" Module path:" + toList(getCompilationModulePath()) + "\n")
344-
+ (" Class path: " + toList(getCompilationClasspath()) + "\n")
345-
+ (" Patches: " + toList(modulePatches));
346-
if (debugPaths) {
347-
logger.lifecycle(value);
348-
} else {
349-
logger.info(value);
350-
}
356+
public String getCompilationPathDebugInfo() {
357+
return "Modular extension, compilation paths, source set="
358+
+ (sourceSet.getName() + (hasModuleDescriptor ? " (module)" : ""))
359+
+ (", mode=" + mode + ":\n")
360+
+ (" Module path:" + toList(getCompilationModulePath()) + "\n")
361+
+ (" Class path: " + toList(getCompilationClasspath()) + "\n")
362+
+ (" Patches: " + toList(modulePatches));
351363
}
352364

353-
public void logRuntimePaths(Logger logger) {
354-
String value =
355-
"Modular extension, runtime paths, source set="
356-
+ (sourceSet.getName() + (hasModuleDescriptor() ? " (module)" : ""))
357-
+ (", mode=" + mode + ":\n")
358-
+ (" Module path:" + toList(getRuntimeModulePath()) + "\n")
359-
+ (" Class path: " + toList(getRuntimeClasspath()) + "\n")
360-
+ (" Patches : " + toList(modulePatches));
361-
if (debugPaths) {
362-
logger.lifecycle(value);
363-
} else {
364-
logger.info(value);
365-
}
365+
public String getRuntimePathDebugInfo() {
366+
return "Modular extension, runtime paths, source set="
367+
+ (sourceSet.getName() + (hasModuleDescriptor ? " (module)" : ""))
368+
+ (", mode=" + mode + ":\n")
369+
+ (" Module path:" + toList(getRuntimeModulePath()) + "\n")
370+
+ (" Class path: " + toList(getRuntimeClasspath()) + "\n")
371+
+ (" Patches : " + toList(modulePatches));
366372
}
367373

368374
@Override

0 commit comments

Comments
 (0)