diff --git a/scip-java/src/main/kotlin/org/scip_code/scip_java/buildtools/BazelBuildTool.kt b/scip-java/src/main/kotlin/org/scip_code/scip_java/buildtools/BazelBuildTool.kt index f27c8af94..88197f5c7 100644 --- a/scip-java/src/main/kotlin/org/scip_code/scip_java/buildtools/BazelBuildTool.kt +++ b/scip-java/src/main/kotlin/org/scip_code/scip_java/buildtools/BazelBuildTool.kt @@ -1,6 +1,7 @@ package org.scip_code.scip_java.buildtools import java.io.File +import java.io.OutputStream import java.nio.charset.StandardCharsets import java.nio.file.FileSystems import java.nio.file.FileVisitResult @@ -10,6 +11,9 @@ import java.nio.file.Paths import java.nio.file.SimpleFileVisitor import java.nio.file.StandardOpenOption import java.nio.file.attribute.BasicFileAttributes +import java.security.DigestInputStream +import java.security.MessageDigest +import java.util.HexFormat import org.scip_code.scip_java.Embedded import org.scip_code.scip_java.commands.IndexCommand @@ -70,6 +74,7 @@ class BazelBuildTool(index: IndexCommand) : BuildTool("Bazel", index) { "--output_groups=scip", "--define=java_home=$javaHome", "--define=scip_java_binary=$scipJavaBinary", + "--define=scip_java_fingerprint=${scipJavaFingerprint()}", "--verbose_failures", ) + targetSpecs @@ -81,6 +86,24 @@ class BazelBuildTool(index: IndexCommand) : BuildTool("Bazel", index) { } } + /** + * Hashes the jars of the running scip-java. The aspect can't declare the scip-java binary as an + * action input because it lives outside the workspace, so it puts this hash in the action key + * instead. Otherwise Bazel would reuse indexes produced by an older scip-java. + */ + private fun scipJavaFingerprint(): String { + val digest = MessageDigest.getInstance("SHA-256") + for (entry in System.getProperty("java.class.path").split(File.pathSeparator)) { + val path = Paths.get(entry) + if (!Files.isRegularFile(path)) continue + digest.update(path.fileName.toString().toByteArray(StandardCharsets.UTF_8)) + Files.newInputStream(path).use { input -> + DigestInputStream(input, digest).transferTo(OutputStream.nullOutputStream()) + } + } + return HexFormat.of().formatHex(digest.digest()) + } + private fun runBazelBuild(buildCommand: List): Int { val sandbox = SandboxCommandExtractor() index.app.info(buildCommand.joinToString(" ")) diff --git a/scip-java/src/main/resources/scip-java/scip_java.bzl b/scip-java/src/main/resources/scip-java/scip_java.bzl index 54d6ea25d..37ca4df32 100644 --- a/scip-java/src/main/resources/scip-java/scip_java.bzl +++ b/scip-java/src/main/resources/scip-java/scip_java.bzl @@ -146,6 +146,10 @@ def _scip_java(target, ctx): env = { "JAVA_HOME": ctx.var["java_home"], "NO_PROGRESS_BAR": "true", + # The scip-java binary is outside the workspace and can't be an action + # input. This hash of scip-java is part of the action key instead, so + # a new scip-java re-indexes targets instead of reusing cached outputs. + "SCIP_JAVA_FINGERPRINT": ctx.var.get("scip_java_fingerprint", ""), }, mnemonic = "ScipJavaIndex", inputs = depset([build_config_path] + output_dir, transitive = deps),