aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/packages
diff options
context:
space:
mode:
authorGravatar cushon <cushon@google.com>2017-11-21 13:17:49 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2017-11-21 13:20:08 -0800
commit7cc8efe44a167d818deb77e53f12cecc15b4e4aa (patch)
tree79577e2bdcfb003f577c3e880ec8dd743ec9f6e6 /src/main/java/com/google/devtools/build/lib/packages
parent59d2ece50d7998e355afff8fd7cabd4215fc070d (diff)
Add support for negative package specifications
Package specifications can now be prefixed with `-` to indicate negation: the specification `-//foo/bar/...` excludes all packages under `//foo/bar` that would otherwise have been matched. RELNOTES: Package specifications can now be prefixed with `-` to indicate negation PiperOrigin-RevId: 176551382
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/packages')
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/PackageSpecification.java77
1 files changed, 75 insertions, 2 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageSpecification.java b/src/main/java/com/google/devtools/build/lib/packages/PackageSpecification.java
index 63823fbcaa..56d59e09c2 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageSpecification.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageSpecification.java
@@ -43,6 +43,7 @@ public abstract class PackageSpecification {
private static final String PACKAGE_LABEL = "__pkg__";
private static final String SUBTREE_LABEL = "__subpackages__";
private static final String ALL_BENEATH_SUFFIX = "/...";
+ private static final String NEGATIVE_PREFIX = "-";
/** Returns {@code true} if the package spec includes the provided {@code packageName}. */
protected abstract boolean containsPackage(PackageIdentifier packageName);
@@ -56,6 +57,11 @@ public abstract class PackageSpecification {
*/
protected abstract String toStringWithoutRepository();
+ /** Returns {@code true} if the package specification represents a negated match. */
+ protected boolean negative() {
+ return false;
+ }
+
/**
* Parses the provided {@link String} into a {@link PackageSpecification}.
*
@@ -81,6 +87,18 @@ public abstract class PackageSpecification {
public static PackageSpecification fromString(RepositoryName repositoryName, String spec)
throws InvalidPackageSpecificationException {
String result = spec;
+ boolean negative = false;
+ if (result.startsWith(NEGATIVE_PREFIX)) {
+ negative = true;
+ result = result.substring(NEGATIVE_PREFIX.length());
+ }
+ PackageSpecification packageSpecification = fromStringPositive(repositoryName, result);
+ return negative ? new NegativePackageSpecification(packageSpecification) : packageSpecification;
+ }
+
+ private static PackageSpecification fromStringPositive(RepositoryName repositoryName, String spec)
+ throws InvalidPackageSpecificationException {
+ String result = spec;
boolean allBeneath = false;
if (result.endsWith(ALL_BENEATH_SUFFIX)) {
allBeneath = true;
@@ -225,6 +243,50 @@ public abstract class PackageSpecification {
}
}
+ /** A package specification for a negative match, e.g. {@code -//pkg/sub/...}. */
+ private static class NegativePackageSpecification extends PackageSpecification {
+
+ private final PackageSpecification delegate;
+
+ private NegativePackageSpecification(PackageSpecification delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ protected boolean negative() {
+ return true;
+ }
+
+ @Override
+ protected boolean containsPackage(PackageIdentifier packageName) {
+ return delegate.containsPackage(packageName);
+ }
+
+ @Override
+ protected String toStringWithoutRepository() {
+ return "-" + delegate.toStringWithoutRepository();
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ return obj instanceof NegativePackageSpecification
+ && delegate.equals(((NegativePackageSpecification) obj).delegate);
+ }
+
+ @Override
+ public String toString() {
+ return "-" + delegate;
+ }
+ }
+
private static class AllPackages extends PackageSpecification {
private static final PackageSpecification EVERYTHING = new AllPackages();
@@ -286,10 +348,21 @@ public abstract class PackageSpecification {
/**
* Returns {@code true} if the package specifications include the provided {@code packageName}.
- * That is, at least one positive package specification matches.
+ * That is, at least one positive package specification matches, and no negative package
+ * specifications match.
*/
public boolean containsPackage(PackageIdentifier packageIdentifier) {
- return packageSpecifications.stream().anyMatch(p -> p.containsPackage(packageIdentifier));
+ boolean match = false;
+ for (PackageSpecification p : packageSpecifications) {
+ if (p.containsPackage(packageIdentifier)) {
+ if (p.negative()) {
+ return false;
+ } else {
+ match = true;
+ }
+ }
+ }
+ return match;
}
/**