diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java | 146 |
1 files changed, 117 insertions, 29 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; } } } |