Make Artifacts be compared to each other based on their exec paths (and not their paths). This gives a predictable order in places where Artifacts are sorted by their natural order.
This works because exec paths of Artifacts are unique in any given build.
--
MOS_MIGRATED_REVID=90807141
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
index 95bb3ab..4eb11ca 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
@@ -33,6 +33,7 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.List;
import javax.annotation.Nullable;
@@ -68,7 +69,25 @@
@SkylarkModule(name = "File",
doc = "This type represents a file used by the build system. It can be "
+ "either a source file or a derived file produced by a rule.")
-public class Artifact implements FileType.HasFilename, Comparable<Artifact>, ActionInput {
+public class Artifact implements FileType.HasFilename, ActionInput {
+
+ /**
+ * Compares artifact according to their exec paths. Sorts null values first.
+ */
+ public static final Comparator<Artifact> EXEC_PATH_COMPARATOR = new Comparator<Artifact>() {
+ @Override
+ public int compare(Artifact a, Artifact b) {
+ if (a == b) {
+ return 0;
+ } else if (a == null) {
+ return -1;
+ } else if (b == null) {
+ return -1;
+ } else {
+ return a.execPath.compareTo(b.execPath);
+ }
+ }
+ };
/** An object that can expand middleman artifacts. */
public interface MiddlemanExpander {
@@ -366,19 +385,12 @@
return false;
}
// We don't bother to check root in the equivalence relation, because we
- // assume that 'root' is an ancestor of 'path', and that all possible roots
- // are disjoint, so unless things are really screwed up, it's ok.
+ // assume that no root is an ancestor of another one.
Artifact that = (Artifact) other;
return this.path.equals(that.path);
}
@Override
- public final int compareTo(Artifact o) {
- // The artifact factory ensures that there is a unique artifact for a given path.
- return this.path.compareTo(o.path);
- }
-
- @Override
public final int hashCode() {
return path.hashCode();
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java b/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java
index 921e4e7..cc076e0 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/CachingAnalysisEnvironment.java
@@ -167,7 +167,7 @@
}
// The order of the artifacts.entrySet iteration is unspecified - we use a TreeMap here to
// guarantee that the return value of this method is deterministic.
- Map<Artifact, String> orphanArtifacts = new TreeMap<>();
+ Map<Artifact, String> orphanArtifacts = new TreeMap<>(Artifact.EXEC_PATH_COMPARATOR);
for (Map.Entry<Artifact, String> entry : artifacts.entrySet()) {
Artifact a = entry.getKey();
if (!a.isSourceArtifact() && !artifactsWithActions.contains(a)) {
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java b/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java
index 0ba34cb..c4b3f53 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java
@@ -85,10 +85,10 @@
PathFragment bPath = new PathFragment("src/b");
Artifact aArtifact = new Artifact(aPath, rootDir);
Artifact bArtifact = new Artifact(bPath, rootDir);
- assertEquals(-1, aArtifact.compareTo(bArtifact));
- assertEquals(0, aArtifact.compareTo(aArtifact));
- assertEquals(0, bArtifact.compareTo(bArtifact));
- assertEquals(1, bArtifact.compareTo(aArtifact));
+ assertEquals(-1, Artifact.EXEC_PATH_COMPARATOR.compare(aArtifact, bArtifact));
+ assertEquals(0, Artifact.EXEC_PATH_COMPARATOR.compare(aArtifact, aArtifact));
+ assertEquals(0, Artifact.EXEC_PATH_COMPARATOR.compare(bArtifact, bArtifact));
+ assertEquals(1, Artifact.EXEC_PATH_COMPARATOR.compare(bArtifact, aArtifact));
}
@Test