Track empty directories with BAZEL_TRACK_SOURCE_DIRECTORIES
RecursiveFilesystemTraversalFunction did not emit a ResolvedFile for
empty directories and thus didn't track their existence at all since
they have no children that would track it implicitly.
This commit adds the tracking of empty directories for
DirectoryArtifactTraversalRequest only, which is used to implement the
BAZEL_TRACK_SOURCE_DIRECTORIES flag.
Also adds a basic test for the source directory tracking functionality.
Closes #15774.
PiperOrigin-RevId: 468804794
Change-Id: I2c06c05b335781234d4fa90f3d8c1e7fe6dd184a
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
index 8e3adbe..326e331 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
@@ -637,6 +637,11 @@
}
@Override
+ protected boolean emitEmptyDirectoryNodes() {
+ return true;
+ }
+
+ @Override
protected String errorInfo() {
return "Directory artifact " + artifact.prettyPrint();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FilesetTraversalRequest.java b/src/main/java/com/google/devtools/build/lib/skyframe/FilesetTraversalRequest.java
index 650c21b..e98ff06 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/FilesetTraversalRequest.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/FilesetTraversalRequest.java
@@ -65,6 +65,11 @@
}
@Override
+ protected boolean emitEmptyDirectoryNodes() {
+ return false;
+ }
+
+ @Override
protected final String errorInfo() {
return String.format(
"Fileset '%s' traversing %s '%s'",
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
index a50cc3f..de37dd5 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
@@ -620,6 +620,9 @@
paths = NestedSetBuilder.<ResolvedFile>stableOrder().addTransitive(children).add(root);
} else {
root = ResolvedFileFactory.directory(rootInfo.realPath);
+ if (traversal.emitEmptyDirectoryNodes() && paths.isEmpty()) {
+ paths.add(root);
+ }
}
return RecursiveFilesystemTraversalValue.of(root, paths.build());
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TraversalRequest.java b/src/main/java/com/google/devtools/build/lib/skyframe/TraversalRequest.java
index 55871f1..2073b72 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TraversalRequest.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TraversalRequest.java
@@ -53,6 +53,14 @@
protected abstract boolean skipTestingForSubpackage();
/**
+ * Whether to emit nodes for empty directories.
+ *
+ * <p>If this returns false, empty directories will not be represented in the result of the
+ * traversal.
+ */
+ protected abstract boolean emitEmptyDirectoryNodes();
+
+ /**
* Returns information to be attached to any error messages that may be reported.
*
* <p>This is purely informational and is not considered in equality.