Automated rollback of commit 0676dcfac708a34110388394805ae821cdf6b0ee.

*** Reason for rollback ***

Seems like some of our rule implementations aren't ready for this.

*** Original change description ***

Make runfiles conflicts fail the build.

Previously, runfiles conflicts would print an ERROR message and then allow the build to continue, resolving the conflict in an arbitrary way.

Most of this CL is churn to allow the runfiles mapping computation methods to raise ExecException. The only interesting changes are in Runfiles.java, RunfilesTest.java, and SkylarkRuleImplementationFunctionsTest.java.

Fixes https://github.com/bazelbuild/bazel...

***

PiperOrigin-RevId: 213338327
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/Runfiles.java b/src/main/java/com/google/devtools/build/lib/analysis/Runfiles.java
index 399dca5..2793953 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/Runfiles.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/Runfiles.java
@@ -361,22 +361,12 @@
         .build();
   }
 
-  /** Returns the symlinks as a map from path fragment to artifact. */
-  public Map<PathFragment, Artifact> getSymlinksAsMap() {
-    try {
-      return entriesToMap(symlinks, null);
-    } catch (IOException e) {
-      throw new IllegalStateException("unexpected since we passed a null conflict checker", e);
-    }
-  }
-
   /**
    * Returns the symlinks as a map from path fragment to artifact.
    *
    * @param checker If not null, check for conflicts using this checker.
    */
-  public Map<PathFragment, Artifact> getSymlinksAsMap(@Nullable ConflictChecker checker)
-      throws IOException {
+  public Map<PathFragment, Artifact> getSymlinksAsMap(@Nullable ConflictChecker checker) {
     return entriesToMap(symlinks, checker);
   }
 
@@ -514,9 +504,11 @@
       this.sawWorkspaceName = legacyExternalRunfiles;
     }
 
