diff --git a/src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java b/src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java index 8b96ded0a78712..ed261abfde5210 100644 --- a/src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java +++ b/src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java @@ -13,7 +13,6 @@ // limitations under the License. package com.google.devtools.build.lib.remote; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; import static com.google.devtools.build.lib.remote.util.RxFutures.toCompletable; @@ -183,13 +182,16 @@ protected ListenableFuture prefetchFiles( Map> trees = new HashMap<>(); List files = new ArrayList<>(); for (ActionInput input : inputs) { - checkArgument(!input.isDirectory(), "cannot prefetch a directory"); - // Source artifacts don't need to be fetched. if (input instanceof Artifact && ((Artifact) input).isSourceArtifact()) { continue; } + // Skip empty tree artifacts (non-empty tree artifacts should have already been expanded). + if (input.isDirectory()) { + continue; + } + if (input instanceof TreeFileArtifact) { TreeFileArtifact treeFile = (TreeFileArtifact) input; SpecialArtifact treeArtifact = treeFile.getParent(); diff --git a/src/test/java/com/google/devtools/build/lib/remote/BuildWithoutTheBytesIntegrationTestBase.java b/src/test/java/com/google/devtools/build/lib/remote/BuildWithoutTheBytesIntegrationTestBase.java index 50c42e13168699..942f5eae1c44bf 100644 --- a/src/test/java/com/google/devtools/build/lib/remote/BuildWithoutTheBytesIntegrationTestBase.java +++ b/src/test/java/com/google/devtools/build/lib/remote/BuildWithoutTheBytesIntegrationTestBase.java @@ -579,6 +579,31 @@ public void treeOutputsFromLocalFileSystem_works() throws Exception { assertValidOutputFile("out/foobar.txt", "file-1\nbar\n"); } + @Test + public void emptyTreeConsumedByLocalAction() throws Exception { + // Disable remote execution so that the empty tree artifact is prefetched. + addOptions("--modify_execution_info=Genrule=+no-remote-exec"); + setDownloadToplevel(); + writeOutputDirRule(); + write( + "BUILD", + "load(':output_dir.bzl', 'output_dir')", + "output_dir(", + " name = 'foo',", + " manifest = ':manifest',", + ")", + "genrule(", + " name = 'foobar',", + " srcs = [':foo'],", + " outs = ['foobar.txt'],", + " cmd = 'touch $@',", + ")"); + write("manifest"); // no files + + buildTarget("//:foobar"); + waitDownloads(); + } + @Test public void multiplePackagePaths_buildsSuccessfully() throws Exception { write(