TargetsBelowDirectory#getAllIgnoredSubdirectoriesToExclude explicitly return whether it's been fully filtered by the ignored directories.
RELNOTES[INC]: Specifying a target pattern underneath a directory specified by .bazelignore will now emit a warning, not an error.
PiperOrigin-RevId: 353281197
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java b/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
index b6180c3..21eb22f 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.cmdline;
import static com.google.common.util.concurrent.Futures.immediateCancelledFuture;
+import static com.google.common.util.concurrent.Futures.immediateVoidFuture;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
@@ -551,14 +552,17 @@
"Fully excluded target pattern %s should have already been filtered out (%s)",
this,
excludedSubdirectories);
- ImmutableSet<PathFragment> filteredIgnored =
+ IgnoredPathFragmentsInScopeOrFilteringIgnorer ignoredIntersection =
getAllIgnoredSubdirectoriesToExclude(ignoredSubdirectories);
+ if (warnIfFiltered(ignoredIntersection, resolver)) {
+ return;
+ }
resolver.findTargetsBeneathDirectory(
directory.getRepository(),
getOriginalPattern(),
directory.getPackageFragment().getPathString(),
rulesOnly,
- filteredIgnored,
+ ignoredIntersection.ignoredPathFragments(),
excludedSubdirectories,
callback,
exceptionClass);
@@ -577,38 +581,136 @@
"Fully excluded target pattern %s should have already been filtered out (%s)",
this,
excludedSubdirectories);
- ImmutableSet<PathFragment> filteredIgnored;
+ IgnoredPathFragmentsInScopeOrFilteringIgnorer ignoredIntersection;
try {
- filteredIgnored = getAllIgnoredSubdirectoriesToExclude(ignoredSubdirectories);
+ ignoredIntersection = getAllIgnoredSubdirectoriesToExclude(ignoredSubdirectories);
} catch (InterruptedException e) {
return immediateCancelledFuture();
}
+ if (warnIfFiltered(ignoredIntersection, resolver)) {
+ return immediateVoidFuture();
+ }
return resolver.findTargetsBeneathDirectoryAsync(
directory.getRepository(),
getOriginalPattern(),
directory.getPackageFragment().getPathString(),
rulesOnly,
- filteredIgnored,
+ ignoredIntersection.ignoredPathFragments(),
excludedSubdirectories,
callback,
exceptionClass,
executor);
}
- public ImmutableSet<PathFragment> getAllIgnoredSubdirectoriesToExclude(
+ private boolean warnIfFiltered(
+ IgnoredPathFragmentsInScopeOrFilteringIgnorer ignoredIntersection,
+ TargetPatternResolver<?> resolver) {
+ if (ignoredIntersection.wasFiltered()) {
+ resolver.warn(
+ "Pattern '"
+ + getOriginalPattern()
+ + "' was filtered out by ignored directory '"
+ + ignoredIntersection.filteringIgnorer().getPathString()
+ + "'");
+ return true;
+ }
+ return false;
+ }
+
+ public IgnoredPathFragmentsInScopeOrFilteringIgnorer getAllIgnoredSubdirectoriesToExclude(
InterruptibleSupplier<ImmutableSet<PathFragment>> ignoredPackagePrefixes)
throws InterruptedException {
- ImmutableSet<PathFragment> ignoredPaths = ignoredPackagePrefixes.get();
ImmutableSet.Builder<PathFragment> ignoredPathsBuilder =
ImmutableSet.builderWithExpectedSize(0);
- for (PathFragment ignoredPackagePrefix : ignoredPaths) {
+ for (PathFragment ignoredPackagePrefix : ignoredPackagePrefixes.get()) {
+ if (this.containedIn(ignoredPackagePrefix)) {
+ return new IgnoredPathFragmentsInScopeOrFilteringIgnorer.FilteringIgnorer(
+ ignoredPackagePrefix);
+ }
PackageIdentifier pkgIdForIgnoredDirectorPrefix =
PackageIdentifier.create(this.getDirectory().getRepository(), ignoredPackagePrefix);
if (this.containsAllTransitiveSubdirectories(pkgIdForIgnoredDirectorPrefix)) {
ignoredPathsBuilder.add(ignoredPackagePrefix);
}
}
- return ignoredPathsBuilder.build();
+ return IgnoredPathFragmentsInScopeOrFilteringIgnorer.IgnoredPathFragments.of(
+ ignoredPathsBuilder.build());
+ }
+
+ /**
+ * Morally an {@code Either<ImmutableSet<PathFragment>, PathFragment>}, saying whether the given
+ * set of ignored directories intersected a directory (in which case the directories that were
+ * in the intersection are returned) or completely contained it (in which case a containing
+ * directory is returned).
+ */
+ public abstract static class IgnoredPathFragmentsInScopeOrFilteringIgnorer {
+ public abstract boolean wasFiltered();
+
+ public abstract ImmutableSet<PathFragment> ignoredPathFragments();
+
+ public abstract PathFragment filteringIgnorer();
+
+ private static class IgnoredPathFragments
+ extends IgnoredPathFragmentsInScopeOrFilteringIgnorer {
+ private static final IgnoredPathFragments EMPTYSET_IGNORED =
+ new IgnoredPathFragments(ImmutableSet.of());
+
+ private final ImmutableSet<PathFragment> ignoredPathFragments;
+
+ private IgnoredPathFragments(ImmutableSet<PathFragment> ignoredPathFragments) {
+ this.ignoredPathFragments = ignoredPathFragments;
+ }
+
+ static IgnoredPathFragments of(ImmutableSet<PathFragment> ignoredPathFragments) {
+ if (ignoredPathFragments.isEmpty()) {
+ return EMPTYSET_IGNORED;
+ }
+ return new IgnoredPathFragments(ignoredPathFragments);
+ }
+
+ @Override
+ public boolean wasFiltered() {
+ return false;
+ }
+
+ @Override
+ public ImmutableSet<PathFragment> ignoredPathFragments() {
+ return ignoredPathFragments;
+ }
+
+ @Override
+ public PathFragment filteringIgnorer() {
+ throw new UnsupportedOperationException("No filter: " + ignoredPathFragments);
+ }
+ }
+
+ private static class FilteringIgnorer extends IgnoredPathFragmentsInScopeOrFilteringIgnorer {
+ private final PathFragment filteringIgnorer;
+
+ FilteringIgnorer(PathFragment filteringIgnorer) {
+ this.filteringIgnorer = filteringIgnorer;
+ }
+
+ @Override
+ public boolean wasFiltered() {
+ return true;
+ }
+
+ @Override
+ public ImmutableSet<PathFragment> ignoredPathFragments() {
+ throw new UnsupportedOperationException("was filtered: " + filteringIgnorer);
+ }
+
+ @Override
+ public PathFragment filteringIgnorer() {
+ return filteringIgnorer;
+ }
+ }
+ }
+
+ /** Is {@code containingDirectory} an ancestor of or equal to this {@link #directory}? */
+ public boolean containedIn(PathFragment containingDirectory) {
+ return directory.getPackageFragment().startsWith(containingDirectory);
}
/**