Move some IO-focused classes that don't have deps on other parts of Bazel to the new lib/io package. Also, couldn't resist some clean-ups on Abstract(File)ChainUniquenessFunction: was only used for RootedPath, so specialized to that, and streamlined the uniquifier a bit, hopefully without any bugs that our test battery won't catch. I did debate truly uniquifying the cycle by breaking ties based on the next element, but managed to back away. PiperOrigin-RevId: 363756543
diff --git a/src/main/java/com/google/devtools/build/lib/io/AbstractFileChainUniquenessFunction.java b/src/main/java/com/google/devtools/build/lib/io/AbstractFileChainUniquenessFunction.java new file mode 100644 index 0000000..76fc2a9 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/io/AbstractFileChainUniquenessFunction.java
@@ -0,0 +1,83 @@ +// Copyright 2014 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.io; + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.events.Event; +import com.google.devtools.build.lib.vfs.RootedPath; +import com.google.devtools.build.skyframe.EmptySkyValue; +import com.google.devtools.build.skyframe.SkyFunction; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.SkyValue; + +/** + * Given a "cycle" of {@link RootedPath} files, emits an error message for this cycle. The keys for + * this SkyFunction are assumed to deduplicate cycles that differ only in which element of the cycle + * they start at, so multiple paths to the cycle will be reported by a single execution of this + * function. + * + * <p>The cycle need not actually be a cycle -- any iterable exhibiting an error that is independent + * of the iterable's starting point can be an argument to this function. + */ +abstract class AbstractFileChainUniquenessFunction implements SkyFunction { + protected abstract String getConciseDescription(); + + protected abstract String getHeaderMessage(); + + protected abstract String getFooterMessage(); + + protected abstract String elementToString(RootedPath path); + + @Override + public SkyValue compute(SkyKey skyKey, Environment env) { + StringBuilder errorMessage = new StringBuilder(); + errorMessage.append(getConciseDescription() + " detected\n"); + errorMessage.append(getHeaderMessage() + "\n"); + @SuppressWarnings("unchecked") + ImmutableList<RootedPath> chain = (ImmutableList<RootedPath>) skyKey.argument(); + for (RootedPath elt : chain) { + errorMessage.append(elementToString(elt) + "\n"); + } + errorMessage.append(getFooterMessage() + "\n"); + // The purpose of this SkyFunction is the side effect of emitting an error message exactly + // once per build per unique error. + env.getListener().handle(Event.error(errorMessage.toString())); + return EmptySkyValue.INSTANCE; + } + + @Override + public String extractTag(SkyKey skyKey) { + return null; + } + + /** + * Creates a canonicalized representation of the cycle specified by {@code chain}. {@code chain} + * must be non-empty. The representation may not be unique if cycle has duplicate elements. + */ + static ImmutableList<RootedPath> canonicalize(ImmutableList<RootedPath> cycle) { + int minPos = 0; + RootedPath min = cycle.get(0); + for (int i = 1; i < cycle.size(); i++) { + RootedPath cur = cycle.get(i); + if (cur.compareTo(min) < 0) { + minPos = i; + min = cur; + } + } + return ImmutableList.<RootedPath>builderWithExpectedSize(cycle.size()) + .addAll(cycle.subList(minPos, cycle.size())) + .addAll(cycle.subList(0, minPos)) + .build(); + } +}
diff --git a/src/main/java/com/google/devtools/build/lib/io/BUILD b/src/main/java/com/google/devtools/build/lib/io/BUILD index 810dec3..fdd02fe 100644 --- a/src/main/java/com/google/devtools/build/lib/io/BUILD +++ b/src/main/java/com/google/devtools/build/lib/io/BUILD
@@ -10,9 +10,71 @@ visibility = ["//src:__subpackages__"], ) -# TODO(janakr): move other general-purpose IO classes here (FileSymlinkException -# and friends, for instance). java_library( name = "inconsistent_filesystem_exception", srcs = ["InconsistentFilesystemException.java"], ) + +java_library( + name = "file_symlink_exception", + srcs = ["FileSymlinkException.java"], +) + +java_library( + name = "file_symlink_cycle_exception", + srcs = ["FileSymlinkCycleException.java"], + deps = [ + ":file_symlink_exception", + "//src/main/java/com/google/devtools/build/lib/vfs", + "//third_party:guava", + ], +) + +java_library( + name = "abstract_chain_uniqueness_function", + srcs = ["AbstractFileChainUniquenessFunction.java"], + deps = [ + "//src/main/java/com/google/devtools/build/lib/events", + "//src/main/java/com/google/devtools/build/lib/vfs", + "//src/main/java/com/google/devtools/build/skyframe", + "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", + "//third_party:guava", + ], +) + +java_library( + name = "file_symlink_cycle_uniqueness_function", + srcs = ["FileSymlinkCycleUniquenessFunction.java"], + deps = [ + ":abstract_chain_uniqueness_function", + "//src/main/java/com/google/devtools/build/lib/concurrent", + "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec", + "//src/main/java/com/google/devtools/build/lib/vfs", + "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", + "//third_party:guava", + ], +) + +java_library( + name = "file_symlink_infinite_expansion_exception", + srcs = ["FileSymlinkInfiniteExpansionException.java"], + deps = [ + ":file_symlink_exception", + "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec", + "//src/main/java/com/google/devtools/build/lib/vfs", + "//third_party:guava", + ], +) + +java_library( + name = "file_symlink_infinite_expansion_uniqueness_function", + srcs = ["FileSymlinkInfiniteExpansionUniquenessFunction.java"], + deps = [ + ":abstract_chain_uniqueness_function", + "//src/main/java/com/google/devtools/build/lib/concurrent", + "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec", + "//src/main/java/com/google/devtools/build/lib/vfs", + "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", + "//third_party:guava", + ], +)
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkCycleException.java b/src/main/java/com/google/devtools/build/lib/io/FileSymlinkCycleException.java similarity index 97% rename from src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkCycleException.java rename to src/main/java/com/google/devtools/build/lib/io/FileSymlinkCycleException.java index 5fd93a1..8821aec 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkCycleException.java +++ b/src/main/java/com/google/devtools/build/lib/io/FileSymlinkCycleException.java
@@ -11,7 +11,7 @@ // 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.skyframe; +package com.google.devtools.build.lib.io; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkCycleUniquenessFunction.java b/src/main/java/com/google/devtools/build/lib/io/FileSymlinkCycleUniquenessFunction.java similarity index 84% rename from src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkCycleUniquenessFunction.java rename to src/main/java/com/google/devtools/build/lib/io/FileSymlinkCycleUniquenessFunction.java index d9b3705..56f746b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkCycleUniquenessFunction.java +++ b/src/main/java/com/google/devtools/build/lib/io/FileSymlinkCycleUniquenessFunction.java
@@ -11,7 +11,7 @@ // 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.skyframe; +package com.google.devtools.build.lib.io; import com.google.common.collect.ImmutableList; import com.google.common.collect.Interner; @@ -28,11 +28,12 @@ * (e.g. {@code ['a' -> 'b' -> 'c' -> 'a']} and {@code ['b' -> 'c' -> 'a' -> 'b']}), and letting * Skyframe do its magic. */ -public class FileSymlinkCycleUniquenessFunction - extends AbstractChainUniquenessFunction<RootedPath> { +public class FileSymlinkCycleUniquenessFunction extends AbstractFileChainUniquenessFunction { + public static final SkyFunctionName NAME = + SkyFunctionName.createHermetic("FILE_SYMLINK_CYCLE_UNIQUENESS"); - static SkyKey key(ImmutableList<RootedPath> cycle) { - return Key.create(ChainUniquenessUtils.canonicalize(cycle)); + public static SkyKey key(ImmutableList<RootedPath> cycle) { + return Key.create(AbstractFileChainUniquenessFunction.canonicalize(cycle)); } @AutoCodec.VisibleForSerialization @@ -52,7 +53,7 @@ @Override public SkyFunctionName functionName() { - return SkyFunctions.FILE_SYMLINK_CYCLE_UNIQUENESS; + return NAME; } }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkException.java b/src/main/java/com/google/devtools/build/lib/io/FileSymlinkException.java similarity index 88% rename from src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkException.java rename to src/main/java/com/google/devtools/build/lib/io/FileSymlinkException.java index 50610d5..e8da68d 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkException.java +++ b/src/main/java/com/google/devtools/build/lib/io/FileSymlinkException.java
@@ -11,7 +11,7 @@ // 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.skyframe; +package com.google.devtools.build.lib.io; import java.io.IOException; @@ -22,6 +22,6 @@ } /** Returns a description of the problem that is suitable for printing to users. */ - // TODO(nharmata): Consider unifying this with AbstractChainUniquenessFunction. + // TODO(nharmata): Consider unifying this with AbstractFileChainUniquenessFunction. public abstract String getUserFriendlyMessage(); }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkInfiniteExpansionException.java b/src/main/java/com/google/devtools/build/lib/io/FileSymlinkInfiniteExpansionException.java similarity index 97% rename from src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkInfiniteExpansionException.java rename to src/main/java/com/google/devtools/build/lib/io/FileSymlinkInfiniteExpansionException.java index 0020a6b..cc2a02d 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkInfiniteExpansionException.java +++ b/src/main/java/com/google/devtools/build/lib/io/FileSymlinkInfiniteExpansionException.java
@@ -11,7 +11,7 @@ // 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.skyframe; +package com.google.devtools.build.lib.io; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkInfiniteExpansionUniquenessFunction.java b/src/main/java/com/google/devtools/build/lib/io/FileSymlinkInfiniteExpansionUniquenessFunction.java similarity index 72% rename from src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkInfiniteExpansionUniquenessFunction.java rename to src/main/java/com/google/devtools/build/lib/io/FileSymlinkInfiniteExpansionUniquenessFunction.java index 56f6801..eb4f47c 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/FileSymlinkInfiniteExpansionUniquenessFunction.java +++ b/src/main/java/com/google/devtools/build/lib/io/FileSymlinkInfiniteExpansionUniquenessFunction.java
@@ -11,7 +11,7 @@ // 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.skyframe; +package com.google.devtools.build.lib.io; import com.google.common.collect.ImmutableList; import com.google.common.collect.Interner; @@ -23,18 +23,18 @@ import com.google.devtools.build.skyframe.SkyKey; /** - * A {@link - * com/google/devtools/build/lib/skyframe/FileSymlinkInfiniteExpansionUniquenessFunction.java used - * only in javadoc: com.google.devtools.build.skyframe.SkyFunction} that has the side effect of - * reporting a file symlink expansion error exactly once. This is achieved by forcing the same value - * key for two logically equivalent expansion errors (e.g. ['a' -> 'b' -> 'c' -> 'a/nope'] and ['b' - * -> 'c' -> 'a' -> 'a/nope']), and letting Skyframe do its magic. + * A {@link com.google.devtools.build.skyframe.SkyFunction} that has the side effect of reporting a + * file symlink expansion error exactly once. This is achieved by forcing the same value key for two + * logically equivalent expansion errors (e.g. ['a' -> 'b' -> 'c' -> 'a/nope'] and ['b' -> 'c' -> + * 'a' -> 'a/nope']), and letting Skyframe do its magic. */ public class FileSymlinkInfiniteExpansionUniquenessFunction - extends AbstractChainUniquenessFunction<RootedPath> { + extends AbstractFileChainUniquenessFunction { + public static final SkyFunctionName NAME = + SkyFunctionName.createHermetic("FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS"); - static SkyKey key(ImmutableList<RootedPath> cycle) { - return Key.create(ChainUniquenessUtils.canonicalize(cycle)); + public static SkyKey key(ImmutableList<RootedPath> cycle) { + return Key.create(AbstractFileChainUniquenessFunction.canonicalize(cycle)); } @AutoCodec.VisibleForSerialization @@ -54,7 +54,7 @@ @Override public SkyFunctionName functionName() { - return SkyFunctions.FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS; + return NAME; } }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AbstractChainUniquenessFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AbstractChainUniquenessFunction.java deleted file mode 100644 index 489cc0e..0000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/AbstractChainUniquenessFunction.java +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2014 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.skyframe; - -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.lib.events.Event; -import com.google.devtools.build.skyframe.EmptySkyValue; -import com.google.devtools.build.skyframe.SkyFunction; -import com.google.devtools.build.skyframe.SkyKey; -import com.google.devtools.build.skyframe.SkyValue; - -/** - * Given a "cycle" of objects of type {@param S}, emits an error message for this cycle. - * The keys for this SkyFunction are assumed to deduplicate cycles that differ only in which element - * of the cycle they start at, so multiple paths to the cycle will be reported by a single execution - * of this function. - * - * <p>The cycle need not actually be a cycle -- any iterable exhibiting an error that is independent - * of the iterable's starting point can be an argument to this function. - */ -abstract class AbstractChainUniquenessFunction<S> implements SkyFunction { - protected abstract String getConciseDescription(); - - protected abstract String getHeaderMessage(); - - protected abstract String getFooterMessage(); - - protected abstract String elementToString(S elt); - - @Override - public SkyValue compute(SkyKey skyKey, Environment env) { - StringBuilder errorMessage = new StringBuilder(); - errorMessage.append(getConciseDescription() + " detected\n"); - errorMessage.append(getHeaderMessage() + "\n"); - @SuppressWarnings("unchecked") - ImmutableList<S> chain = (ImmutableList<S>) skyKey.argument(); - for (S elt : chain) { - errorMessage.append(elementToString(elt) + "\n"); - } - errorMessage.append(getFooterMessage() + "\n"); - // The purpose of this SkyFunction is the side effect of emitting an error message exactly - // once per build per unique error. - env.getListener().handle(Event.error(errorMessage.toString())); - return EmptySkyValue.INSTANCE; - } - - @Override - public String extractTag(SkyKey skyKey) { - return null; - } -} -
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD index 3e49f95..0d9388a 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -142,9 +142,6 @@ ":directory_listing_state_value", ":execution_finished_event", ":file_function", - ":file_symlink_cycle_uniqueness_function", - ":file_symlink_exception", - ":file_symlink_infinite_expansion_uniqueness_function", ":fileset_entry_function", ":filesystem_value_checker", ":glob_descriptor", @@ -275,6 +272,9 @@ "//src/main/java/com/google/devtools/build/lib/collect/nestedset", "//src/main/java/com/google/devtools/build/lib/concurrent", "//src/main/java/com/google/devtools/build/lib/events", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_cycle_uniqueness_function", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_exception", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_infinite_expansion_uniqueness_function", "//src/main/java/com/google/devtools/build/lib/io:inconsistent_filesystem_exception", "//src/main/java/com/google/devtools/build/lib/packages", "//src/main/java/com/google/devtools/build/lib/packages/semantics", @@ -323,17 +323,6 @@ ) java_library( - name = "abstract_chain_uniqueness_function", - srcs = ["AbstractChainUniquenessFunction.java"], - deps = [ - "//src/main/java/com/google/devtools/build/lib/events", - "//src/main/java/com/google/devtools/build/skyframe", - "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", - "//third_party:guava", - ], -) - -java_library( name = "detailed_exceptions", srcs = [ "DetailedException.java", @@ -1040,12 +1029,6 @@ ) java_library( - name = "chain_uniqueness_utils", - srcs = ["ChainUniquenessUtils.java"], - deps = ["//third_party:guava"], -) - -java_library( name = "client_environment_function", srcs = ["ClientEnvironmentFunction.java"], deps = [ @@ -1388,12 +1371,12 @@ srcs = ["FileFunction.java"], deps = [ ":cycle_utils", - ":file_symlink_cycle_exception", - ":file_symlink_cycle_uniqueness_function", - ":file_symlink_exception", - ":file_symlink_infinite_expansion_exception", - ":file_symlink_infinite_expansion_uniqueness_function", "//src/main/java/com/google/devtools/build/lib/actions:file_metadata", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_cycle_exception", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_cycle_uniqueness_function", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_exception", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_infinite_expansion_exception", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_infinite_expansion_uniqueness_function", "//src/main/java/com/google/devtools/build/lib/pkgcache", "//src/main/java/com/google/devtools/build/lib/util", "//src/main/java/com/google/devtools/build/lib/vfs", @@ -1406,62 +1389,6 @@ ) java_library( - name = "file_symlink_cycle_exception", - srcs = ["FileSymlinkCycleException.java"], - deps = [ - ":file_symlink_exception", - "//src/main/java/com/google/devtools/build/lib/vfs", - "//third_party:guava", - ], -) - -java_library( - name = "file_symlink_cycle_uniqueness_function", - srcs = ["FileSymlinkCycleUniquenessFunction.java"], - deps = [ - ":abstract_chain_uniqueness_function", - ":chain_uniqueness_utils", - ":sky_functions", - "//src/main/java/com/google/devtools/build/lib/concurrent", - "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec", - "//src/main/java/com/google/devtools/build/lib/vfs", - "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", - "//third_party:guava", - ], -) - -java_library( - name = "file_symlink_exception", - srcs = ["FileSymlinkException.java"], -) - -java_library( - name = "file_symlink_infinite_expansion_exception", - srcs = ["FileSymlinkInfiniteExpansionException.java"], - deps = [ - ":file_symlink_exception", - "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec", - "//src/main/java/com/google/devtools/build/lib/vfs", - "//third_party:guava", - ], -) - -java_library( - name = "file_symlink_infinite_expansion_uniqueness_function", - srcs = ["FileSymlinkInfiniteExpansionUniquenessFunction.java"], - deps = [ - ":abstract_chain_uniqueness_function", - ":chain_uniqueness_utils", - ":sky_functions", - "//src/main/java/com/google/devtools/build/lib/concurrent", - "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec", - "//src/main/java/com/google/devtools/build/lib/vfs", - "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", - "//third_party:guava", - ], -) - -java_library( name = "fileset_entry_function", srcs = ["FilesetEntryFunction.java"], deps = [ @@ -1548,8 +1475,6 @@ srcs = ["GlobFunction.java"], deps = [ ":directory_listing_value", - ":file_symlink_infinite_expansion_exception", - ":file_symlink_infinite_expansion_uniqueness_function", ":glob_descriptor", ":glob_value", ":ignored_package_prefixes_value", @@ -1557,6 +1482,8 @@ "//src/main/java/com/google/devtools/build/lib/actions:file_metadata", "//src/main/java/com/google/devtools/build/lib/cmdline", "//src/main/java/com/google/devtools/build/lib/collect/nestedset", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_infinite_expansion_exception", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_infinite_expansion_uniqueness_function", "//src/main/java/com/google/devtools/build/lib/io:inconsistent_filesystem_exception", "//src/main/java/com/google/devtools/build/lib/vfs", "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", @@ -1781,7 +1708,6 @@ srcs = ["PackageLookupFunction.java"], deps = [ ":already_reported_exception", - ":file_symlink_exception", ":ignored_package_prefixes_value", ":local_repository_lookup_value", ":package_lookup_value", @@ -1789,6 +1715,7 @@ "//src/main/java/com/google/devtools/build/lib/actions:file_metadata", "//src/main/java/com/google/devtools/build/lib/cmdline", "//src/main/java/com/google/devtools/build/lib/cmdline:LabelValidator", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_exception", "//src/main/java/com/google/devtools/build/lib/io:inconsistent_filesystem_exception", "//src/main/java/com/google/devtools/build/lib/packages", "//src/main/java/com/google/devtools/build/lib/packages/semantics", @@ -2064,9 +1991,6 @@ deps = [ ":directory_listing_value", ":dirents", - ":file_symlink_exception", - ":file_symlink_infinite_expansion_exception", - ":file_symlink_infinite_expansion_uniqueness_function", ":package_lookup_value", ":precomputed_value", ":process_package_directory_result", @@ -2074,6 +1998,9 @@ "//src/main/java/com/google/devtools/build/lib/analysis:blaze_directories", "//src/main/java/com/google/devtools/build/lib/cmdline", "//src/main/java/com/google/devtools/build/lib/events", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_exception", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_infinite_expansion_exception", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_infinite_expansion_uniqueness_function", "//src/main/java/com/google/devtools/build/lib/io:inconsistent_filesystem_exception", "//src/main/java/com/google/devtools/build/lib/packages", "//src/main/java/com/google/devtools/build/lib/packages/semantics", @@ -2147,9 +2074,6 @@ ":action_execution_value", ":detailed_exceptions", ":directory_listing_value", - ":file_symlink_exception", - ":file_symlink_infinite_expansion_exception", - ":file_symlink_infinite_expansion_uniqueness_function", ":package_lookup_value", ":sky_functions", ":tree_artifact_value", @@ -2159,6 +2083,9 @@ "//src/main/java/com/google/devtools/build/lib/collect/nestedset", "//src/main/java/com/google/devtools/build/lib/concurrent", "//src/main/java/com/google/devtools/build/lib/events", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_exception", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_infinite_expansion_exception", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_infinite_expansion_uniqueness_function", "//src/main/java/com/google/devtools/build/lib/packages", "//src/main/java/com/google/devtools/build/lib/profiler", "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec",
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ChainUniquenessUtils.java b/src/main/java/com/google/devtools/build/lib/skyframe/ChainUniquenessUtils.java deleted file mode 100644 index 0ab6f96..0000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ChainUniquenessUtils.java +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2014 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.skyframe; - -import com.google.common.collect.ImmutableList; - -/** - * A value for ensuring that an error for a cycle/chain is reported exactly once. This is achieved - * by forcing the same value key for two logically equivalent errors and letting Skyframe do its - * magic. - */ -class ChainUniquenessUtils { - - private ChainUniquenessUtils() {} - - /** - * Create a canonicalized representation of the cycle specified by {@code chain}. {@code chain} - * must be non-empty. - */ - static <T> ImmutableList<T> canonicalize(ImmutableList<T> cycle) { - int minPos = 0; - String minString = cycle.get(0).toString(); - for (int i = 1; i < cycle.size(); i++) { - // TODO(bazel-team): Is the toString representation stable enough? - String candidateString = cycle.get(i).toString(); - if (candidateString.compareTo(minString) < 0) { - minPos = i; - minString = candidateString; - } - } - ImmutableList.Builder<T> builder = ImmutableList.builder(); - for (int i = 0; i < cycle.size(); i++) { - int pos = (minPos + i) % cycle.size(); - builder.add(cycle.get(pos)); - } - return builder.build(); - } -} -
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 7e0668a..8feb81d 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
@@ -21,6 +21,11 @@ import com.google.devtools.build.lib.actions.FileStateType; import com.google.devtools.build.lib.actions.FileStateValue; import com.google.devtools.build.lib.actions.FileValue; +import com.google.devtools.build.lib.io.FileSymlinkCycleException; +import com.google.devtools.build.lib.io.FileSymlinkCycleUniquenessFunction; +import com.google.devtools.build.lib.io.FileSymlinkException; +import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionException; +import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionUniquenessFunction; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.vfs.Path;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/GlobFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/GlobFunction.java index 4fd7369..9f3c88e 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/GlobFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/GlobFunction.java
@@ -22,6 +22,8 @@ import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionException; +import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionUniquenessFunction; import com.google.devtools.build.lib.io.InconsistentFilesystemException; import com.google.devtools.build.lib.vfs.Dirent; import com.google.devtools.build.lib.vfs.PathFragment;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java index 60df010..5d273c9 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java
@@ -19,6 +19,7 @@ import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; import com.google.devtools.build.lib.cmdline.RepositoryName; +import com.google.devtools.build.lib.io.FileSymlinkException; import com.google.devtools.build.lib.io.InconsistentFilesystemException; import com.google.devtools.build.lib.packages.AggregatingAttributeMapper; import com.google.devtools.build.lib.packages.ErrorDeterminingRepositoryException;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java index 150ef47..40d20b5 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
@@ -36,6 +36,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.ExtendedEventHandler.Postable; +import com.google.devtools.build.lib.io.FileSymlinkException; import com.google.devtools.build.lib.io.InconsistentFilesystemException; import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException; import com.google.devtools.build.lib.packages.BuildFileNotFoundException;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java index ec22abe..e4a2f0e 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
@@ -21,6 +21,7 @@ import com.google.devtools.build.lib.cmdline.LabelConstants; import com.google.devtools.build.lib.cmdline.LabelValidator; import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.io.FileSymlinkException; import com.google.devtools.build.lib.io.InconsistentFilesystemException; import com.google.devtools.build.lib.packages.BuildFileName; import com.google.devtools.build.lib.packages.BuildFileNotFoundException;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java b/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java index 36ba24f..d5f4ede 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java
@@ -26,6 +26,9 @@ import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.EventHandler; +import com.google.devtools.build.lib.io.FileSymlinkException; +import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionException; +import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionUniquenessFunction; import com.google.devtools.build.lib.io.InconsistentFilesystemException; import com.google.devtools.build.lib.packages.NoSuchPackageException; import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
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 457394e..3b62ec3 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
@@ -32,6 +32,9 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.events.Event; +import com.google.devtools.build.lib.io.FileSymlinkException; +import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionException; +import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionUniquenessFunction; import com.google.devtools.build.lib.packages.BuildFileNotFoundException; import com.google.devtools.build.lib.profiler.Profiler; import com.google.devtools.build.lib.profiler.ProfilerTask;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java index 0321227..65f3c74 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
@@ -31,10 +31,6 @@ SkyFunctionName.createHermetic("ACTION_ENVIRONMENT_VARIABLE"); public static final SkyFunctionName DIRECTORY_LISTING_STATE = SkyFunctionName.createNonHermetic("DIRECTORY_LISTING_STATE"); - public static final SkyFunctionName FILE_SYMLINK_CYCLE_UNIQUENESS = - SkyFunctionName.createHermetic("FILE_SYMLINK_CYCLE_UNIQUENESS"); - public static final SkyFunctionName FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS = - SkyFunctionName.createHermetic("FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS"); public static final SkyFunctionName DIRECTORY_LISTING = SkyFunctionName.createHermetic("DIRECTORY_LISTING"); // Hermetic even though package lookups secretly access the set of deleted packages, because
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 9043195..5b84fe3 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
@@ -114,6 +114,8 @@ import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.events.ExtendedEventHandler; import com.google.devtools.build.lib.events.Reporter; +import com.google.devtools.build.lib.io.FileSymlinkCycleUniquenessFunction; +import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionUniquenessFunction; import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException; import com.google.devtools.build.lib.packages.BuildFileName; import com.google.devtools.build.lib.packages.NoSuchPackageException; @@ -495,9 +497,9 @@ map.put(SkyFunctions.ACTION_ENVIRONMENT_VARIABLE, new ActionEnvironmentFunction()); map.put(FileStateValue.FILE_STATE, newFileStateFunction()); map.put(SkyFunctions.DIRECTORY_LISTING_STATE, newDirectoryListingStateFunction()); - map.put(SkyFunctions.FILE_SYMLINK_CYCLE_UNIQUENESS, new FileSymlinkCycleUniquenessFunction()); + map.put(FileSymlinkCycleUniquenessFunction.NAME, new FileSymlinkCycleUniquenessFunction()); map.put( - SkyFunctions.FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS, + FileSymlinkInfiniteExpansionUniquenessFunction.NAME, new FileSymlinkInfiniteExpansionUniquenessFunction()); map.put(FileValue.FILE, new FileFunction(pkgLocator, nonexistentFileReceiver)); map.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction());
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java b/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java index 471b98b..f2830e4 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java
@@ -37,6 +37,8 @@ import com.google.devtools.build.lib.concurrent.NamedForkJoinPool; import com.google.devtools.build.lib.events.Reporter; import com.google.devtools.build.lib.events.StoredEventHandler; +import com.google.devtools.build.lib.io.FileSymlinkCycleUniquenessFunction; +import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionUniquenessFunction; import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException; import com.google.devtools.build.lib.packages.BuildFileName; import com.google.devtools.build.lib.packages.CachingPackageLocator; @@ -61,8 +63,6 @@ import com.google.devtools.build.lib.skyframe.ExternalPackageFunction; import com.google.devtools.build.lib.skyframe.FileFunction; import com.google.devtools.build.lib.skyframe.FileStateFunction; -import com.google.devtools.build.lib.skyframe.FileSymlinkCycleUniquenessFunction; -import com.google.devtools.build.lib.skyframe.FileSymlinkInfiniteExpansionUniquenessFunction; import com.google.devtools.build.lib.skyframe.IgnoredPackagePrefixesFunction; import com.google.devtools.build.lib.skyframe.ManagedDirectoriesKnowledge; import com.google.devtools.build.lib.skyframe.PackageFunction; @@ -465,9 +465,9 @@ .put( FileStateValue.FILE_STATE, new FileStateFunction(tsgm, syscallCacheRef, externalFilesHelper)) - .put(SkyFunctions.FILE_SYMLINK_CYCLE_UNIQUENESS, new FileSymlinkCycleUniquenessFunction()) + .put(FileSymlinkCycleUniquenessFunction.NAME, new FileSymlinkCycleUniquenessFunction()) .put( - SkyFunctions.FILE_SYMLINK_INFINITE_EXPANSION_UNIQUENESS, + FileSymlinkInfiniteExpansionUniquenessFunction.NAME, new FileSymlinkInfiniteExpansionUniquenessFunction()) .put(FileValue.FILE, new FileFunction(pkgLocatorRef)) .put(
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/packages/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/packages/BUILD index f0acc83..ccb25d4 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/packages/BUILD +++ b/src/main/java/com/google/devtools/build/lib/skyframe/packages/BUILD
@@ -36,14 +36,14 @@ "//src/main/java/com/google/devtools/build/lib/cmdline", "//src/main/java/com/google/devtools/build/lib/concurrent", "//src/main/java/com/google/devtools/build/lib/events", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_cycle_uniqueness_function", + "//src/main/java/com/google/devtools/build/lib/io:file_symlink_infinite_expansion_uniqueness_function", "//src/main/java/com/google/devtools/build/lib/packages", "//src/main/java/com/google/devtools/build/lib/pkgcache", "//src/main/java/com/google/devtools/build/lib/repository:external_package_helper", "//src/main/java/com/google/devtools/build/lib/skyframe:bzl_compile", "//src/main/java/com/google/devtools/build/lib/skyframe:containing_package_lookup_function", "//src/main/java/com/google/devtools/build/lib/skyframe:file_function", - "//src/main/java/com/google/devtools/build/lib/skyframe:file_symlink_cycle_uniqueness_function", - "//src/main/java/com/google/devtools/build/lib/skyframe:file_symlink_infinite_expansion_uniqueness_function", "//src/main/java/com/google/devtools/build/lib/skyframe:ignored_package_prefixes_function", "//src/main/java/com/google/devtools/build/lib/skyframe:managed_directories_knowledge", "//src/main/java/com/google/devtools/build/lib/skyframe:package_lookup_function",
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java b/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java index 2f97b3c..1f2ebfc 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java
@@ -16,6 +16,7 @@ import com.google.common.base.Preconditions; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import java.io.Serializable; +import java.util.Comparator; import java.util.Objects; import javax.annotation.Nullable; @@ -30,7 +31,7 @@ * clients via #asPath or #getRoot. */ @AutoCodec -public class RootedPath implements Serializable { +public class RootedPath implements Serializable, Comparable<RootedPath> { private final Root root; private final PathFragment rootRelativePath; @@ -128,9 +129,16 @@ return result; } - @Override public String toString() { return "[" + root + "]/[" + rootRelativePath + "]"; } + + @Override + public int compareTo(RootedPath o) { + return COMPARATOR.compare(this, o); + } + + private static final Comparator<RootedPath> COMPARATOR = + Comparator.comparing(RootedPath::getRoot).thenComparing(RootedPath::getRootRelativePath); }