-    /** Adds a map under the workspaceName. */
+    /**
+     * Adds a map under the workspaceName.
+     */
     public void addUnderWorkspace(
-        Map<PathFragment, Artifact> inputManifest, ConflictChecker checker) throws IOException {
+        Map<PathFragment, Artifact> inputManifest, ConflictChecker checker) {
       for (Map.Entry<PathFragment, Artifact> entry : inputManifest.entrySet()) {
         PathFragment path = entry.getKey();
         if (isUnderWorkspace(path)) {
@@ -532,9 +524,10 @@
       }
     }
 
-    /** Adds a map to the root directory. */
-    public void add(Map<PathFragment, Artifact> inputManifest, ConflictChecker checker)
-        throws IOException {
+    /**
+     * Adds a map to the root directory.
+     */
+    public void add(Map<PathFragment, Artifact> inputManifest, ConflictChecker checker) {
       for (Map.Entry<PathFragment, Artifact> entry : inputManifest.entrySet()) {
         checker.put(manifest, checkForWorkspace(entry.getKey()), entry.getValue());
       }
@@ -580,22 +573,12 @@
     return rootSymlinks;
   }
 
-  /** Returns the root symlinks as a map from path fragment to artifact. */
-  public Map<PathFragment, Artifact> getRootSymlinksAsMap() {
-    try {
-      return entriesToMap(rootSymlinks, null);
-    } catch (IOException e) {
-      throw new IllegalStateException("unexpected since we passed a null conflict checker", e);
-    }
-  }
-
   /**
    * Returns the root symlinks as a map from path fragment to artifact.
    *
    * @param checker If not null, check for conflicts using this checker.
    */
-  public Map<PathFragment, Artifact> getRootSymlinksAsMap(@Nullable ConflictChecker checker)
-      throws IOException {
+  public Map<PathFragment, Artifact> getRootSymlinksAsMap(@Nullable ConflictChecker checker) {
     return entriesToMap(rootSymlinks, checker);
   }
 
@@ -604,12 +587,7 @@
    * account.
    */
   public Map<PathFragment, Artifact> asMapWithoutRootSymlinks() {
-    Map<PathFragment, Artifact> result;
-    try {
-      result = entriesToMap(symlinks, null);
-    } catch (IOException e) {
-      throw new IllegalStateException("unexpected since we passed a null conflict checker", e);
-    }
+    Map<PathFragment, Artifact> result = entriesToMap(symlinks, null);
     // If multiple artifacts have the same root-relative path, the last one in the list will win.
     // That is because the runfiles tree cannot contain the same artifact for different
     // configurations, because it only uses root-relative paths.
@@ -669,11 +647,11 @@
    *
    * @param entrySet Sequence of entries to add.
    * @param checker If not null, check for conflicts with this checker, otherwise silently allow
-   *     entries to overwrite previous entries.
+   *    entries to overwrite previous entries.
    * @return Map<PathFragment, Artifact> Map of runfile entries.
    */
   private static Map<PathFragment, Artifact> entriesToMap(
-      Iterable<SymlinkEntry> entrySet, @Nullable ConflictChecker checker) throws IOException {
+      Iterable<SymlinkEntry> entrySet, @Nullable ConflictChecker checker) {
     checker = (checker != null) ? checker : ConflictChecker.IGNORE_CHECKER;
     Map<PathFragment, Artifact> map = new LinkedHashMap<>();
     for (SymlinkEntry entry : entrySet) {
@@ -710,6 +688,9 @@
     /** Location for eventHandler warnings. Ignored if eventHandler is null. */
     private final Location location;
 
+    /** Type of event to emit */
+    private final EventKind eventKind;
+
     /** Construct a ConflictChecker for the given reporter with the given behavior */
     public ConflictChecker(ConflictPolicy policy, EventHandler eventHandler, Location location) {
       if (eventHandler == null) {
@@ -719,6 +700,7 @@
       }
       this.eventHandler = eventHandler;
       this.location = location;
+      this.eventKind = (policy == ConflictPolicy.ERROR) ? EventKind.ERROR : EventKind.WARNING;
     }
 
     /**
@@ -728,8 +710,7 @@
      * @param path Path fragment to use as key in map.
      * @param artifact Artifact to store in map. This may be null to indicate an empty file.
      */
-    public void put(Map<PathFragment, Artifact> map, PathFragment path, Artifact artifact)
-        throws IOException {
+    public void put(Map<PathFragment, Artifact> map, PathFragment path, Artifact artifact) {
       Preconditions.checkArgument(
           artifact == null || !artifact.isMiddlemanArtifact(), "%s", artifact);
       if (policy != ConflictPolicy.IGNORE && map.containsKey(path)) {
@@ -740,18 +721,13 @@
               (previous == null) ? "empty file" : previous.getExecPath().toString();
           String artifactStr =
               (artifact == null) ? "empty file" : artifact.getExecPath().toString();
-          if (policy == ConflictPolicy.WARN) {
-            String message =
-                String.format(
-                    "overwrote runfile %s, was symlink to %s, now symlink to %s",
-                    path.getSafePathString(), previousStr, artifactStr);
-            eventHandler.handle(Event.of(EventKind.WARNING, location, message));
-          } else {
-            throw new IOException(
-                String.format(
-                    "runfile %s mapped to both %s and %s",
-                    path.getSafePathString(), previousStr, artifactStr));
-          }
+          String message =
+              String.format(
+                  "overwrote runfile %s, was symlink to %s, now symlink to %s",
+                  path.getSafePathString(),
+                  previousStr,
+                  artifactStr);
+          eventHandler.handle(Event.of(eventKind, location, message));
         }
       }
       map.put(path, artifact);
@@ -1195,13 +1171,13 @@
   public void fingerprint(Fingerprint fp) {
     fp.addBoolean(getLegacyExternalRunfiles());
     fp.addPath(getSuffix());
-    Map<PathFragment, Artifact> symlinks = getSymlinksAsMap();
+    Map<PathFragment, Artifact> symlinks = getSymlinksAsMap(null);
     fp.addInt(symlinks.size());
     for (Map.Entry<PathFragment, Artifact> symlink : symlinks.entrySet()) {
       fp.addPath(symlink.getKey());
       fp.addPath(symlink.getValue().getExecPath());
     }
-    Map<PathFragment, Artifact> rootSymlinks = getRootSymlinksAsMap();
+    Map<PathFragment, Artifact> rootSymlinks = getRootSymlinksAsMap(null);
     fp.addInt(rootSymlinks.size());
     for (Map.Entry<PathFragment, Artifact> rootSymlink : rootSymlinks.entrySet()) {
       fp.addPath(rootSymlink.getKey());