Skip to content

Commit 494855c

Browse files
Keep Kotlin compile configs of composite builds apart
The Gradle plugin named each Kotlin config file after the sanitized task path. Task paths are only unique within one build, so the root build and an included build both wrote -compileKotlin.txt and the later one replaced the earlier, dropping its sources from the index. Sanitizing also mapped :a-b:compileKotlin and 🅰️b:compileKotlin to the same name. Name the file after a hash of the build's root directory and the task path instead. Amp-Thread-ID: https://ampcode.com/threads/T-01a1a6a2-f2b0-775c-a192-e5d11290c493 Co-authored-by: Christoph Hegemann <christoph.hegemann@sourcegraph.com>
1 parent 802f52f commit 494855c

12 files changed

Lines changed: 56 additions & 2 deletions

File tree

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package org.scip_code.scip_java.gradle;
22

33
import java.io.File;
4+
import java.nio.charset.StandardCharsets;
45
import java.nio.file.Files;
56
import java.nio.file.Path;
67
import java.nio.file.Paths;
8+
import java.security.MessageDigest;
79
import java.util.ArrayList;
810
import java.util.HashSet;
11+
import java.util.HexFormat;
912
import java.util.List;
1013
import java.util.Map;
1114
import java.util.Set;
@@ -271,7 +274,8 @@ private static Set<String> addJavacPlugin(Project project, Object javacPluginDep
271274
}
272275

273276
/**
274-
* Dumps the sources and classpath of a Kotlin compile task to {@code kotlin-configs/<task>.txt}.
277+
* Dumps the sources and classpath of a Kotlin compile task to {@code
278+
* kotlin-configs/<task>-<hash>.txt}.
275279
*/
276280
private static void writeKotlinConfig(Task task, String sourceRoot, String targetRoot) {
277281
try {
@@ -317,7 +321,14 @@ private static void writeKotlinConfig(Task task, String sourceRoot, String targe
317321

318322
Path configDir = Paths.get(targetRoot, "kotlin-configs");
319323
Files.createDirectories(configDir);
320-
String fileName = task.getPath().replaceAll("[^A-Za-z0-9]", "-") + ".txt";
324+
// Task paths are only unique within one build, and every build of a
325+
// composite (included builds, buildSrc) writes here, so the build's
326+
// root directory is part of the identity. Hashing, unlike sanitizing,
327+
// keeps ":a-b:x" and ":a:b:x" apart; NUL cannot occur in a path.
328+
String identity = task.getProject().getRootDir().getAbsolutePath() + "\0" + task.getPath();
329+
byte[] hash =
330+
MessageDigest.getInstance("SHA-256").digest(identity.getBytes(StandardCharsets.UTF_8));
331+
String fileName = task.getName() + "-" + HexFormat.of().formatHex(hash, 0, 8) + ".txt";
321332
Files.write(configDir.resolve(fileName), lines);
322333
} catch (Exception exc) {
323334
throw new RuntimeException(

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ class GradleBuildToolTest : BuildToolHarness() {
204204
runs = 2,
205205
)
206206
)
207+
// Regression test: Kotlin compile tasks whose paths are equal in different
208+
// builds of a composite (`:compileKotlin` in the root and included build),
209+
// or equal after sanitizing (`:a-b` and `:a:b`), overwrote each other's
210+
// configs, so only one of their sources was indexed.
211+
add(checkGradleBuild("kotlin-composite", "gradle/kotlin-composite", expectedScipFiles = 4))
207212
add(
208213
checkGradleBuild(
209214
"implementation-deps",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
plugins {
2+
id 'org.jetbrains.kotlin.jvm'
3+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
package ab
2+
object Dashed {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
plugins {
2+
id 'org.jetbrains.kotlin.jvm'
3+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
package ab
2+
object Nested {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
plugins {
2+
id 'org.jetbrains.kotlin.jvm' version '2.4.0'
3+
}
4+
allprojects {
5+
repositories {
6+
mavenCentral()
7+
}
8+
}
9+
// `scipCompileAll` only runs tasks of the root build.
10+
tasks.named('compileKotlin') {
11+
dependsOn gradle.includedBuild('included').task(':compileKotlin')
12+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
plugins {
2+
id 'org.jetbrains.kotlin.jvm' version '2.4.0'
3+
}
4+
repositories {
5+
mavenCentral()
6+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rootProject.name = 'included'
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
package included
2+
object Included {}

0 commit comments

Comments
 (0)