when IC logic decides to rebuild the whole target, ensure all resources are fully copied

GitOrigin-RevId: 4cf638c06264959339b1728b378e3b0a6f7d15c2
This commit is contained in:
Eugene Zhuravlev
2025-09-29 00:11:15 +00:00
committed by intellij-monorepo-bot
parent aa8e80e719
commit 47abb89c2a
3 changed files with 39 additions and 14 deletions
@@ -58,7 +58,6 @@ public class BazelIncBuilder {
ConfigurationState presentState = new ConfigurationState(context.getPathMapper(), context.getSources(), context.getResources(), context.getBinaryDependencies(), context.getFlags());
srcSnapshotDelta = new SnapshotDeltaImpl(pastState.getSources(), presentState.getSources());
resourcesDelta = new ResourcesSnapshotDelta(pastState.getResources(), presentState.getResources());
if (shouldRecompileAll(srcSnapshotDelta) || pastState.getFlagsDigest() != presentState.getFlagsDigest() || pastState.getClasspathStructureDigest() != presentState.getClasspathStructureDigest()) {
int changedPercent = srcSnapshotDelta.getChangedPercent();
@@ -148,6 +147,10 @@ public class BazelIncBuilder {
}
}
}
if (!srcSnapshotDelta.isRecompileAll()) {
resourcesDelta = new ResourcesSnapshotDelta(pastState.getResources(), presentState.getResources());
}
}
List<CompilerRunner> roundCompilers = collect(map(RunnerRegistry.getRoundCompilers(), f -> f.create(context, storageManager)), new ArrayList<>());
@@ -170,10 +173,10 @@ public class BazelIncBuilder {
OutputSinkImpl outSink = new OutputSinkImpl(storageManager);
if (isInitialRound) {
// processing resources
ZipOutputBuilder out = storageManager.getOutputBuilder();
if (resourcesDelta == null) {
if (resourcesDelta == null || srcSnapshotDelta.isRecompileAll()) {
// copy everything
for (ResourceGroup group : context.getResources()) {
copyResources(group, context.getPathMapper(), out);
@@ -194,6 +197,15 @@ public class BazelIncBuilder {
logDeletedPaths(context, cleaned);
}
}
else {
if (srcSnapshotDelta.isRecompileAll()) {
// After several rounds, the IC logic can decide to recompile everything
ZipOutputBuilder out = storageManager.getOutputBuilder();
for (ResourceGroup group : context.getResources()) {
copyResources(group, context.getPathMapper(), out);
}
}
}
for (CompilerRunner runner : roundCompilers) {
@@ -344,17 +356,17 @@ public class BazelIncBuilder {
String stripPrefix = group.getStripPrefix();
if (!stripPrefix.isEmpty()) {
if (destPath.regionMatches(!SystemInfo.isFileSystemCaseSensitive, 0, stripPrefix, 0, stripPrefix.length()) && (destPath.length() == stripPrefix.length() || destPath.charAt(stripPrefix.length()) == '/') ) {
destPath = destPath.substring(stripPrefix.length());
if (destPath.length() > stripPrefix.length() && destPath.regionMatches(!SystemInfo.isFileSystemCaseSensitive, 0, stripPrefix, 0, stripPrefix.length()) && destPath.charAt(stripPrefix.length()) == '/' ) {
destPath = destPath.substring(stripPrefix.length() + 1);
}
else {
return null;
return null; // todo: emit error
}
}
String addPrefix = group.getAddPrefix();
if (!addPrefix.isEmpty()) {
destPath = destPath.startsWith("/")? addPrefix + destPath : addPrefix + "/" + destPath;
destPath = addPrefix + "/" + destPath;
}
return destPath;
@@ -37,13 +37,18 @@ public class ConfigurationState {
CLFlags.NON_INCREMENTAL,
CLFlags.JAVA_COUNT,
CLFlags.TARGET_LABEL,
CLFlags.CP, // processed separately
CLFlags.OUT,
CLFlags.ABI_OUT,
CLFlags.WARN,
CLFlags.X_WASM_ATTACH_JS_EXCEPTION,
CLFlags.ADD_EXPORT,
CLFlags.ADD_READS
CLFlags.ADD_READS,
CLFlags.SRCS,
CLFlags.RESOURCES
);
private final NodeSourcePathMapper myPathMapper;
@@ -1,5 +1,7 @@
package com.intellij.tools.build.bazel.jvmIncBuilder.impl;
import com.dynatrace.hash4j.hashing.HashStream64;
import com.dynatrace.hash4j.hashing.Hashing;
import com.intellij.tools.build.bazel.jvmIncBuilder.ResourceGroup;
import org.jetbrains.jps.dependency.DataReader;
import org.jetbrains.jps.dependency.GraphDataInput;
@@ -8,7 +10,6 @@ import org.jetbrains.jps.dependency.NodeSource;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class ResourceGroupImpl extends SourceSnapshotImpl implements ResourceGroup {
@@ -20,16 +21,23 @@ public class ResourceGroupImpl extends SourceSnapshotImpl implements ResourceGro
myStripPrefix = normalizePrefix(stripPrefix);
myAddPrefix = normalizePrefix(addPrefix);
String prefixDigest = Long.toHexString(Utils.digest(List.of(myStripPrefix, myAddPrefix)));
HashStream64 hash = Hashing.xxh3_64().hashStream();
for (Map.Entry<NodeSource, String> entry : digestSources.entrySet()) {
entry.setValue(prefixDigest + ":" + entry.getValue());
entry.setValue(Long.toHexString(hash.reset().putString(myStripPrefix).putString(myAddPrefix).putString(entry.getValue()).getAsLong()));
}
}
private static String normalizePrefix(String prefix) {
prefix = prefix.replace(File.separatorChar, '/');
while (prefix.endsWith("/")) {
prefix = prefix.substring(0, prefix.length() - 1);
if (!prefix.isEmpty()) {
prefix = prefix.replace(File.separatorChar, '/');
int start = 0;
while (start < prefix.length() && prefix.charAt(start) == '/') start += 1;
int end = prefix.length() - 1;
while (end > start && prefix.charAt(end) == '/') end -= 1;
prefix = start <= end? prefix.substring(start, end + 1) : "";
}
return prefix;
}