diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build')
12 files changed, 207 insertions, 69 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java index 0b272fbbcb..c241c5698a 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java +++ b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java @@ -428,10 +428,13 @@ public abstract class AbstractAction implements Action, SkylarkValue { for (Artifact input : getMandatoryInputs()) { // Assume that if the file did not exist, we would not have gotten here. try { - if (input.isSourceArtifact() && !metadataProvider.getMetadata(input).isFile()) { - eventHandler.handle(Event.warn(getOwner().getLocation(), "input '" - + input.prettyPrint() + "' to " + getOwner().getLabel() - + " is a directory; dependency checking of directories is unsound")); + if (input.isSourceArtifact() + && metadataProvider.getMetadata(input).getType().isDirectory()) { + // TODO(ulfjack): What about dependency checking of special files? + eventHandler.handle(Event.warn(getOwner().getLocation(), + String.format( + "input '%s' to %s is a directory; dependency checking of directories is unsound", + input.prettyPrint(), getOwner().getLabel()))); } } catch (IOException e) { throw new UserExecException(e); diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java b/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java index 8e4dc88a46..b6957cfcca 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java @@ -51,15 +51,21 @@ import javax.annotation.Nullable; * otherwise lightweight, and should be constructed anew and discarded for each build request. */ public class ActionCacheChecker { + private static final byte[] EMPTY_DIGEST = new byte[0]; private static final Metadata CONSTANT_METADATA = new Metadata() { @Override + public FileStateType getType() { + return FileStateType.REGULAR_FILE; + } + + @Override public boolean isFile() { - return false; + return true; } @Override public byte[] getDigest() { - throw new UnsupportedOperationException(); + return EMPTY_DIGEST; } @Override diff --git a/src/main/java/com/google/devtools/build/lib/actions/FileStateType.java b/src/main/java/com/google/devtools/build/lib/actions/FileStateType.java new file mode 100644 index 0000000000..8e339e481e --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/actions/FileStateType.java @@ -0,0 +1,79 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.actions; + +/** An enum indicating the type of a path on the file system. */ +public enum FileStateType { + REGULAR_FILE("file"), + /** + * A special file such as a socket, fifo, or device. See + * {@link com.google.devtools.build.lib.vfs.FileStatus#isSpecialFile}. + */ + SPECIAL_FILE("special file"), + DIRECTORY("directory"), + SYMLINK("symlink"), + NONEXISTENT("non-existent path"); + + private final String name; + + private FileStateType(String name) { + this.name = name; + } + + public String getHumanReadableName() { + return name; + } + + /** Returns true if this type does not correspond to a non-existent path. */ + public boolean exists() { + return this != NONEXISTENT; + } + + /** Returns true if this value corresponds to a symlink. */ + public boolean isSymlink() { + return this == SYMLINK; + } + + /** + * Returns true if this value corresponds to a regular file. If so, its parent directory is + * guaranteed to exist. + */ + public boolean isFile() { + return this == REGULAR_FILE; + } + + /** + * Returns true if this value corresponds to a special file. If so, its parent directory is + * guaranteed to exist. + */ + public boolean isSpecialFile() { + return this == SPECIAL_FILE; + } + + /** + * Returns true if this value corresponds to a regular or special file. If so, its parent + * directory is guaranteed to exist. + */ + public boolean isRegularOrSpecialFile() { + return this == REGULAR_FILE || this == FileStateType.SPECIAL_FILE; + } + + /** + * Returns true if the file is a directory. If so, its parent directory is guaranteed to exist. + */ + public boolean isDirectory() { + return this == DIRECTORY; + } +}
\ No newline at end of file diff --git a/src/main/java/com/google/devtools/build/lib/actions/MetadataProvider.java b/src/main/java/com/google/devtools/build/lib/actions/MetadataProvider.java index 40d54b6c92..1538286ff9 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/MetadataProvider.java +++ b/src/main/java/com/google/devtools/build/lib/actions/MetadataProvider.java @@ -29,6 +29,10 @@ public interface MetadataProvider { * then t >= p. Aside from these properties, t can be any value and may vary arbitrarily across * calls. * + * <p>Returned {@link Metadata} instance correspond to the final target of a symlink, and + * therefore must not have a type of + * {@link com.google.devtools.build.lib.actions.FileStateType#SYMLINK} themselves. + * * The return value is owned by the cache and must not be modified. * * @param input the input to retrieve the digest for diff --git a/src/main/java/com/google/devtools/build/lib/actions/cache/Metadata.java b/src/main/java/com/google/devtools/build/lib/actions/cache/Metadata.java index 642bd29593..c14cb03a57 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/cache/Metadata.java +++ b/src/main/java/com/google/devtools/build/lib/actions/cache/Metadata.java @@ -14,12 +14,12 @@ package com.google.devtools.build.lib.actions.cache; +import com.google.devtools.build.lib.actions.FileStateType; + /** - * An interface to represent the state of a file (or directory). This is used to determine whether a - * file has changed or not. - * - * <p>NB! Several other parts of Blaze are relying on the fact that metadata uses mtime and not - * ctime. If metadata is ever changed to use ctime, all uses of Metadata must be carefully examined. + * An interface to represent the state of a file system object for the execution phase. This is not + * used by Skyframe for invalidation, it is primarily used by the action cache and the various + * {@link com.google.devtools.build.lib.exec.SpawnRunner} implementations. */ public interface Metadata { /** @@ -30,6 +30,14 @@ public interface Metadata { } /** + * The type of the underlying file system object. If it is a regular file, then it is + * guaranteed to have a digest. Otherwise it does not have a digest. + */ + default FileStateType getType() { + return isFile() ? FileStateType.REGULAR_FILE : FileStateType.DIRECTORY; + } + + /** * Whether the underlying file system object is a file or a symlink to a file, rather than a * directory. All files are guaranteed to have a digest, and {@link #getDigest} must only be * called on files. @@ -40,7 +48,7 @@ public interface Metadata { * Returns the file's digest; must only be called on objects for which {@link #isFile} returns * true. * - * <p>The return value is owned by the cache and must not be modified. + * <p>The return value is owned by this object and must not be modified. */ byte[] getDigest(); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java index 2a8c6e5beb..4e087dbbac 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java @@ -219,7 +219,7 @@ public class ActionMetadataHandler implements MetadataHandler { } // We do not cache exceptions besides nonexistence here, because it is unlikely that the file // will be requested from this cache too many times. - fileValue = constructFileValue(artifact, null); + fileValue = constructFileValue(artifact, /*statNoFollow=*/ null); return maybeStoreAdditionalData(artifact, fileValue, null); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileArtifactValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileArtifactValue.java index 7f45e7d7ae..6bc9f5a1da 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileArtifactValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileArtifactValue.java @@ -17,6 +17,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.FileStateType; import com.google.devtools.build.lib.actions.cache.DigestUtils; import com.google.devtools.build.lib.actions.cache.Metadata; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; @@ -45,6 +46,11 @@ import javax.annotation.Nullable; @Immutable @ThreadSafe public abstract class FileArtifactValue implements SkyValue, Metadata { private static final class SingletonMarkerValue extends FileArtifactValue implements Singleton { + @Override + public FileStateType getType() { + return FileStateType.NONEXISTENT; + } + @Nullable @Override public byte[] getDigest() { @@ -74,6 +80,11 @@ public abstract class FileArtifactValue implements SkyValue, Metadata { private static final class OmittedFileValue extends FileArtifactValue implements Singleton { @Override + public FileStateType getType() { + return FileStateType.NONEXISTENT; + } + + @Override public byte[] getDigest() { throw new UnsupportedOperationException(); } @@ -117,6 +128,11 @@ public abstract class FileArtifactValue implements SkyValue, Metadata { this.mtime = mtime; } + @Override + public FileStateType getType() { + return FileStateType.DIRECTORY; + } + @Nullable @Override public byte[] getDigest() { @@ -154,6 +170,11 @@ public abstract class FileArtifactValue implements SkyValue, Metadata { } @Override + public FileStateType getType() { + return FileStateType.REGULAR_FILE; + } + + @Override public byte[] getDigest() { return digest; } @@ -255,10 +276,13 @@ public abstract class FileArtifactValue implements SkyValue, Metadata { return false; } Metadata m = (Metadata) o; + if (getType() != m.getType()) { + return false; + } if (isFile()) { - return m.isFile() && Arrays.equals(getDigest(), m.getDigest()) && getSize() == m.getSize(); + return Arrays.equals(getDigest(), m.getDigest()) && getSize() == m.getSize(); } else { - return !m.isFile() && getModifiedTime() == m.getModifiedTime(); + return getModifiedTime() == m.getModifiedTime(); } } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileFunction.java index acac707c92..965c4c5fbb 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileFunction.java @@ -18,8 +18,8 @@ import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; +import com.google.devtools.build.lib.actions.FileStateType; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; -import com.google.devtools.build.lib.skyframe.FileStateValue.Type; import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; @@ -69,7 +69,7 @@ public class FileFunction implements SkyFunction { } realRootedPath = resolvedState.getFirst(); realFileStateValue = resolvedState.getSecond(); - if (realFileStateValue.getType() == Type.NONEXISTENT) { + if (realFileStateValue.getType() == FileStateType.NONEXISTENT) { return FileValue.value( rootedPath, FileStateValue.NONEXISTENT_FILE_STATE_NODE, @@ -95,7 +95,7 @@ public class FileFunction implements SkyFunction { ArrayList<RootedPath> symlinkChain = new ArrayList<>(); TreeSet<Path> orderedSeenPaths = Sets.newTreeSet(); - while (realFileStateValue.getType().equals(FileStateValue.Type.SYMLINK)) { + while (realFileStateValue.getType().isSymlink()) { symlinkChain.add(realRootedPath); orderedSeenPaths.add(realRootedPath.asPath()); Pair<RootedPath, FileStateValue> resolvedState = getSymlinkTargetRootedPath(realRootedPath, @@ -145,7 +145,7 @@ public class FileFunction implements SkyFunction { if (realFileStateValue == null) { return null; } - if (realFileStateValue.getType() != FileStateValue.Type.NONEXISTENT + if (realFileStateValue.getType() != FileStateType.NONEXISTENT && parentFileValue != null && !parentFileValue.isDirectory()) { String type = realFileStateValue.getType().toString().toLowerCase(); String message = type + " " + rootedPath.asPath() + " exists but its parent " diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java index c309b427ad..2595663fd4 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileStateValue.java @@ -14,7 +14,9 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; +import com.google.devtools.build.lib.actions.FileStateType; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.FileStatus; @@ -33,10 +35,10 @@ import java.util.Objects; import javax.annotation.Nullable; /** - * Encapsulates the filesystem operations needed to get state for a path. This is at least a - * 'lstat' to determine what type of file the path is. + * Encapsulates the filesystem operations needed to get state for a path. This is equivalent to an + * 'lstat' that does not follow symlinks to determine what type of file the path is. * <ul> - * <li> For a non-existent file, the non existence is noted. + * <li> For a non-existent file, the non-existence is noted. * <li> For a symlink, the symlink target is noted. * <li> For a directory, the existence is noted. * <li> For a file, the existence is noted, along with metadata about the file (e.g. @@ -58,15 +60,6 @@ public abstract class FileStateValue implements SkyValue { public static final NonexistentFileStateValue NONEXISTENT_FILE_STATE_NODE = new NonexistentFileStateValue(); - /** Type of a path. */ - public enum Type { - REGULAR_FILE, - SPECIAL_FILE, - DIRECTORY, - SYMLINK, - NONEXISTENT, - } - protected FileStateValue() { } @@ -106,8 +99,9 @@ public abstract class FileStateValue implements SkyValue { return LegacySkyKey.create(SkyFunctions.FILE_STATE, rootedPath); } - public abstract Type getType(); + public abstract FileStateType getType(); + /** Returns the target of the symlink, or throws an exception if this is not a symlink. */ PathFragment getSymlinkTarget() { throw new IllegalStateException(); } @@ -205,8 +199,8 @@ public abstract class FileStateValue implements SkyValue { } @Override - public Type getType() { - return Type.REGULAR_FILE; + public FileStateType getType() { + return FileStateType.REGULAR_FILE; } @Override @@ -230,12 +224,17 @@ public abstract class FileStateValue implements SkyValue { @Override public boolean equals(Object obj) { - if (obj instanceof RegularFileStateValue) { - RegularFileStateValue other = (RegularFileStateValue) obj; - return size == other.size && mtime == other.mtime && Arrays.equals(digest, other.digest) - && Objects.equals(contentsProxy, other.contentsProxy); + if (obj == this) { + return true; } - return false; + if (!(obj instanceof RegularFileStateValue)) { + return false; + } + RegularFileStateValue other = (RegularFileStateValue) obj; + return size == other.size + && mtime == other.mtime + && Arrays.equals(digest, other.digest) + && Objects.equals(contentsProxy, other.contentsProxy); } @Override @@ -244,6 +243,15 @@ public abstract class FileStateValue implements SkyValue { } @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("digest", digest) + .add("size", size) + .add("mtime", mtime) + .add("contentsProxy", contentsProxy).toString(); + } + + @Override public String prettyPrint() { String contents = digest != null ? String.format("digest of %s", Arrays.toString(digest)) @@ -261,11 +269,10 @@ public abstract class FileStateValue implements SkyValue { this.contentsProxy = contentsProxy; } - static SpecialFileStateValue fromStat(PathFragment path, FileStatusWithDigest stat, + static SpecialFileStateValue fromStat(PathFragment path, FileStatus stat, @Nullable TimestampGranularityMonitor tsgm) throws IOException { long mtime = stat.getLastModifiedTime(); - // Note that TimestampGranularityMonitor#notifyDependenceOnFileTime is a thread-safe - // method. + // Note that TimestampGranularityMonitor#notifyDependenceOnFileTime is a thread-safe method. if (tsgm != null) { tsgm.notifyDependenceOnFileTime(path, mtime); } @@ -273,8 +280,8 @@ public abstract class FileStateValue implements SkyValue { } @Override - public Type getType() { - return Type.SPECIAL_FILE; + public FileStateType getType() { + return FileStateType.SPECIAL_FILE; } @Override @@ -294,11 +301,14 @@ public abstract class FileStateValue implements SkyValue { @Override public boolean equals(Object obj) { - if (obj instanceof SpecialFileStateValue) { - SpecialFileStateValue other = (SpecialFileStateValue) obj; - return Objects.equals(contentsProxy, other.contentsProxy); + if (obj == this) { + return true; } - return false; + if (!(obj instanceof SpecialFileStateValue)) { + return false; + } + SpecialFileStateValue other = (SpecialFileStateValue) obj; + return Objects.equals(contentsProxy, other.contentsProxy); } @Override @@ -319,8 +329,8 @@ public abstract class FileStateValue implements SkyValue { } @Override - public Type getType() { - return Type.DIRECTORY; + public FileStateType getType() { + return FileStateType.DIRECTORY; } @Override @@ -350,8 +360,8 @@ public abstract class FileStateValue implements SkyValue { } @Override - public Type getType() { - return Type.SYMLINK; + public FileStateType getType() { + return FileStateType.SYMLINK; } @Override @@ -386,8 +396,8 @@ public abstract class FileStateValue implements SkyValue { } @Override - public Type getType() { - return Type.NONEXISTENT; + public FileStateType getType() { + return FileStateType.NONEXISTENT; } @Override @@ -398,6 +408,9 @@ public abstract class FileStateValue implements SkyValue { // This object is normally a singleton, but deserialization produces copies. @Override public boolean equals(Object obj) { + if (obj == this) { + return true; + } return obj instanceof NonexistentFileStateValue; } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java index 441bf6939e..7374bf32fe 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/FileValue.java @@ -14,9 +14,9 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.base.Preconditions; +import com.google.devtools.build.lib.actions.FileStateType; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; -import com.google.devtools.build.lib.skyframe.FileStateValue.Type; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.LegacySkyKey; @@ -48,9 +48,10 @@ import javax.annotation.Nullable; public abstract class FileValue implements SkyValue { public boolean exists() { - return realFileStateValue().getType() != Type.NONEXISTENT; + return realFileStateValue().getType() != FileStateType.NONEXISTENT; } + /** Returns true if the original path is a symlink; the target path can never be a symlink. */ public boolean isSymlink() { return false; } @@ -60,8 +61,8 @@ public abstract class FileValue implements SkyValue { * file. If so, its parent directory is guaranteed to exist. */ public boolean isFile() { - return realFileStateValue().getType() == Type.REGULAR_FILE - || realFileStateValue().getType() == Type.SPECIAL_FILE; + return realFileStateValue().getType() == FileStateType.REGULAR_FILE + || realFileStateValue().getType() == FileStateType.SPECIAL_FILE; } /** @@ -69,7 +70,7 @@ public abstract class FileValue implements SkyValue { * its parent directory is guaranteed to exist. */ public boolean isSpecialFile() { - return realFileStateValue().getType() == Type.SPECIAL_FILE; + return realFileStateValue().getType() == FileStateType.SPECIAL_FILE; } /** @@ -77,7 +78,7 @@ public abstract class FileValue implements SkyValue { * parent directory is guaranteed to exist. */ public boolean isDirectory() { - return realFileStateValue().getType() == Type.DIRECTORY; + return realFileStateValue().getType() == FileStateType.DIRECTORY; } /** @@ -125,12 +126,12 @@ public abstract class FileValue implements SkyValue { static FileValue value(RootedPath rootedPath, FileStateValue fileStateValue, RootedPath realRootedPath, FileStateValue realFileStateValue) { if (rootedPath.equals(realRootedPath)) { - Preconditions.checkState(fileStateValue.getType() != FileStateValue.Type.SYMLINK, + Preconditions.checkState(fileStateValue.getType() != FileStateType.SYMLINK, "rootedPath: %s, fileStateValue: %s, realRootedPath: %s, realFileStateValue: %s", rootedPath, fileStateValue, realRootedPath, realFileStateValue); return new RegularFileValue(rootedPath, fileStateValue); } else { - if (fileStateValue.getType() == FileStateValue.Type.SYMLINK) { + if (fileStateValue.getType() == FileStateType.SYMLINK) { return new SymlinkFileValue(realRootedPath, realFileStateValue, fileStateValue.getSymlinkTarget()); } else { diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java index 3c450d3462..5924481a85 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java @@ -50,6 +50,7 @@ import com.google.devtools.build.lib.actions.ArtifactFactory; import com.google.devtools.build.lib.actions.ArtifactOwner; import com.google.devtools.build.lib.actions.EnvironmentalExecException; import com.google.devtools.build.lib.actions.Executor; +import com.google.devtools.build.lib.actions.FileStateType; import com.google.devtools.build.lib.actions.ResourceManager; import com.google.devtools.build.lib.actions.Root; import com.google.devtools.build.lib.analysis.AspectCollection; @@ -911,12 +912,11 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { protected abstract void invalidate(Predicate<SkyKey> pred); - private static boolean compatibleFileTypes(Dirent.Type oldType, FileStateValue.Type newType) { - return (oldType.equals(Dirent.Type.FILE) && newType.equals(FileStateValue.Type.REGULAR_FILE)) - || (oldType.equals(Dirent.Type.UNKNOWN) - && newType.equals(FileStateValue.Type.SPECIAL_FILE)) - || (oldType.equals(Dirent.Type.DIRECTORY) && newType.equals(FileStateValue.Type.DIRECTORY)) - || (oldType.equals(Dirent.Type.SYMLINK) && newType.equals(FileStateValue.Type.SYMLINK)); + private static boolean compatibleFileTypes(Dirent.Type oldType, FileStateType newType) { + return (oldType.equals(Dirent.Type.FILE) && newType.equals(FileStateType.REGULAR_FILE)) + || (oldType.equals(Dirent.Type.UNKNOWN) && newType.equals(FileStateType.SPECIAL_FILE)) + || (oldType.equals(Dirent.Type.DIRECTORY) && newType.equals(FileStateType.DIRECTORY)) + || (oldType.equals(Dirent.Type.SYMLINK) && newType.equals(FileStateType.SYMLINK)); } protected Differencer.Diff getDiff(TimestampGranularityMonitor tsgm, diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerFilesHash.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerFilesHash.java index 5fc0f3863c..a39e47f968 100644 --- a/src/main/java/com/google/devtools/build/lib/worker/WorkerFilesHash.java +++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerFilesHash.java @@ -74,7 +74,7 @@ class WorkerFilesHash { Artifact localArtifact = mapping.getValue(); if (localArtifact != null) { Metadata metadata = actionInputFileCache.getMetadata(localArtifact); - if (metadata.isFile()) { + if (metadata.getType().isFile()) { workerFilesMap.put( root.getRelative(mapping.getKey()), HashCode.fromBytes(metadata.getDigest())); |