Skip to content

Commit 802f52f

Browse files
committed
Revert "fix/gradle: fix configuration cache issues"
This reverts commit e976e40. Not needed now that the CLI disables the configuration cache.
1 parent 34064ce commit 802f52f

2 files changed

Lines changed: 54 additions & 86 deletions

File tree

‎scip-gradle-plugin/src/main/java/org/scip_code/scip_java/gradle/ScipGradlePlugin.java‎

Lines changed: 51 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.nio.file.Path;
66
import java.nio.file.Paths;
77
import java.util.ArrayList;
8-
import java.util.HashMap;
98
import java.util.HashSet;
109
import java.util.List;
1110
import java.util.Map;
@@ -21,6 +20,8 @@
2120
import org.gradle.api.tasks.Input;
2221
import org.gradle.api.tasks.SourceSet;
2322
import org.gradle.api.tasks.SourceSetContainer;
23+
import org.gradle.api.tasks.TaskProvider;
24+
import org.gradle.api.tasks.TaskState;
2425
import org.gradle.api.tasks.compile.CompileOptions;
2526
import org.gradle.api.tasks.compile.JavaCompile;
2627
import org.gradle.process.CommandLineArgumentProvider;
@@ -138,75 +139,41 @@ private void configureProject(Project project) {
138139
}
139140
}
140141

141-
// Kotlin sources are not indexed inside kotlinc: after each Kotlin compile
142-
// task, its sources and classpath are dumped for the scip-java CLI to index
143-
// after the build, decoupling indexing from the build's Kotlin compiler
144-
// version. The dump is a finalizer rather than an action of the compile
145-
// task, because Gradle skips the compile task's actions when it is up to
142+
// Kotlin sources are not indexed inside kotlinc: after the Kotlin compile
143+
// tasks, their sources and classpath are dumped for the scip-java CLI to
144+
// index after the build, decoupling indexing from the build's Kotlin
145+
// compiler version. The dump is a finalizer rather than an action of the
146+
// compile tasks, because Gradle skips their actions when they are up to
146147
// date or restored from the build cache, while the CLI deletes the
147148
// targetroot before every build. The finalizer declares no outputs, so
148-
// Gradle runs it every time. A rule creates it on demand, because tasks
149-
// can't be registered from configureEach, and it captures only file
150-
// collections rather than the compile task, so it works with the
151-
// configuration cache.
152-
Map<String, String> kotlinConfigTasks = new HashMap<>();
153-
project
154-
.getTasks()
155-
.addRule(
156-
"Pattern: scipKotlinConfig<Task>: dumps a Kotlin compile task's configuration",
157-
name -> {
158-
String compileName = kotlinConfigTasks.get(name);
159-
if (compileName == null) {
160-
return;
161-
}
162-
Task compile = project.getTasks().getByName(compileName);
163-
String compilePath = compile.getPath();
164-
// Referring to KotlinCompile directly triggers NoClassDefFoundError -
165-
// the plugin classpath is murky and we deliberately don't bundle the
166-
// Kotlin Gradle plugin. So we commit the sins of reflection.
167-
FileCollection libraries = fileCollection(compile, "getLibraries");
168-
if (libraries == null) {
169-
libraries = fileCollection(compile, "getClasspath");
170-
}
171-
if (libraries == null) {
172-
throw new IllegalStateException(
173-
"scip-java: failed to extract Kotlin compile configuration for task '"
174-
+ compileName
175-
+ "': no libraries or classpath");
176-
}
177-
FileCollection classpath = libraries;
178-
FileCollection sources = compile.getInputs().getSourceFiles();
179-
// Kotlin Gradle Plugin without javaSources (pre 1.7) has none.
180-
FileCollection javaSources = fileCollection(compile, "getJavaSources");
181-
FileCollection allJavaSources = javaSources != null ? javaSources : project.files();
182-
project
183-
.getTasks()
184-
.create(
185-
name,
186-
export ->
187-
export.doLast(
188-
ignored ->
189-
writeKotlinConfig(
190-
compilePath,
191-
classpath,
192-
sources,
193-
allJavaSources,
194-
sourceRoot,
195-
targetRoot)));
196-
});
149+
// Gradle runs it every time.
150+
List<Task> kotlinCompileTasks = new ArrayList<>();
151+
TaskProvider<Task> kotlinConfigs =
152+
project
153+
.getTasks()
154+
.register(
155+
"scipKotlinConfigs",
156+
export ->
157+
export.doLast(
158+
ignored -> {
159+
for (Task task : kotlinCompileTasks) {
160+
// Only tasks of this build that succeeded; up-to-date
161+
// and cached tasks count as executed.
162+
TaskState state = task.getState();
163+
if (state.getExecuted() && state.getFailure() == null) {
164+
writeKotlinConfig(task, sourceRoot, targetRoot);
165+
}
166+
}
167+
}));
197168
// Not limited to the plugin checks above: AGP 9's built-in Kotlin adds
198169
// Kotlin compile tasks to Android modules without applying a Kotlin plugin.
199170
project
200171
.getTasks()
201172
.configureEach(
202173
task -> {
203174
if (task.getClass().getSimpleName().contains("KotlinCompile")) {
204-
String name =
205-
"scipKotlinConfig"
206-
+ Character.toUpperCase(task.getName().charAt(0))
207-
+ task.getName().substring(1);
208-
kotlinConfigTasks.put(name, task.getName());
209-
task.finalizedBy(name);
175+
kotlinCompileTasks.add(task);
176+
task.finalizedBy(kotlinConfigs);
210177
}
211178
});
212179

