Only depend on the WORKSPACE file for external files that are under the external/ directory, i.e. were created by Bazel.
This avoids a cycle that arose when a file is load()ed from the WORKSPACE file that is reached through a symlink to an external directory:
* The WORKSPACE file depends on the package lookup node of the .bzl file
* The package lookup node (transitively) depends on wherever the symlink points
* The target of the symlink is an external file and as such, it depends on the WORKSPACE file
This will probably be, erm, interesting to solve when we get as far as to load stuff from external repositories in the WORKSPACE file, but we are just not there yet.
--
MOS_MIGRATED_REVID=110344658
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java
index ca7de18..873d48d 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java
@@ -33,6 +33,7 @@
import com.google.common.collect.Sets;
import com.google.common.testing.EqualsTester;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.events.NullEventHandler;
import com.google.devtools.build.lib.events.StoredEventHandler;
@@ -280,7 +281,6 @@
getFilesSeenAndAssertValueChangesIfContentsOfFileChanges("../outside", true, "a"));
assertThat(seenFiles)
.containsExactly(
- rootedPath("WORKSPACE"),
rootedPath("a"),
rootedPath(""),
RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.EMPTY_FRAGMENT),
@@ -298,7 +298,6 @@
getFilesSeenAndAssertValueChangesIfContentsOfFileChanges("/absolute", true, "a"));
assertThat(seenFiles)
.containsExactly(
- rootedPath("WORKSPACE"),
rootedPath("a"),
rootedPath(""),
RootedPath.toRootedPath(fs.getRootDirectory(), PathFragment.EMPTY_FRAGMENT),
@@ -306,6 +305,30 @@
}
@Test
+ public void testAbsoluteSymlinkToExternal() throws Exception {
+ String externalPath =
+ outputBase.getRelative(Label.EXTERNAL_PATH_PREFIX).getRelative("a/b").getPathString();
+ symlink("a", externalPath);
+ file("b");
+ file(externalPath);
+ Set<RootedPath> seenFiles = Sets.newHashSet();
+ seenFiles.addAll(getFilesSeenAndAssertValueChangesIfContentsOfFileChanges("b", false, "a"));
+ seenFiles.addAll(
+ getFilesSeenAndAssertValueChangesIfContentsOfFileChanges(externalPath, true, "a"));
+ Path root = fs.getRootDirectory();
+ assertThat(seenFiles)
+ .containsExactly(
+ rootedPath("WORKSPACE"),
+ rootedPath("a"),
+ rootedPath(""),
+ RootedPath.toRootedPath(root, PathFragment.EMPTY_FRAGMENT),
+ RootedPath.toRootedPath(root, new PathFragment("output_base")),
+ RootedPath.toRootedPath(root, new PathFragment("output_base/external")),
+ RootedPath.toRootedPath(root, new PathFragment("output_base/external/a")),
+ RootedPath.toRootedPath(root, new PathFragment("output_base/external/a/b")));
+ }
+
+ @Test
public void testSymlinkAsAncestor() throws Exception {
file("a/b/c/d");
symlink("f", "a/b/c");