Allow package blacklisting to be done via a file checked into the depot. By default this is disabled. -- MOS_MIGRATED_REVID=107644420
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java new file mode 100644 index 0000000..11c78ae --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java
@@ -0,0 +1,110 @@ +// Copyright 2015 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.ImmutableSet; +import com.google.common.io.CharStreams; +import com.google.common.io.LineProcessor; +import com.google.devtools.build.lib.pkgcache.PathPackageLocator; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.RootedPath; +import com.google.devtools.build.skyframe.SkyFunction; +import com.google.devtools.build.skyframe.SkyFunctionException; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.SkyValue; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +import javax.annotation.Nullable; + +/** + * A function that retrieves a set of blacklisted package pattern prefixes from the file given by + * PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE. + */ +public class BlacklistedPackagePrefixesFunction implements SkyFunction { + @Nullable + @Override + public SkyValue compute(SkyKey key, Environment env) + throws SkyFunctionException, InterruptedException { + PathPackageLocator pkgLocator = PrecomputedValue.PATH_PACKAGE_LOCATOR.get(env); + PathFragment patternsFile = PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.get(env); + if (env.valuesMissing()) { + return null; + } + + if (patternsFile.equals(PathFragment.EMPTY_FRAGMENT)) { + return new BlacklistedPackagePrefixesValue(ImmutableSet.<PathFragment>of()); + } + + for (Path packagePathEntry : pkgLocator.getPathEntries()) { + RootedPath rootedPatternFile = RootedPath.toRootedPath(packagePathEntry, patternsFile); + FileValue patternFileValue = (FileValue) env.getValue(FileValue.key(rootedPatternFile)); + if (patternFileValue == null) { + return null; + } + if (patternFileValue.isFile()) { + try { + try (InputStreamReader reader = + new InputStreamReader(rootedPatternFile.asPath().getInputStream(), + StandardCharsets.UTF_8)) { + return new BlacklistedPackagePrefixesValue( + CharStreams.readLines(reader, new PathFragmentLineProcessor())); + } + } catch (IOException e) { + String errorMessage = e.getMessage() != null + ? "error '" + e.getMessage() + "'" : "an error"; + throw new BlacklistedPatternsFunctionException( + new InconsistentFilesystemException( + rootedPatternFile.asPath() + " is not readable because: " + errorMessage + + ". Was it modified mid-build?")); + } + } + } + + return new BlacklistedPackagePrefixesValue(ImmutableSet.<PathFragment>of()); + } + + private static final class PathFragmentLineProcessor + implements LineProcessor<ImmutableSet<PathFragment>> { + private final ImmutableSet.Builder<PathFragment> fragments = ImmutableSet.builder(); + + @Override + public boolean processLine(String line) throws IOException { + if (!line.isEmpty()) { + fragments.add(new PathFragment(line)); + } + return true; + } + + @Override + public ImmutableSet<PathFragment> getResult() { + return fragments.build(); + } + } + + @Nullable + @Override + public String extractTag(SkyKey skyKey) { + return null; + } + + private static final class BlacklistedPatternsFunctionException extends SkyFunctionException { + public BlacklistedPatternsFunctionException(InconsistentFilesystemException e) { + super(e, Transience.TRANSIENT); + } + } +}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesValue.java new file mode 100644 index 0000000..036f055 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesValue.java
@@ -0,0 +1,56 @@ +// 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.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.SkyValue; + +/** + * An immutable set of package name prefixes that should be blacklisted. + */ +public class BlacklistedPackagePrefixesValue implements SkyValue { + private final ImmutableSet<PathFragment> patterns; + + private static final SkyKey BLACKLIST_KEY = + new SkyKey(SkyFunctions.BLACKLISTED_PACKAGE_PREFIXES, ""); + + public BlacklistedPackagePrefixesValue(ImmutableSet<PathFragment> exclusions) { + this.patterns = Preconditions.checkNotNull(exclusions); + } + + public static SkyKey key() { + return BLACKLIST_KEY; + } + + public ImmutableSet<PathFragment> getPatterns() { + return patterns; + } + + @Override + public int hashCode() { + return patterns.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof BlacklistedPackagePrefixesValue) { + BlacklistedPackagePrefixesValue other = (BlacklistedPackagePrefixesValue) obj; + return this.patterns.equals(other.patterns); + } + return false; + } +}
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 3a4f7d6..28557d1 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
@@ -73,13 +73,14 @@ return PackageLookupValue.DELETED_PACKAGE_VALUE; } - ImmutableSet<PathFragment> patterns = PrecomputedValue.BLACKLISTED_PKG_PREFIXES.get(env); - if (patterns == null) { + BlacklistedPackagePrefixesValue blacklistedPatternsValue = + (BlacklistedPackagePrefixesValue) env.getValue(BlacklistedPackagePrefixesValue.key()); + if (blacklistedPatternsValue == null) { return null; } PathFragment buildFileFragment = packageKey.getPackageFragment(); - for (PathFragment pattern : patterns) { + for (PathFragment pattern : blacklistedPatternsValue.getPatterns()) { if (buildFileFragment.startsWith(pattern)) { return PackageLookupValue.DELETED_PACKAGE_VALUE; }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java index 518b538..0e17d97 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java
@@ -19,7 +19,6 @@ import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.TopLevelArtifactContext; @@ -77,8 +76,9 @@ public static final Precomputed<String> DEFAULTS_PACKAGE_CONTENTS = new Precomputed<>(new SkyKey(SkyFunctions.PRECOMPUTED, "default_pkg")); - public static final Precomputed<ImmutableSet<PathFragment>> BLACKLISTED_PKG_PREFIXES = - new Precomputed<>(new SkyKey(SkyFunctions.PRECOMPUTED, "blacklisted_pkg_patterns")); + public static final Precomputed<PathFragment> BLACKLISTED_PACKAGE_PREFIXES_FILE = + new Precomputed<>( + new SkyKey(SkyFunctions.PRECOMPUTED, "blacklisted_package_prefixes_file")); public static final Precomputed<RuleVisibility> DEFAULT_VISIBILITY = new Precomputed<>(new SkyKey(SkyFunctions.PRECOMPUTED, "default_visibility"));
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveDirectoryTraversalFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveDirectoryTraversalFunction.java index 3286908..4ee7430 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveDirectoryTraversalFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveDirectoryTraversalFunction.java
@@ -113,11 +113,13 @@ */ TReturn visitDirectory(RecursivePkgKey recursivePkgKey, Environment env) { RootedPath rootedPath = recursivePkgKey.getRootedPath(); - ImmutableSet<PathFragment> blacklist = PrecomputedValue.BLACKLISTED_PKG_PREFIXES.get(env); + BlacklistedPackagePrefixesValue blacklist = + (BlacklistedPackagePrefixesValue) env.getValue(BlacklistedPackagePrefixesValue.key()); if (blacklist == null) { return null; } - Set<PathFragment> excludedPaths = Sets.union(recursivePkgKey.getExcludedPaths(), blacklist); + Set<PathFragment> excludedPaths = + Sets.union(recursivePkgKey.getExcludedPaths(), blacklist.getPatterns()); Path root = rootedPath.getRoot(); PathFragment rootRelativePath = rootedPath.getRelativePath();
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 b041211..3ed5488 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
@@ -51,6 +51,8 @@ SkyFunctionName.create("PREPARE_DEPS_OF_PATTERN"); public static final SkyFunctionName PREPARE_DEPS_OF_TARGETS_UNDER_DIRECTORY = SkyFunctionName.create("PREPARE_DEPS_OF_TARGETS_UNDER_DIRECTORY"); + public static final SkyFunctionName BLACKLISTED_PACKAGE_PREFIXES = + SkyFunctionName.create("BLACKLISTED_PACKAGE_PREFIXES"); public static final SkyFunctionName TEST_SUITE_EXPANSION = SkyFunctionName.create("TEST_SUITE_EXPANSION"); public static final SkyFunctionName TESTS_IN_SUITE = SkyFunctionName.create("TESTS_IN_SUITE");
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 76ad0e7..c21a416 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
@@ -344,6 +344,7 @@ map.put(SkyFunctions.PREPARE_DEPS_OF_PATTERN, new PrepareDepsOfPatternFunction(pkgLocator)); map.put(SkyFunctions.PREPARE_DEPS_OF_TARGETS_UNDER_DIRECTORY, new PrepareDepsOfTargetsUnderDirectoryFunction()); + map.put(SkyFunctions.BLACKLISTED_PACKAGE_PREFIXES, new BlacklistedPackagePrefixesFunction()); map.put(SkyFunctions.TESTS_IN_SUITE, new TestsInSuiteFunction()); map.put(SkyFunctions.TEST_SUITE_EXPANSION, new TestSuiteExpansionFunction()); map.put(SkyFunctions.TARGET_PATTERN_PHASE, new TargetPatternPhaseFunction()); @@ -499,8 +500,8 @@ } } - protected ImmutableSet<PathFragment> getBlacklistedPkgPrefixes() { - return ImmutableSet.of(); + protected PathFragment getBlacklistedPackagePrefixesFile() { + return PathFragment.EMPTY_FRAGMENT; } class BuildViewProvider { @@ -861,8 +862,8 @@ public abstract void setDeletedPackages(Iterable<PackageIdentifier> pkgs); @VisibleForTesting - public final void setBlacklistedPkgPrefixes(ImmutableSet<PathFragment> blacklist) { - PrecomputedValue.BLACKLISTED_PKG_PREFIXES.set(injectable(), blacklist); + public final void setBlacklistedPackagePrefixesFile(PathFragment blacklistedPkgFile) { + PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(injectable(), blacklistedPkgFile); } /** @@ -879,7 +880,7 @@ maybeInjectPrecomputedValuesForAnalysis(); setCommandId(commandId); - setBlacklistedPkgPrefixes(getBlacklistedPkgPrefixes()); + setBlacklistedPackagePrefixesFile(getBlacklistedPackagePrefixesFile()); setShowLoadingProgress(showLoadingProgress); setDefaultVisibility(defaultVisibility); setupDefaultPackage(defaultsPackageContents);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java index 0c80029..72a47a5 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java
@@ -57,6 +57,8 @@ Map<SkyFunctionName, SkyFunction> skyFunctions = new HashMap<>(); skyFunctions.put(SkyFunctions.PACKAGE_LOOKUP, new PackageLookupFunction(deletedPackages)); skyFunctions.put(SkyFunctions.CONTAINING_PACKAGE_LOOKUP, new ContainingPackageLookupFunction()); + skyFunctions.put(SkyFunctions.BLACKLISTED_PACKAGE_PREFIXES, + new BlacklistedPackagePrefixesFunction()); skyFunctions.put(SkyFunctions.FILE_STATE, new FileStateFunction(tsgm, externalFilesHelper)); skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator, tsgm, externalFilesHelper)); RecordingDifferencer differencer = new RecordingDifferencer(); @@ -64,7 +66,8 @@ driver = new SequentialBuildDriver(evaluator); PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID()); PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); - PrecomputedValue.BLACKLISTED_PKG_PREFIXES.set(differencer, ImmutableSet.<PathFragment>of()); + PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(differencer, + PathFragment.EMPTY_FRAGMENT); } private ContainingPackageLookupValue lookupContainingPackage(String packageName)
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java index aa03d90..f8f0a45 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/FilesetEntryFunctionTest.java
@@ -94,6 +94,8 @@ skyFunctions.put( SkyFunctions.RECURSIVE_FILESYSTEM_TRAVERSAL, new RecursiveFilesystemTraversalFunction()); skyFunctions.put(SkyFunctions.PACKAGE_LOOKUP, new PackageLookupFunction(deletedPackages)); + skyFunctions.put(SkyFunctions.BLACKLISTED_PACKAGE_PREFIXES, + new BlacklistedPackagePrefixesFunction()); skyFunctions.put(SkyFunctions.FILESET_ENTRY, new FilesetEntryFunction()); differencer = new RecordingDifferencer(); @@ -101,7 +103,8 @@ driver = new SequentialBuildDriver(evaluator); PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID()); PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); - PrecomputedValue.BLACKLISTED_PKG_PREFIXES.set(differencer, ImmutableSet.<PathFragment>of()); + PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(differencer, + PathFragment.EMPTY_FRAGMENT); } private Artifact getSourceArtifact(String path) throws Exception {
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/GlobFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/GlobFunctionTest.java index 8aa1422..18b29f6 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/GlobFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/GlobFunctionTest.java
@@ -113,7 +113,8 @@ driver = new SequentialBuildDriver(evaluator); PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID()); PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); - PrecomputedValue.BLACKLISTED_PKG_PREFIXES.set(differencer, ImmutableSet.<PathFragment>of()); + PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set( + differencer, PathFragment.EMPTY_FRAGMENT); createTestFiles(); } @@ -130,6 +131,8 @@ new DirectoryListingStateFunction(externalFilesHelper)); skyFunctions.put(SkyFunctions.DIRECTORY_LISTING, new DirectoryListingFunction()); skyFunctions.put(SkyFunctions.PACKAGE_LOOKUP, new PackageLookupFunction(deletedPackages)); + skyFunctions.put(SkyFunctions.BLACKLISTED_PACKAGE_PREFIXES, + new BlacklistedPackagePrefixesFunction()); skyFunctions.put( SkyFunctions.FILE_STATE, new FileStateFunction(
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java index f96a43d..a1e5e9a 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java
@@ -17,7 +17,6 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.PackageIdentifier; @@ -79,8 +78,9 @@ ImmutableList<String> patternSequence = ImmutableList.of("//foo/..."); // and a blacklist for the malformed package, - getSkyframeExecutor().setBlacklistedPkgPrefixes( - ImmutableSet.of(new PathFragment("foo/foo"))); + getSkyframeExecutor().setBlacklistedPackagePrefixesFile( + new PathFragment("config/blacklist.txt")); + scratch.file("config/blacklist.txt", "foo/foo"); assertSkipsFoo(patternSequence); }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java index ee1dd8b..a4367e0 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java
@@ -90,6 +90,8 @@ skyFunctions.put( SkyFunctions.RECURSIVE_FILESYSTEM_TRAVERSAL, new RecursiveFilesystemTraversalFunction()); skyFunctions.put(SkyFunctions.PACKAGE_LOOKUP, new PackageLookupFunction(deletedPackages)); + skyFunctions.put(SkyFunctions.BLACKLISTED_PACKAGE_PREFIXES, + new BlacklistedPackagePrefixesFunction()); progressReceiver = new RecordingEvaluationProgressReceiver(); differencer = new RecordingDifferencer(); @@ -97,7 +99,8 @@ driver = new SequentialBuildDriver(evaluator); PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID()); PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); - PrecomputedValue.BLACKLISTED_PKG_PREFIXES.set(differencer, ImmutableSet.<PathFragment>of()); + PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set( + differencer, PathFragment.EMPTY_FRAGMENT); } private Artifact sourceArtifact(String path) {