@@ -303,57 +270,59 @@ private static Set<String> addJavacPlugin(Project project, Object javacPluginDep
303270
return pluginTasks;
304271
}
305272

306-
private static FileCollection fileCollection(Task task, String getter) {
307-
try {
308-
return (FileCollection) task.getClass().getMethod(getter).invoke(task);
309-
} catch (ReflectiveOperationException exc) {
310-
return null;
311-
}
312-
}
313-
314273
/**
315274
* Dumps the sources and classpath of a Kotlin compile task to {@code kotlin-configs/<task>.txt}.
316275
*/
317-
private static void writeKotlinConfig(
318-
String taskPath,
319-
FileCollection libraries,
320-
FileCollection kotlinSources,
321-
FileCollection javaSources,
322-
String sourceRoot,
323-
String targetRoot) {
276+
private static void writeKotlinConfig(Task task, String sourceRoot, String targetRoot) {
324277
try {
325278
List<String> lines = new ArrayList<>();
326279
lines.add("sourceroot " + sourceRoot);
280+
281+
// Referring to KotlinCompile directly triggers NoClassDefFoundError -
282+
// the plugin classpath is murky and we deliberately don't bundle the
283+
// Kotlin Gradle plugin. So we commit the sins of reflection.
284+
FileCollection libraries;
285+
try {
286+
libraries = (FileCollection) task.getClass().getMethod("getLibraries").invoke(task);
287+
} catch (ReflectiveOperationException exc) {
288+
libraries = (FileCollection) task.getClass().getMethod("getClasspath").invoke(task);
289+
}
327290
for (File entry : libraries.getFiles()) {
328291
lines.add("classpath " + entry.getAbsolutePath());
329292
}
330293

331294
int sources = 0;
332-
for (File file : kotlinSources.getFiles()) {
295+
for (File file : task.getInputs().getSourceFiles().getFiles()) {
333296
if (file.getName().endsWith(".kt") || file.getName().endsWith(".kts")) {
334297
lines.add("source " + file.getAbsolutePath());
335298
sources++;
336299
}
337300
}
338301
// Java sources of the same module are listed too, so Kotlin
339302
// references to them resolve. The indexer only emits Kotlin files.
340-
for (File file : javaSources.getFiles()) {
341-
if (file.getName().endsWith(".java")) {
342-
lines.add("source " + file.getAbsolutePath());
303+
try {
304+
FileCollection javaSources =
305+
(FileCollection) task.getClass().getMethod("getJavaSources").invoke(task);
306+
for (File file : javaSources.getFiles()) {
307+
if (file.getName().endsWith(".java")) {
308+
lines.add("source " + file.getAbsolutePath());
309+
}
343310
}
311+
} catch (ReflectiveOperationException exc) {
312+
// Kotlin Gradle Plugin without javaSources (pre 1.7).
344313
}
345314
if (sources == 0) {
346315
return;
347316
}
348317

349318
Path configDir = Paths.get(targetRoot, "kotlin-configs");
350319
Files.createDirectories(configDir);
351-
String fileName = taskPath.replaceAll("[^A-Za-z0-9]", "-") + ".txt";
320+
String fileName = task.getPath().replaceAll("[^A-Za-z0-9]", "-") + ".txt";
352321
Files.write(configDir.resolve(fileName), lines);
353322
} catch (Exception exc) {
354323
throw new RuntimeException(
355324
"scip-java: failed to extract Kotlin compile configuration for task '"
356-
+ taskPath
325+
+ task.getName()
357326
+ "': "
358327
+ exc,
359328
exc);

‎scip-java/src/test/kotlin/tests/GradleBuildToolTest.kt‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,7 @@ class GradleBuildToolTest : BuildToolHarness() {
186186
add(checkGradleBuild("kotlin2", "gradle/kotlin2", expectedScipFiles = 4))
187187
// Regression tests: Kotlin sources must be indexed again when the Kotlin
188188
// compile tasks are restored from the build cache, or are up to date
189-
// because the build command doesn't clean. The second run of the latter
190-
// also reuses the configuration cache entry of the first.
189+
// because the build command doesn't clean.
191190
add(
192191
checkGradleBuild(
193192
"kotlin-build-cache",
@@ -200,8 +199,8 @@ class GradleBuildToolTest : BuildToolHarness() {
200199
checkGradleBuild(
201200
"kotlin-up-to-date",
202201
"gradle/kotlin2",
203-
expectedScipFiles = 1,
204-
extraArguments = listOf("--", "--configuration-cache", "compileKotlin"),
202+
expectedScipFiles = 2,
203+
extraArguments = listOf("--", "compileKotlin", "compileJava"),
205204
runs = 2,
206205
)
207206
)

0 commit comments

Comments
 (0)