Support Fileset expansion inside Runfiles during input expansion.
RELNOTES: None
PiperOrigin-RevId: 252954464
diff --git a/src/main/java/com/google/devtools/build/lib/exec/SpawnInputExpander.java b/src/main/java/com/google/devtools/build/lib/exec/SpawnInputExpander.java
index baad566..5f0cc2f 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/SpawnInputExpander.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/SpawnInputExpander.java
@@ -33,6 +33,7 @@
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
@@ -44,7 +45,7 @@
* laid out.
*/
public class SpawnInputExpander {
- @VisibleForTesting static final ActionInput EMPTY_FILE = new EmptyActionInput("/dev/null");
+ public static final ActionInput EMPTY_FILE = new EmptyActionInput("/dev/null");
private final Path execRoot;
private final boolean strict;
@@ -133,6 +134,9 @@
location.getRelative(((TreeFileArtifact) input).getParentRelativePath()),
input);
}
+ } else if (localArtifact.isFileset()) {
+ addFilesetManifest(
+ location, localArtifact, artifactExpander.getFileset(localArtifact), inputMap);
} else {
if (strict) {
failIfDirectory(actionFileCache, localArtifact);
@@ -146,6 +150,25 @@
}
}
+ /** Adds runfiles inputs from runfilesSupplier to inputMappings. */
+ public Map<PathFragment, ActionInput> addRunfilesToInputs(
+ RunfilesSupplier runfilesSupplier,
+ MetadataProvider actionFileCache,
+ ArtifactExpander artifactExpander,
+ ArtifactPathResolver pathResolver,
+ boolean expandTreeArtifactsInRunfiles)
+ throws IOException {
+ Map<PathFragment, ActionInput> inputMap = new HashMap<>();
+ addRunfilesToInputs(
+ inputMap,
+ runfilesSupplier,
+ actionFileCache,
+ artifactExpander,
+ pathResolver,
+ expandTreeArtifactsInRunfiles);
+ return inputMap;
+ }
+
private static void failIfDirectory(MetadataProvider actionFileCache, ActionInput input)
throws IOException {
FileArtifactValue metadata = actionFileCache.getMetadata(input);
@@ -160,10 +183,20 @@
Map<PathFragment, ActionInput> inputMappings)
throws IOException {
for (Artifact fileset : filesetMappings.keySet()) {
- ImmutableList<FilesetOutputSymlink> outputSymlinks = filesetMappings.get(fileset);
- FilesetManifest filesetManifest =
- FilesetManifest.constructFilesetManifest(
- outputSymlinks, fileset.getExecPath(), relSymlinkBehavior);
+ addFilesetManifest(
+ fileset.getExecPath(), fileset, filesetMappings.get(fileset), inputMappings);
+ }
+ }
+
+ void addFilesetManifest(
+ PathFragment location,
+ Artifact filesetArtifact,
+ ImmutableList<FilesetOutputSymlink> filesetLinks,
+ Map<PathFragment, ActionInput> inputMappings)
+ throws IOException {
+ Preconditions.checkState(filesetArtifact.isFileset(), filesetArtifact);
+ FilesetManifest filesetManifest =
+ FilesetManifest.constructFilesetManifest(filesetLinks, location, relSymlinkBehavior);
for (Map.Entry<PathFragment, String> mapping : filesetManifest.getEntries().entrySet()) {
String value = mapping.getValue();
@@ -173,7 +206,6 @@
: ActionInputHelper.fromPath(execRoot.getRelative(value).getPathString());
addMapping(inputMappings, mapping.getKey(), artifact);
}
- }
}
private void addInputs(
diff --git a/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java b/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java
index a9c22c2..153f44e 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java
@@ -103,6 +103,43 @@
}
@Test
+ public void testRunfilesWithFileset() throws Exception {
+ Artifact artifact = createFilesetArtifact("foo/biz/fs_out");
+ Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
+ RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
+ FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
+ mockCache.put(
+ artifact,
+ FileArtifactValue.createNormalFile(
+ FAKE_DIGEST, /*proxy=*/ null, 0L, /*isShareable=*/ true));
+
+ ArtifactExpander filesetExpander =
+ new ArtifactExpander() {
+ @Override
+ public void expand(Artifact artifact, Collection<? super Artifact> output) {
+ throw new IllegalStateException("Unexpected tree expansion");
+ }
+
+ @Override
+ public ImmutableList<FilesetOutputSymlink> getFileset(Artifact artifact) {
+ return ImmutableList.of(
+ FilesetOutputSymlink.createForTesting(
+ PathFragment.create("zizz"),
+ PathFragment.create("/foo/fake_exec/xyz/zizz"),
+ PathFragment.create("/foo/fake_exec/")));
+ }
+ };
+
+ expander.addRunfilesToInputs(
+ inputMappings, supplier, mockCache, filesetExpander, ArtifactPathResolver.IDENTITY, true);
+ assertThat(inputMappings).hasSize(1);
+ assertThat(inputMappings)
+ .containsEntry(
+ PathFragment.create("runfiles/workspace/foo/biz/fs_out/zizz"),
+ ActionInputHelper.fromPath("/root/xyz/zizz"));
+ }
+
+ @Test
public void testRunfilesDirectoryStrict() {
Artifact artifact =
ActionsTestUtil.createArtifact(
@@ -327,6 +364,15 @@
}
private SpecialArtifact createTreeArtifact(String relPath) throws IOException {
+ return createSpecialArtifact(relPath, SpecialArtifactType.TREE);
+ }
+
+ private SpecialArtifact createFilesetArtifact(String relPath) throws IOException {
+ return createSpecialArtifact(relPath, SpecialArtifactType.FILESET);
+ }
+
+ private SpecialArtifact createSpecialArtifact(String relPath, SpecialArtifactType type)
+ throws IOException {
Path outputDir = execRoot.getRelative("out");
Path outputPath = outputDir.getRelative(relPath);
outputPath.createDirectoryAndParents();
@@ -335,7 +381,7 @@
derivedRoot,
derivedRoot.getExecPath().getRelative(derivedRoot.getRoot().relativize(outputPath)),
ActionsTestUtil.NULL_ARTIFACT_OWNER,
- SpecialArtifactType.TREE);
+ type);
}
@Test