Rollback of commit 4b73e972d909bcd533f2f9940f95a00b9b73bdde.

*** Reason for rollback ***

Broke tests on CI: http://ci.bazel.io/job/bazel-tests/570/


*** Original change description ***

Roll forward execroot change

RELNOTES[INC]: Previously, an external repository would be symlinked into the
execution root at execroot/local_repo/external/remote_repo. This changes it to
be at execroot/remote_repo. This may break genrules/Skylark actions that
hardcode execution root paths. If this causes breakages for you, ensure that
genrules are using $(location :target) to access files and Skylark rules are
using http://bazel.io/docs/skylark/lib/File.html's path, dirname, etc.
functions. Cust...

--
PiperOrigin-RevId: 147833177
MOS_MIGRATED_REVID=147833177
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java
index ed01807..1abc893 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java
@@ -142,7 +142,7 @@
    * <p>For example "//pkg:target" -> "pkg/&lt;fragment&gt;/target.
    */
   public static PathFragment getUniqueDirectory(Label label, PathFragment fragment) {
-    return label.getPackageIdentifier().getPackageFragment().getRelative(fragment)
+    return label.getPackageIdentifier().getSourceRoot().getRelative(fragment)
         .getRelative(label.getName());
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/CompilationHelper.java b/src/main/java/com/google/devtools/build/lib/analysis/CompilationHelper.java
index 7e93108..8a1fddc 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/CompilationHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/CompilationHelper.java
@@ -21,6 +21,7 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.collect.nestedset.Order;
+
 import java.util.List;
 
 /**
@@ -53,8 +54,8 @@
     }
     MiddlemanFactory factory = env.getMiddlemanFactory();
     return ImmutableList.of(factory.createMiddlemanAllowMultiple(
-        env, actionOwner, ruleContext.getRule().getLabel().getPackageIdentifier().getSourceRoot(),
-        purpose, filesToBuild, ruleContext.getConfiguration().getMiddlemanDirectory(
+        env, actionOwner, ruleContext.getPackageDirectory(), purpose, filesToBuild,
+        ruleContext.getConfiguration().getMiddlemanDirectory(
             ruleContext.getRule().getRepository())));
   }
 
@@ -86,8 +87,7 @@
     MiddlemanFactory factory = env.getMiddlemanFactory();
     Iterable<Artifact> artifacts = dep.getProvider(FileProvider.class).getFilesToBuild();
     return ImmutableList.of(
-        factory.createMiddlemanAllowMultiple(env, actionOwner,
-            ruleContext.getRule().getLabel().getPackageIdentifier().getSourceRoot(),
+        factory.createMiddlemanAllowMultiple(env, actionOwner, ruleContext.getPackageDirectory(),
             purpose, artifacts, ruleContext.getConfiguration().getMiddlemanDirectory(
                 ruleContext.getRule().getRepository())));
   }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
index 8cf2d37..e2fbee9 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
@@ -149,7 +149,9 @@
         : configuration.getGenfilesDirectory(rule.getRepository());
     ArtifactOwner owner =
         new ConfiguredTargetKey(rule.getLabel(), configuration.getArtifactOwnerConfiguration());
-    PathFragment rootRelativePath = outputFile.getLabel().toPathFragment();
+    PathFragment rootRelativePath =
+        outputFile.getLabel().getPackageIdentifier().getSourceRoot().getRelative(
+            outputFile.getLabel().getName());
     Artifact result = isFileset
         ? artifactFactory.getFilesetArtifact(rootRelativePath, root, owner)
         : artifactFactory.getDerivedArtifact(rootRelativePath, root, owner);
@@ -200,7 +202,7 @@
     } else if (target instanceof InputFile) {
       InputFile inputFile = (InputFile) target;
       Artifact artifact = artifactFactory.getSourceArtifact(
-          inputFile.getLabel().toPathFragment(),
+          inputFile.getExecPath(),
           Root.asSourceRoot(inputFile.getPackage().getSourceRoot(),
               inputFile.getPackage().getPackageIdentifier().getRepository().isMain()),
           new ConfiguredTargetKey(target.getLabel(), config));
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java b/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java
index fc30d6a..225b3e1 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java
@@ -332,7 +332,7 @@
 
     for (Artifact artifact : artifacts) {
       PathFragment execPath =
-          takeExecPath ? artifact.getExecPath() : artifact.getRunfilesPath();
+          takeExecPath ? artifact.getExecPath() : artifact.getRootRelativePath();
       if (execPath != null) {  // omit middlemen etc
         paths.add(execPath.getCallablePathString());
       }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 4efcf03..656ca25 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -87,7 +87,6 @@
 import com.google.devtools.build.lib.util.Preconditions;
 import com.google.devtools.build.lib.util.StringUtil;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
-import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -593,19 +592,6 @@
    * thus guaranteeing that it never clashes with artifacts created by rules in other packages.
    */
   public Artifact getPackageRelativeArtifact(PathFragment relative, Root root) {
-    // TODO: other root types, is this never a main repo?
-    if (relative.startsWith(new PathFragment(Label.EXTERNAL_PATH_PREFIX))) {
-      // This is an external path, use a different root.
-      if (root.isSourceRoot()) {
-        root = Root.asSourceRoot(root.getPath().getRelative(relative.subFragment(0, 2)));
-      } else {
-        boolean isMainRepo = false;
-        Path newExecRoot = root.getExecRoot().getRelative(relative.subFragment(0, 2));
-        root = Root.asDerivedRoot(
-            newExecRoot, newExecRoot.getRelative(root.getExecPath()), isMainRepo);
-      }
-      relative = relative.subFragment(2, relative.segmentCount());
-    }
     return getDerivedArtifact(getPackageDirectory().getRelative(relative), root);
   }
 
@@ -624,7 +610,7 @@
    * {@link #getUniqueDirectoryArtifact(String, PathFragment, Root)}) ensures that this is the case.
    */
   public PathFragment getPackageDirectory() {
-    return getLabel().getPackageIdentifier().getPackageFragment();
+    return getLabel().getPackageIdentifier().getSourceRoot();
   }
 
   /**
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 2e62eae..8f171a3 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
@@ -427,19 +427,6 @@
     return newManifest;
   }
 
-  private static PathFragment getRootRelativePath(Artifact artifact) {
-    Preconditions.checkArgument(artifact != null);
-    if (artifact.getRoot().isMainRepo()) {
-      return artifact.getRootRelativePath();
-    }
-
-    return new PathFragment(Label.EXTERNAL_PATH_PREFIX)
-        .getRelative(artifact.isSourceArtifact()
-            ? artifact.getRoot().getPath().getBaseName()
-            : artifact.getRoot().getExecRoot().getBaseName())
-        .getRelative(artifact.getRootRelativePath());
-  }
-
   /**
    * Returns the symlinks as a map from PathFragment to Artifact.
    *
@@ -456,7 +443,7 @@
     Map<PathFragment, Artifact> manifest = getSymlinksAsMap(checker);
     // Add unconditional artifacts (committed to inclusion on construction of runfiles).
     for (Artifact artifact : getUnconditionalArtifactsWithoutMiddlemen()) {
-      checker.put(manifest, Runfiles.getRootRelativePath(artifact), artifact);
+      checker.put(manifest, artifact.getRootRelativePath(), artifact);
     }
 
     // Add conditional artifacts (only included if they appear in a pruning manifest).
@@ -513,7 +500,7 @@
     // workspace.
     private boolean sawWorkspaceName;
 
-    ManifestBuilder(
+    public ManifestBuilder(
         PathFragment workspaceName, boolean legacyExternalRunfiles) {
       this.manifest = new HashMap<>();
       this.workspaceName = workspaceName;
@@ -524,27 +511,19 @@
     /**
      * Adds a map under the workspaceName.
      */
-    void addUnderWorkspace(
+    public void addUnderWorkspace(
         Map<PathFragment, Artifact> inputManifest, ConflictChecker checker) {
       for (Map.Entry<PathFragment, Artifact> entry : inputManifest.entrySet()) {
         PathFragment path = entry.getKey();
-        if (isUnderWorkspace(entry.getValue())) {
-          // For empty files (e.g., ../repo/__init__.py), we don't have an artifact so
-          // isUnderWorkspace returns true.
-          checker.put(manifest, workspaceName.getRelative(path).normalize(), entry.getValue());
+        if (isUnderWorkspace(path)) {
           sawWorkspaceName = true;
+          checker.put(manifest, workspaceName.getRelative(path), entry.getValue());
         } else {
-          PathFragment root = entry.getValue().getRoot().getPath().asFragment();
           if (legacyExternalRunfiles) {
-            // external/repo
-            PathFragment repoDir = root.subFragment(root.segmentCount() - 2, root.segmentCount());
-            // Turn ../repo/foo info wsname/external/repo/foo.
-            checker.put(
-                manifest, workspaceName.getRelative(repoDir).getRelative(path).normalize(),
-                entry.getValue());
+            checker.put(manifest, workspaceName.getRelative(path), entry.getValue());
           }
-          checker.put(
-              manifest, workspaceName.getRelative(entry.getKey()).normalize(), entry.getValue());
+          // Always add the non-legacy .runfiles/repo/whatever path.
+          checker.put(manifest, getExternalPath(path), entry.getValue());
         }
       }
     }
@@ -572,20 +551,17 @@
       return manifest;
     }
 
+    private PathFragment getExternalPath(PathFragment path) {
+      return checkForWorkspace(path.relativeTo(Label.EXTERNAL_PACKAGE_NAME));
+    }
+
     private PathFragment checkForWorkspace(PathFragment path) {
-      sawWorkspaceName = sawWorkspaceName
-          || path.getSegment(0).equals(workspaceName.getPathString());
+      sawWorkspaceName = sawWorkspaceName || path.getSegment(0).equals(workspaceName);
       return path;
     }
 
-    private static boolean isUnderWorkspace(@Nullable Artifact artifact) {
-      if (artifact == null) {
-        return true;
-      }
-      PathFragment root = artifact.getRoot().getPath().asFragment();
-      return root.segmentCount() < 2
-          || !root.getSegment(root.segmentCount() - 2).equals(
-              Label.EXTERNAL_PACKAGE_NAME.getPathString());
+    private static boolean isUnderWorkspace(PathFragment path) {
+      return !path.startsWith(Label.EXTERNAL_PACKAGE_NAME);
     }
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index 93e9e8d..b16a4a6 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -1001,7 +1001,7 @@
   /**
    * Directories in the output tree.
    *
-   * <p>The computation of the output directories should be a non-injective mapping from
+   * <p>The computation of the output directory should be a non-injective mapping from
    * BuildConfiguration instances to strings. The result should identify the aspects of the
    * configuration that should be reflected in the output file names.  Furthermore the
    * returned string must not contain shell metacharacters.
@@ -1067,15 +1067,15 @@
 
     Root getRoot(
         RepositoryName repositoryName, String outputDirName, BlazeDirectories directories) {
-      // e.g., execroot/repo1/../repo2 -> execroot/repo2
-      Path execRoot = directories.getExecRoot().getRelative(repositoryName.getPathUnderExecRoot());
-      // e.g., execroot/repo2/bazel-out/config
+      // e.g., execroot/repo1
+      Path execRoot = directories.getExecRoot();
+      // e.g., execroot/repo1/bazel-out/config/bin
       Path outputDir = execRoot.getRelative(directories.getRelativeOutputPath())
           .getRelative(outputDirName);
       if (middleman) {
         return INTERNER.intern(Root.middlemanRoot(execRoot, outputDir, repositoryName.isMain()));
       }
-      // e.g., [[execroot/repo2]/bazel-out/config/bin]
+      // e.g., [[execroot/repo1]/bazel-out/config/bin]
       return INTERNER.intern(
           Root.asDerivedRoot(execRoot, outputDir.getRelative(name), repositoryName.isMain()));
     }