Skip to content

Commit 94c519b

Browse files
ShreeM01tjgq
andauthored
Skip empty directories instead of throwing in prefetcher. (bazelbuild#17718)
While non-empty tree artifacts in the inputs to an action are expanded into the files they contain and omitted from the input mapping, empty tree artifacts are still present, as they signal the need to create the directory. Thus, the check added in 763f966 is incorrect. I'm explicitly skipping the empty tree artifacts in prefetchFiles() as otherwise they get skipped as a result of FileArtifactValue#isRemote() returning false for the FileArtifactValue associated with an empty tree artifact (even if it was produced remotely!), which is extremely subtle. Closes bazelbuild#17183. PiperOrigin-RevId: 501207095 Change-Id: Ib52727d6fdc6b7a291a61fba33914e57531fb1f4 Co-authored-by: Tiago Quelhas <[email protected]>
1 parent 885ae7e commit 94c519b

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java

+6
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,16 @@ protected ListenableFuture<Void> prefetchFiles(
197197
Map<SpecialArtifact, List<TreeFileArtifact>> trees = new HashMap<>();
198198
List<ActionInput> files = new ArrayList<>();
199199
for (ActionInput input : inputs) {
200+
// Source artifacts don't need to be fetched.
200201
if (input instanceof Artifact && ((Artifact) input).isSourceArtifact()) {
201202
continue;
202203
}
203204

205+
// Skip empty tree artifacts (non-empty tree artifacts should have already been expanded).
206+
if (input.isDirectory()) {
207+
continue;
208+
}
209+
204210
if (input instanceof TreeFileArtifact) {
205211
TreeFileArtifact treeFile = (TreeFileArtifact) input;
206212
SpecialArtifact treeArtifact = treeFile.getParent();

src/test/java/com/google/devtools/build/lib/remote/BuildWithoutTheBytesIntegrationTestBase.java

+52
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,58 @@ public void treeOutputsFromLocalFileSystem_works() throws Exception {
520520
assertValidOutputFile("out/foobar.txt", "file-1\nbar\n");
521521
}
522522

523+
@Test
524+
public void emptyTreeConsumedByLocalAction() throws Exception {
525+
// Disable remote execution so that the empty tree artifact is prefetched.
526+
addOptions("--modify_execution_info=Genrule=+no-remote-exec");
527+
setDownloadToplevel();
528+
writeOutputDirRule();
529+
write(
530+
"BUILD",
531+
"load(':output_dir.bzl', 'output_dir')",
532+
"output_dir(",
533+
" name = 'foo',",
534+
" manifest = ':manifest',",
535+
")",
536+
"genrule(",
537+
" name = 'foobar',",
538+
" srcs = [':foo'],",
539+
" outs = ['foobar.txt'],",
540+
" cmd = 'touch $@',",
541+
")");
542+
write("manifest"); // no files
543+
544+
buildTarget("//:foobar");
545+
waitDownloads();
546+
}
547+
548+
@Test
549+
public void multiplePackagePaths_buildsSuccessfully() throws Exception {
550+
write(
551+
"../a/src/BUILD",
552+
"genrule(",
553+
" name = 'foo',",
554+
" srcs = [],",
555+
" outs = ['out/foo.txt'],",
556+
" cmd = 'echo foo > $@',",
557+
")");
558+
write(
559+
"BUILD",
560+
"genrule(",
561+
" name = 'foobar',",
562+
" srcs = ['//src:foo'],",
563+
" outs = ['out/foobar.txt'],",
564+
" cmd = 'cat $(location //src:foo) > $@ && echo bar >> $@',",
565+
")");
566+
addOptions("--package_path=%workspace%:%workspace%/../a");
567+
setDownloadToplevel();
568+
569+
buildTarget("//:foobar");
570+
waitDownloads();
571+
572+
assertValidOutputFile("out/foobar.txt", "foo\nbar\n");
573+
}
574+
523575
@Test
524576
public void incrementalBuild_deleteOutputsInUnwritableParentDirectory() throws Exception {
525577
write(

0 commit comments

Comments
 (0)