aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Lukacs Berki <lberki@google.com>2015-09-24 07:48:36 +0000
committerGravatar Philipp Wollermann <philwo@google.com>2015-09-24 14:21:47 +0000
commit960dc27e8cfecec2448b92810dfa14d3ce4f2f1e (patch)
treed3ba11f45770e89303c8857f0ad21a751a17db90
parent402d112bc25449f1e690bbbace600bbcda834d24 (diff)
Make intra-package wildcards work for remote repositories and clean up target pattern parsing just a tiny little bit.
This wounds #389 dealing 4d6 fire damage (recursive wildcards, e.g. /... and friends still don't work) -- MOS_MIGRATED_REVID=103822319
-rw-r--r--src/main/java/com/google/devtools/build/lib/cmdline/TargetPattern.java97
-rw-r--r--src/main/java/com/google/devtools/build/lib/cmdline/TargetPatternResolver.java14
-rw-r--r--src/main/java/com/google/devtools/build/lib/pkgcache/TargetPatternResolverUtil.java23
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/RecursivePackageProviderBackedTargetPatternResolver.java9
-rwxr-xr-xsrc/test/shell/bazel/local_repository_test.sh24
6 files changed, 98 insertions, 74 deletions
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 6dc23857ad..d456059b23 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
@@ -22,6 +22,8 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.cmdline.LabelValidator.BadLabelException;
import com.google.devtools.build.lib.cmdline.LabelValidator.PackageAndTarget;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier.RepositoryName;
+import com.google.devtools.build.lib.util.StringUtilities;
import java.io.Serializable;
import java.util.ArrayList;
@@ -197,7 +199,7 @@ public abstract class TargetPattern implements Serializable {
Preconditions.checkArgument(excludedSubdirectories.isEmpty(),
"Target pattern \"%s\" of type %s cannot be evaluated with excluded subdirectories: %s.",
getOriginalPattern(), getType(), excludedSubdirectories);
- return resolver.getExplicitTarget(targetName);
+ return resolver.getExplicitTarget(label(targetName));
}
@Override
@@ -251,7 +253,7 @@ public abstract class TargetPattern implements Serializable {
getOriginalPattern(), getType(), excludedSubdirectories);
if (resolver.isPackage(PackageIdentifier.createInDefaultRepo(path))) {
// User has specified a package name. lookout for default target.
- return resolver.getExplicitTarget("//" + path);
+ return resolver.getExplicitTarget(label("//" + path));
}
List<String> pieces = SLASH_SPLITTER.splitToList(path);
@@ -262,7 +264,7 @@ public abstract class TargetPattern implements Serializable {
String packageName = SLASH_JOINER.join(pieces.subList(0, i));
if (resolver.isPackage(PackageIdentifier.createInDefaultRepo(packageName))) {
String targetName = SLASH_JOINER.join(pieces.subList(i, pieces.size()));
- return resolver.getExplicitTarget("//" + packageName + ":" + targetName);
+ return resolver.getExplicitTarget(label("//" + packageName + ":" + targetName));
}
}
@@ -305,16 +307,16 @@ public abstract class TargetPattern implements Serializable {
private static final class TargetsInPackage extends TargetPattern {
- private final String pattern;
+ private final PackageIdentifier packageIdentifier;
private final String suffix;
private final boolean isAbsolute;
private final boolean rulesOnly;
private final boolean checkWildcardConflict;
- private TargetsInPackage(String originalPattern, String pattern, String suffix,
- boolean isAbsolute, boolean rulesOnly, boolean checkWildcardConflict) {
+ private TargetsInPackage(String originalPattern, PackageIdentifier packageIdentifier,
+ String suffix, boolean isAbsolute, boolean rulesOnly, boolean checkWildcardConflict) {
super(Type.TARGETS_IN_PACKAGE, originalPattern);
- this.pattern = Preconditions.checkNotNull(pattern);
+ this.packageIdentifier = packageIdentifier;
this.suffix = Preconditions.checkNotNull(suffix);
this.isAbsolute = isAbsolute;
this.rulesOnly = rulesOnly;
@@ -335,17 +337,7 @@ public abstract class TargetPattern implements Serializable {
}
}
- String packageName = removeSuffix(pattern, suffix);
-
- try {
- PackageIdentifier.parse(packageName);
- } catch (LabelSyntaxException e) {
- throw new TargetParsingException(
- "Invalid package name '" + packageName + "': " + e.getMessage());
- }
-
- return resolver.getTargetsInPackage(getOriginalPattern(),
- PackageIdentifier.createInDefaultRepo(packageName), rulesOnly);
+ return resolver.getTargetsInPackage(getOriginalPattern(), packageIdentifier, rulesOnly);
}
@Override
@@ -355,7 +347,7 @@ public abstract class TargetPattern implements Serializable {
@Override
public String getDirectory() {
- return removeSuffix(pattern, suffix);
+ return packageIdentifier.getPackageFragment().getPathString();
}
@Override
@@ -375,13 +367,13 @@ public abstract class TargetPattern implements Serializable {
return isAbsolute == that.isAbsolute && rulesOnly == that.rulesOnly
&& checkWildcardConflict == that.checkWildcardConflict
&& getOriginalPattern().equals(that.getOriginalPattern())
- && pattern.equals(that.pattern) && suffix.equals(that.suffix);
+ && packageIdentifier.equals(that.packageIdentifier) && suffix.equals(that.suffix);
}
@Override
public int hashCode() {
- return Objects.hash(getType(), getOriginalPattern(), pattern, suffix, isAbsolute, rulesOnly,
- checkWildcardConflict);
+ return Objects.hash(getType(), getOriginalPattern(), packageIdentifier, suffix, isAbsolute,
+ rulesOnly, checkWildcardConflict);
}
/**
@@ -397,18 +389,23 @@ public abstract class TargetPattern implements Serializable {
return null;
}
- T target = resolver.getTargetOrNull("//" + pattern);
+ T target;
+ Label label;
+ try {
+ label = Label.create(packageIdentifier, suffix);
+ target = resolver.getTargetOrNull(label);
+ } catch (LabelSyntaxException e) {
+ return null;
+ }
+
if (target != null) {
- String name = pattern.lastIndexOf(':') != -1
- ? pattern.substring(pattern.lastIndexOf(':') + 1)
- : pattern.substring(pattern.lastIndexOf('/') + 1);
- resolver.warn(String.format("The Blaze target pattern '%s' is ambiguous: '%s' is " +
+ resolver.warn(String.format("The target pattern '%s' is ambiguous: '%s' is " +
"both a wildcard, and the name of an existing %s; " +
"using the latter interpretation",
- "//" + pattern, ":" + name,
+ getOriginalPattern(), ":" + suffix,
resolver.getTargetKind(target)));
try {
- return resolver.getExplicitTarget("//" + pattern);
+ return resolver.getExplicitTarget(label);
} catch (TargetParsingException e) {
throw new IllegalStateException(
"getTargetOrNull() returned non-null, so target should exist", e);
@@ -548,13 +545,18 @@ public abstract class TargetPattern implements Serializable {
String originalPattern = pattern;
final boolean includesRepo = pattern.startsWith("@");
- String repoName = "";
+ RepositoryName repository = PackageIdentifier.DEFAULT_REPOSITORY_NAME;
if (includesRepo) {
int pkgStart = pattern.indexOf("//");
if (pkgStart < 0) {
throw new TargetParsingException("Couldn't find package in target " + pattern);
}
- repoName = pattern.substring(0, pkgStart);
+ try {
+ repository = RepositoryName.create(pattern.substring(0, pkgStart));
+ } catch (LabelSyntaxException e) {
+ throw new TargetParsingException(e.getMessage());
+ }
+
pattern = pattern.substring(pkgStart);
}
final boolean isAbsolute = pattern.startsWith("//");
@@ -598,19 +600,32 @@ public abstract class TargetPattern implements Serializable {
}
if (ALL_RULES_IN_SUFFIXES.contains(targetPart)) {
+ PackageIdentifier packageIdentifier;
+ try {
+ packageIdentifier = PackageIdentifier.parse(repository.getName() + "//" + packagePart);
+ } catch (LabelSyntaxException e) {
+ throw new TargetParsingException(
+ "Invalid package name '" + packagePart + "': " + e.getMessage());
+ }
return new TargetsInPackage(
- originalPattern, pattern, ":" + targetPart, isAbsolute, true, true);
+ originalPattern, packageIdentifier, targetPart, isAbsolute, true, true);
}
if (ALL_TARGETS_IN_SUFFIXES.contains(targetPart)) {
+ PackageIdentifier packageIdentifier;
+ try {
+ packageIdentifier = PackageIdentifier.parse(repository.getName() + "//" + packagePart);
+ } catch (LabelSyntaxException e) {
+ throw new TargetParsingException(
+ "Invalid package name '" + packagePart + "': " + e.getMessage());
+ }
return new TargetsInPackage(
- originalPattern, pattern, ":" + targetPart, isAbsolute, false, true);
+ originalPattern, packageIdentifier, targetPart, isAbsolute, false, true);
}
-
if (includesRepo || isAbsolute || pattern.contains(":")) {
PackageAndTarget packageAndTarget;
- String fullLabel = repoName + "//" + pattern;
+ String fullLabel = repository.getName() + "//" + pattern;
try {
packageAndTarget = LabelValidator.validateAbsoluteLabel(fullLabel);
} catch (BadLabelException e) {
@@ -666,6 +681,18 @@ public abstract class TargetPattern implements Serializable {
}
}
+ // Parse 'label' as a Label, mapping LabelSyntaxException into
+ // TargetParsingException.
+ private static Label label(String label) throws TargetParsingException {
+ try {
+ return Label.parseAbsolute(label);
+ } catch (LabelSyntaxException e) {
+ throw new TargetParsingException("invalid target format: '"
+ + StringUtilities.sanitizeControlChars(label) + "'; "
+ + StringUtilities.sanitizeControlChars(e.getMessage()));
+ }
+ }
+
/**
* The target pattern type (targets below package, in package, explicit target, etc.)
*/
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/TargetPatternResolver.java b/src/main/java/com/google/devtools/build/lib/cmdline/TargetPatternResolver.java
index d106692d9f..abcd516f37 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/TargetPatternResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/TargetPatternResolver.java
@@ -32,15 +32,15 @@ public interface TargetPatternResolver<T> {
void warn(String msg);
/**
- * Returns a single target corresponding to the given name, or null. This method may only throw an
- * exception if the current thread was interrupted.
+ * Returns a single target corresponding to the given label, or null. This method may only throw
+ * an exception if the current thread was interrupted.
*/
- T getTargetOrNull(String targetName) throws InterruptedException;
+ T getTargetOrNull(Label label) throws InterruptedException;
/**
- * Returns a single target corresponding to the given name, or an empty or failed result.
+ * Returns a single target corresponding to the given label, or an empty or failed result.
*/
- ResolvedTargets<T> getExplicitTarget(String targetName)
+ ResolvedTargets<T> getExplicitTarget(Label label)
throws TargetParsingException, InterruptedException;
/**
@@ -83,8 +83,8 @@ public interface TargetPatternResolver<T> {
throws TargetParsingException, InterruptedException;
/**
- * Returns true, if and only if the given name corresponds to a package, i.e., a file with the
- * name {@code packageName/BUILD} exists.
+ * Returns true, if and only if the given package identifier corresponds to a package, i.e., a
+ * file with the name {@code packageName/BUILD} exists in the appropriat repository.
*/
boolean isPackage(PackageIdentifier packageIdentifier);
diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/TargetPatternResolverUtil.java b/src/main/java/com/google/devtools/build/lib/pkgcache/TargetPatternResolverUtil.java
index 60a0d64f8a..0e86f7f2d1 100644
--- a/src/main/java/com/google/devtools/build/lib/pkgcache/TargetPatternResolverUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/pkgcache/TargetPatternResolverUtil.java
@@ -14,8 +14,6 @@
package com.google.devtools.build.lib.pkgcache;
import com.google.common.collect.ImmutableSet;
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.LabelValidator;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.ResolvedTargets;
@@ -23,7 +21,6 @@ import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.cmdline.TargetPatternResolver;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Target;
-import com.google.devtools.build.lib.util.StringUtilities;
import com.google.devtools.build.lib.vfs.PathFragment;
/**
@@ -34,26 +31,6 @@ public final class TargetPatternResolverUtil {
// Utility class.
}
- // Parse 'label' as a Label, mapping LabelSyntaxException into
- // TargetParsingException.
- public static Label label(String label) throws TargetParsingException {
- try {
- return Label.parseAbsolute(label);
- } catch (LabelSyntaxException e) {
- throw invalidTarget(label, e.getMessage());
- }
- }
-
- /**
- * Returns a new exception indicating that a command-line target is invalid.
- */
- private static TargetParsingException invalidTarget(String packageName,
- String additionalMessage) {
- return new TargetParsingException("invalid target format: '" +
- StringUtilities.sanitizeControlChars(packageName) + "'; " +
- StringUtilities.sanitizeControlChars(additionalMessage));
- }
-
public static String getParsingErrorMessage(String message, String originalPattern) {
if (originalPattern == null) {
return message;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java
index a48117f757..34f5f0474a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java
@@ -131,7 +131,7 @@ public class PrepareDepsOfPatternFunction implements SkyFunction {
}
@Override
- public Void getTargetOrNull(String targetName) throws InterruptedException {
+ public Void getTargetOrNull(Label label) throws InterruptedException {
// Note:
// This method is used in just one place, TargetPattern.TargetsInPackage#getWildcardConflict.
// Returning null tells #getWildcardConflict that there is not a target with a name like
@@ -142,9 +142,8 @@ public class PrepareDepsOfPatternFunction implements SkyFunction {
}
@Override
- public ResolvedTargets<Void> getExplicitTarget(String targetName)
+ public ResolvedTargets<Void> getExplicitTarget(Label label)
throws TargetParsingException, InterruptedException {
- Label label = TargetPatternResolverUtil.label(targetName);
try {
Target target = packageProvider.getTarget(env.getListener(), label);
SkyKey key = TransitiveTraversalValue.key(target.getLabel());
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePackageProviderBackedTargetPatternResolver.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePackageProviderBackedTargetPatternResolver.java
index 147a4e7046..25af04ec7f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePackageProviderBackedTargetPatternResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePackageProviderBackedTargetPatternResolver.java
@@ -15,7 +15,6 @@ package com.google.devtools.build.lib.skyframe;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.PackageIdentifier.RepositoryName;
import com.google.devtools.build.lib.cmdline.ResolvedTargets;
@@ -73,22 +72,20 @@ public class RecursivePackageProviderBackedTargetPatternResolver
}
@Override
- public Target getTargetOrNull(String targetName) throws InterruptedException {
+ public Target getTargetOrNull(Label label) throws InterruptedException {
try {
- Label label = Label.parseAbsolute(targetName);
if (!isPackage(label.getPackageIdentifier())) {
return null;
}
return recursivePackageProvider.getTarget(eventHandler, label);
- } catch (LabelSyntaxException | NoSuchThingException e) {
+ } catch (NoSuchThingException e) {
return null;
}
}
@Override
- public ResolvedTargets<Target> getExplicitTarget(String targetName)
+ public ResolvedTargets<Target> getExplicitTarget(Label label)
throws TargetParsingException, InterruptedException {
- Label label = TargetPatternResolverUtil.label(targetName);
try {
Target target = recursivePackageProvider.getTarget(eventHandler, label);
return policy.shouldRetain(target, true)
diff --git a/src/test/shell/bazel/local_repository_test.sh b/src/test/shell/bazel/local_repository_test.sh
index 9fc7a76e7a..e24149a706 100755
--- a/src/test/shell/bazel/local_repository_test.sh
+++ b/src/test/shell/bazel/local_repository_test.sh
@@ -824,4 +824,28 @@ EOF
expect_log "Hello User"
}
+function test_package_wildcard_in_remote_repository() {
+ local r=$TEST_TMPDIR/r
+ rm -fr $r
+ mkdir -p $r/a
+ touch $r/{x,y,a/g,a/h}
+ cat > $r/BUILD <<EOF
+exports_files(["x", "y"])
+EOF
+
+ cat > $r/a/BUILD <<EOF
+exports_files(["g", "h"])
+EOF
+
+ cat > WORKSPACE <<EOF
+local_repository(name="r", path="$r")
+EOF
+
+ bazel query @r//:all-targets + @r//a:all-targets >& $TEST_log || fail "query failed"
+ expect_log "@r//:x"
+ expect_log "@r//:y"
+ expect_log "@r//a:g"
+ expect_log "@r//a:h"
+}
+
run_suite "local repository tests"