diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
5 files changed, 279 insertions, 85 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java b/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java index 92cf7a975f..f3440398a8 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java +++ b/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java @@ -14,42 +14,51 @@ package com.google.devtools.build.lib.actions; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.vfs.PathFragment; +import java.util.Objects; +import javax.annotation.Nullable; /** Definition of a symlink in the output tree of a Fileset rule. */ -public final class FilesetOutputSymlink { +public abstract class FilesetOutputSymlink { private static final String STRIPPED_METADATA = "<stripped-for-testing>"; + private final PathFragment name; + private final PathFragment target; + private final String metadata; + + FilesetOutputSymlink(PathFragment name, PathFragment target, String metadata) { + this.name = Preconditions.checkNotNull(name); + this.target = Preconditions.checkNotNull(target); + this.metadata = Preconditions.checkNotNull(metadata); + } /** Final name of the symlink relative to the Fileset's output directory. */ - public final PathFragment name; + public PathFragment getName() { + return name; + } - /** Target of the symlink. Depending on FilesetEntry.symlinks it may be relative or absolute. */ - public final PathFragment target; + /** + * Target of the symlink. This may be relative to the target's location if the target itself is a + * relative symlink. We can override it by using FilesetEntry.symlinks = 'dereference'. + */ + public PathFragment getTargetPath() { + return target; + } /** Opaque metadata about the link and its target; should change if either of them changes. */ - public final String metadata; - - @VisibleForTesting - public FilesetOutputSymlink(PathFragment name, PathFragment target) { - this.name = name; - this.target = target; - this.metadata = STRIPPED_METADATA; + public String getMetadata() { + return metadata; } + /** true if the target is a generated artifact */ + public abstract boolean isGeneratedTarget(); + /** - * @param name relative path under the Fileset's output directory, including FilesetEntry.destdir - * with and FilesetEntry.strip_prefix applied (if applicable) - * @param target relative or absolute value of the link - * @param metadata opaque metadata about the link and its target; should change if either the link - * or its target changes + * returns the target artifact if it's generated {@link #isGeneratedTarget() == true}, or null + * otherwise. */ - public FilesetOutputSymlink(PathFragment name, PathFragment target, String metadata) { - this.name = Preconditions.checkNotNull(name); - this.target = Preconditions.checkNotNull(target); - this.metadata = Preconditions.checkNotNull(metadata); - } + @Nullable + public abstract FileArtifactValue getTargetArtifactValue(); @Override public boolean equals(Object obj) { @@ -60,22 +69,101 @@ public final class FilesetOutputSymlink { return false; } FilesetOutputSymlink o = (FilesetOutputSymlink) obj; - return name.equals(o.name) && target.equals(o.target) && metadata.equals(o.metadata); + return getName().equals(o.getName()) + && getTargetPath().equals(o.getTargetPath()) + && getMetadata().equals(o.getMetadata()) + && isGeneratedTarget() == o.isGeneratedTarget() + && Objects.equals(getTargetArtifactValue(), o.getTargetArtifactValue()); } @Override public int hashCode() { - return Objects.hashCode(name, target, metadata); + return Objects.hash( + getName(), getTargetPath(), getMetadata(), isGeneratedTarget(), getTargetArtifactValue()); } @Override public String toString() { - if (metadata.equals(STRIPPED_METADATA)) { - return String.format("FilesetOutputSymlink(%s -> %s)", - name.getPathString(), target.getPathString()); + if (getMetadata().equals(STRIPPED_METADATA)) { + return String.format( + "FilesetOutputSymlink(%s -> %s)", + getName().getPathString(), getTargetPath().getPathString()); } else { - return String.format("FilesetOutputSymlink(%s -> %s | metadata=%s)", - name.getPathString(), target.getPathString(), metadata); + return String.format( + "FilesetOutputSymlink(%s -> %s | metadata=%s)", + getName().getPathString(), getTargetPath().getPathString(), getMetadata()); + } + } + + @VisibleForTesting + public static FilesetOutputSymlink createForTesting(PathFragment name, PathFragment target) { + return new SourceOutputSymlink(name, target, STRIPPED_METADATA); + } + + /** + * @param name relative path under the Fileset's output directory, including FilesetEntry.destdir + * with and FilesetEntry.strip_prefix applied (if applicable) + * @param target relative or absolute value of the link + * @param metadata opaque metadata about the link and its target; should change if either the link + * or its target changes + */ + public static FilesetOutputSymlink createForSourceTarget( + PathFragment name, PathFragment target, String metadata) { + return new SourceOutputSymlink(name, target, metadata); + } + + /** + * @param name relative path under the Fileset's output directory, including FilesetEntry.destdir + * with and FilesetEntry.strip_prefix applied (if applicable) + * @param target relative or absolute value of the link + * @param metadata opaque metadata about the link and its target; should change if either the link + * or its target changes + * @param fileArtifactValue the {@link FileArtifactValue} corresponding to the target. + */ + public static FilesetOutputSymlink createForDerivedTarget( + PathFragment name, + PathFragment target, + String metadata, + @Nullable FileArtifactValue fileArtifactValue) { + return new DerivedOutputSymlink(name, target, metadata, fileArtifactValue); + } + + private static class DerivedOutputSymlink extends FilesetOutputSymlink { + private final FileArtifactValue fileArtifactValue; + + DerivedOutputSymlink( + PathFragment name, + PathFragment target, + String metadata, + FileArtifactValue fileArtifactValue) { + super(name, target, metadata); + this.fileArtifactValue = fileArtifactValue; + } + + @Override + public boolean isGeneratedTarget() { + return true; + } + + @Override + public FileArtifactValue getTargetArtifactValue() { + return fileArtifactValue; + } + } + + private static class SourceOutputSymlink extends FilesetOutputSymlink { + SourceOutputSymlink(PathFragment name, PathFragment target, String metadata) { + super(name, target, metadata); + } + + @Override + public boolean isGeneratedTarget() { + return false; + } + + @Override + public FileArtifactValue getTargetArtifactValue() { + return null; } } } diff --git a/src/main/java/com/google/devtools/build/lib/exec/FilesetManifest.java b/src/main/java/com/google/devtools/build/lib/exec/FilesetManifest.java index c48674a913..1b35631108 100644 --- a/src/main/java/com/google/devtools/build/lib/exec/FilesetManifest.java +++ b/src/main/java/com/google/devtools/build/lib/exec/FilesetManifest.java @@ -78,8 +78,8 @@ public final class FilesetManifest { LinkedHashMap<PathFragment, String> entries = new LinkedHashMap<>(); Map<PathFragment, String> relativeLinks = new HashMap<>(); for (FilesetOutputSymlink outputSymlink : outputSymlinks) { - PathFragment fullLocation = targetPrefix.getRelative(outputSymlink.name); - String artifact = outputSymlink.target.getPathString(); + PathFragment fullLocation = targetPrefix.getRelative(outputSymlink.getName()); + String artifact = outputSymlink.getTargetPath().getPathString(); artifact = artifact.isEmpty() ? null : artifact; addSymlinkEntry(artifact, fullLocation, relSymlinkbehavior, entries, relativeLinks); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunction.java index aa4fa7befb..8f4901fbb1 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunction.java @@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.FilesetOutputSymlink; import com.google.devtools.build.lib.actions.FilesetTraversalParams; import com.google.devtools.build.lib.actions.FilesetTraversalParams.DirectTraversal; @@ -59,7 +60,8 @@ public final class FilesetEntryFunction implements SkyFunction { // Create the set of excluded files. Only top-level files can be excluded, i.e. ones that are // directly under the root if the root is a directory. - Set<String> exclusions = createExclusionSet(t.getExcludedFiles()); + Set<String> exclusions = + Sets.filter(t.getExcludedFiles(), e -> PathFragment.create(e).segmentCount() == 1); // The map of output symlinks. Each key is the path of a output symlink that the Fileset must // create, relative to the Fileset.out directory, and each value specifies extra information @@ -79,7 +81,7 @@ public final class FilesetEntryFunction implements SkyFunction { for (SkyKey nestedKey : nestedKeys) { FilesetEntryValue nested = (FilesetEntryValue) results.get(nestedKey); for (FilesetOutputSymlink s : nested.getSymlinks()) { - if (!exclusions.contains(s.name.getPathString())) { + if (!exclusions.contains(s.getName().getPathString())) { maybeStoreSymlink(s, t.getDestPath(), outputSymlinks); } } @@ -189,7 +191,15 @@ public final class FilesetEntryFunction implements SkyFunction { // Metadata field must be present. It can only be absent when stripped by tests. String metadata = Integer.toHexString(f.getMetadataHash()); - maybeStoreSymlink(linkName, targetName, metadata, t.getDestPath(), outputSymlinks); + + maybeStoreSymlink( + linkName, + targetName, + metadata, + t.getDestPath(), + direct.isGenerated(), + f.getValueForDerivedArtifacts(), + outputSymlinks); } } @@ -201,7 +211,14 @@ public final class FilesetEntryFunction implements SkyFunction { FilesetOutputSymlink nestedLink, PathFragment destPath, Map<PathFragment, FilesetOutputSymlink> result) { - maybeStoreSymlink(nestedLink.name, nestedLink.target, nestedLink.metadata, destPath, result); + maybeStoreSymlink( + nestedLink.getName(), + nestedLink.getTargetPath(), + nestedLink.getMetadata(), + destPath, + nestedLink.isGeneratedTarget(), + nestedLink.getTargetArtifactValue(), + result); } /** Stores an output symlink unless it would overwrite an existing one. */ @@ -210,22 +227,21 @@ public final class FilesetEntryFunction implements SkyFunction { PathFragment linkTarget, String metadata, PathFragment destPath, + boolean isGenerated, + FileArtifactValue targetArtifactValue, Map<PathFragment, FilesetOutputSymlink> result) { linkName = destPath.getRelative(linkName); if (!result.containsKey(linkName)) { - result.put(linkName, new FilesetOutputSymlink(linkName, linkTarget, metadata)); - } - } - - private static Set<String> createExclusionSet(Set<String> input) { - return Sets.filter(input, new Predicate<String>() { - @Override - public boolean apply(String e) { - // Keep the top-level exclusions only. Do not look for "/" but count the path segments - // instead, in anticipation of future Windows support. - return PathFragment.create(e).segmentCount() == 1; + if (isGenerated) { + result.put( + linkName, + FilesetOutputSymlink.createForDerivedTarget( + linkName, linkTarget, metadata, targetArtifactValue)); + } else { + result.put( + linkName, FilesetOutputSymlink.createForSourceTarget(linkName, linkTarget, metadata)); } - }); + } } @Override 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 d91e46e805..818d2276eb 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 @@ -203,13 +203,19 @@ public final class RecursiveFilesystemTraversalFunction implements SkyFunction { final FileStateValue metadata; @Nullable final RootedPath realPath; @Nullable final PathFragment unresolvedSymlinkTarget; - - FileInfo(FileType type, FileStateValue metadata, @Nullable RootedPath realPath, - @Nullable PathFragment unresolvedSymlinkTarget) { + @Nullable final FileArtifactValue fileArtifactValue; + + FileInfo( + FileType type, + FileStateValue metadata, + @Nullable RootedPath realPath, + @Nullable PathFragment unresolvedSymlinkTarget, + @Nullable FileArtifactValue fileArtifactValue) { this.type = Preconditions.checkNotNull(type); this.metadata = Preconditions.checkNotNull(metadata); this.realPath = realPath; this.unresolvedSymlinkTarget = unresolvedSymlinkTarget; + this.fileArtifactValue = fileArtifactValue; } @Override @@ -226,7 +232,7 @@ public final class RecursiveFilesystemTraversalFunction implements SkyFunction { private static FileInfo lookUpFileInfo(Environment env, TraversalRequest traversal) throws MissingDepException, IOException, InterruptedException { if (traversal.isRootGenerated) { - byte[] digest = null; + FileArtifactValue fsVal = null; if (traversal.root.getOutputArtifact() != null) { Artifact artifact = traversal.root.getOutputArtifact(); SkyKey artifactKey = ArtifactSkyKey.key(artifact, true); @@ -236,11 +242,9 @@ public final class RecursiveFilesystemTraversalFunction implements SkyFunction { } if (value instanceof FileArtifactValue) { - FileArtifactValue fsVal = (FileArtifactValue) value; - digest = fsVal.getDigest(); + fsVal = (FileArtifactValue) value; } else { - return new FileInfo( - FileType.NONEXISTENT, null, null, null); + return new FileInfo(FileType.NONEXISTENT, null, null, null, null); } } @@ -269,10 +273,15 @@ public final class RecursiveFilesystemTraversalFunction implements SkyFunction { path.resolveSymbolicLinks()); type = followStat.isFile() ? FileType.SYMLINK_TO_FILE : FileType.SYMLINK_TO_DIRECTORY; } - return new FileInfo(type, - FileStateValue.createWithStatNoFollow(traversal.root.asRootedPath(), - new StatWithDigest(noFollowStat, digest), null), - realPath, unresolvedLinkTarget); + return new FileInfo( + type, + FileStateValue.createWithStatNoFollow( + traversal.root.asRootedPath(), + new StatWithDigest(noFollowStat, fsVal != null ? fsVal.getDigest() : null), + null), + realPath, + unresolvedLinkTarget, + fsVal); } else { // Stat the file. FileValue fileValue = @@ -292,14 +301,20 @@ public final class RecursiveFilesystemTraversalFunction implements SkyFunction { } else { type = fileValue.isDirectory() ? FileType.DIRECTORY : FileType.FILE; } - return new FileInfo(type, fileValue.realFileStateValue(), - fileValue.realRootedPath(), unresolvedLinkTarget); + return new FileInfo( + type, + fileValue.realFileStateValue(), + fileValue.realRootedPath(), + unresolvedLinkTarget, + null); } else { // If it doesn't exist, or it's a dangling symlink, we still want to handle that gracefully. return new FileInfo( fileValue.isSymlink() ? FileType.DANGLING_SYMLINK : FileType.NONEXISTENT, - fileValue.realFileStateValue(), null, - fileValue.isSymlink() ? fileValue.getUnresolvedLinkTarget() : null); + fileValue.realFileStateValue(), + null, + fileValue.isSymlink() ? fileValue.getUnresolvedLinkTarget() : null, + null); } } } @@ -436,7 +451,8 @@ public final class RecursiveFilesystemTraversalFunction implements SkyFunction { Preconditions.checkState(info.type.isSymlink() && !info.type.exists(), "{%s} {%s}", linkName, info.type); return RecursiveFilesystemTraversalValue.of( - ResolvedFileFactory.danglingSymlink(linkName, info.unresolvedSymlinkTarget, info.metadata)); + ResolvedFileFactory.danglingSymlink( + linkName, info.unresolvedSymlinkTarget, info.metadata, info.fileArtifactValue)); } /** @@ -452,10 +468,14 @@ public final class RecursiveFilesystemTraversalFunction implements SkyFunction { if (info.type.isSymlink()) { return RecursiveFilesystemTraversalValue.of( ResolvedFileFactory.symlinkToFile( - info.realPath, path, info.unresolvedSymlinkTarget, info.metadata)); + info.realPath, + path, + info.unresolvedSymlinkTarget, + info.metadata, + info.fileArtifactValue)); } else { return RecursiveFilesystemTraversalValue.of( - ResolvedFileFactory.regularFile(path, info.metadata)); + ResolvedFileFactory.regularFile(path, info.metadata, info.fileArtifactValue)); } } @@ -474,7 +494,8 @@ public final class RecursiveFilesystemTraversalFunction implements SkyFunction { rootInfo.realPath, traversal.root.asRootedPath(), rootInfo.unresolvedSymlinkTarget, - hashDirectorySymlink(children, rootInfo.metadata.hashCode())); + hashDirectorySymlink(children, rootInfo.metadata.hashCode()), + rootInfo.fileArtifactValue); paths = NestedSetBuilder.<ResolvedFile>stableOrder().addTransitive(children).add(root); } else { root = ResolvedFileFactory.directory(rootInfo.realPath); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java index 05bce4b1d4..0b91f51eea 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java @@ -18,6 +18,7 @@ import com.google.common.base.Objects; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Interner; +import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.FileStateValue; import com.google.devtools.build.lib.actions.FilesetTraversalParams.DirectTraversalRoot; import com.google.devtools.build.lib.actions.FilesetTraversalParams.PackageBoundaryMode; @@ -262,16 +263,19 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { private static final class RegularFile implements ResolvedFile { private final RootedPath path; @Nullable private final FileStateValue metadata; + @Nullable private final FileArtifactValue artifactValue; /** C'tor for {@link #stripMetadataForTesting()}. */ private RegularFile(RootedPath path) { this.path = Preconditions.checkNotNull(path); this.metadata = null; + this.artifactValue = null; } - RegularFile(RootedPath path, FileStateValue metadata) { + RegularFile(RootedPath path, FileStateValue metadata, FileArtifactValue artifactValue) { this.path = Preconditions.checkNotNull(path); this.metadata = Preconditions.checkNotNull(metadata); + this.artifactValue = artifactValue; } @Override @@ -323,6 +327,11 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { } @Override + public FileArtifactValue getValueForDerivedArtifacts() { + return artifactValue; + } + + @Override public PathFragment getTargetInSymlinkTree(boolean followSymlinks) { return path.asPath().asFragment(); } @@ -382,6 +391,11 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { } @Override + public FileArtifactValue getValueForDerivedArtifacts() { + return null; + } + + @Override public PathFragment getTargetInSymlinkTree(boolean followSymlinks) { return path.asPath().asFragment(); } @@ -390,21 +404,28 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { private static final class DanglingSymlink implements ResolvedFile { private final Symlink symlink; @Nullable private final FileStateValue metadata; + @Nullable private final FileArtifactValue artifactValue; private DanglingSymlink(Symlink symlink) { this.symlink = symlink; this.metadata = null; + this.artifactValue = null; } private DanglingSymlink(RootedPath linkNamePath, PathFragment linkTargetPath) { this.symlink = new Symlink(linkNamePath, linkTargetPath); this.metadata = null; + this.artifactValue = null; } - DanglingSymlink(RootedPath linkNamePath, PathFragment linkTargetPath, - FileStateValue metadata) { + DanglingSymlink( + RootedPath linkNamePath, + PathFragment linkTargetPath, + FileStateValue metadata, + @Nullable FileArtifactValue fileArtifactValue) { this.symlink = new Symlink(linkNamePath, linkTargetPath); this.metadata = Preconditions.checkNotNull(metadata); + this.artifactValue = fileArtifactValue; } @Override @@ -457,6 +478,11 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { } @Override + public FileArtifactValue getValueForDerivedArtifacts() { + return artifactValue; + } + + @Override public PathFragment getTargetInSymlinkTree(boolean followSymlinks) throws DanglingSymlinkException { if (followSymlinks) { @@ -472,12 +498,14 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { private final RootedPath path; @Nullable private final FileStateValue metadata; private final Symlink symlink; + @Nullable private final FileArtifactValue fileArtifactValue; /** C'tor for {@link #stripMetadataForTesting()}. */ private SymlinkToFile(RootedPath targetPath, Symlink symlink) { this.path = Preconditions.checkNotNull(targetPath); this.metadata = null; this.symlink = Preconditions.checkNotNull(symlink); + this.fileArtifactValue = null; } private SymlinkToFile( @@ -485,13 +513,19 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { this.path = Preconditions.checkNotNull(targetPath); this.metadata = null; this.symlink = new Symlink(linkNamePath, linkTargetPath); + this.fileArtifactValue = null; } - SymlinkToFile(RootedPath targetPath, RootedPath linkNamePath, - PathFragment linkTargetPath, FileStateValue metadata) { + SymlinkToFile( + RootedPath targetPath, + RootedPath linkNamePath, + PathFragment linkTargetPath, + FileStateValue metadata, + @Nullable FileArtifactValue fileArtifactValue) { this.path = Preconditions.checkNotNull(targetPath); this.metadata = Preconditions.checkNotNull(metadata); this.symlink = new Symlink(linkNamePath, linkTargetPath); + this.fileArtifactValue = fileArtifactValue; } @Override @@ -544,6 +578,11 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { } @Override + public FileArtifactValue getValueForDerivedArtifacts() { + return fileArtifactValue; + } + + @Override public PathFragment getTargetInSymlinkTree(boolean followSymlinks) { return followSymlinks ? path.asPath().asFragment() : symlink.unresolvedLinkTarget; } @@ -553,12 +592,14 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { private final RootedPath path; @Nullable private final int metadataHash; private final Symlink symlink; + @Nullable private final FileArtifactValue fileArtifactValue; /** C'tor for {@link #stripMetadataForTesting()}. */ private SymlinkToDirectory(RootedPath targetPath, Symlink symlink) { this.path = Preconditions.checkNotNull(targetPath); this.metadataHash = 0; this.symlink = symlink; + this.fileArtifactValue = null; } private SymlinkToDirectory( @@ -566,13 +607,19 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { this.path = Preconditions.checkNotNull(targetPath); this.metadataHash = 0; this.symlink = new Symlink(linkNamePath, linkValue); + this.fileArtifactValue = null; } - SymlinkToDirectory(RootedPath targetPath, RootedPath linkNamePath, - PathFragment linkValue, int metadataHash) { + SymlinkToDirectory( + RootedPath targetPath, + RootedPath linkNamePath, + PathFragment linkValue, + int metadataHash, + @Nullable FileArtifactValue fileArtifactValue) { this.path = Preconditions.checkNotNull(targetPath); this.metadataHash = metadataHash; this.symlink = new Symlink(linkNamePath, linkValue); + this.fileArtifactValue = fileArtifactValue; } @Override @@ -625,6 +672,11 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { } @Override + public FileArtifactValue getValueForDerivedArtifacts() { + return fileArtifactValue; + } + + @Override public PathFragment getTargetInSymlinkTree(boolean followSymlinks) { return followSymlinks ? path.asPath().asFragment() : symlink.unresolvedLinkTarget; } @@ -633,27 +685,41 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { static final class ResolvedFileFactory { private ResolvedFileFactory() {} - public static ResolvedFile regularFile(RootedPath path, FileStateValue metadata) { - return new RegularFile(path, metadata); + public static ResolvedFile regularFile( + RootedPath path, FileStateValue metadata, FileArtifactValue fileArtifactValue) { + return new RegularFile(path, metadata, fileArtifactValue); } public static ResolvedFile directory(RootedPath path) { return new Directory(path); } - public static ResolvedFile symlinkToFile(RootedPath targetPath, RootedPath linkNamePath, - PathFragment linkTargetPath, FileStateValue metadata) { - return new SymlinkToFile(targetPath, linkNamePath, linkTargetPath, metadata); + public static ResolvedFile symlinkToFile( + RootedPath targetPath, + RootedPath linkNamePath, + PathFragment linkTargetPath, + FileStateValue metadata, + FileArtifactValue fileArtifactValue) { + return new SymlinkToFile( + targetPath, linkNamePath, linkTargetPath, metadata, fileArtifactValue); } - public static ResolvedFile symlinkToDirectory(RootedPath targetPath, - RootedPath linkNamePath, PathFragment linkValue, int metadataHash) { - return new SymlinkToDirectory(targetPath, linkNamePath, linkValue, metadataHash); + public static ResolvedFile symlinkToDirectory( + RootedPath targetPath, + RootedPath linkNamePath, + PathFragment linkValue, + int metadataHash, + FileArtifactValue fileArtifactValue) { + return new SymlinkToDirectory( + targetPath, linkNamePath, linkValue, metadataHash, fileArtifactValue); } - public static ResolvedFile danglingSymlink(RootedPath linkNamePath, PathFragment linkValue, - FileStateValue metadata) { - return new DanglingSymlink(linkNamePath, linkValue, metadata); + public static ResolvedFile danglingSymlink( + RootedPath linkNamePath, + PathFragment linkValue, + FileStateValue metadata, + FileArtifactValue fileArtifactValue) { + return new DanglingSymlink(linkNamePath, linkValue, metadata, fileArtifactValue); } } @@ -726,6 +792,9 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { */ PathFragment getTargetInSymlinkTree(boolean followSymlinks) throws DanglingSymlinkException; + @Nullable + FileArtifactValue getValueForDerivedArtifacts(); + /** * Returns a copy of this object with the metadata stripped away. * |