diff options
4 files changed, 32 insertions, 13 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/LabelValidator.java b/src/main/java/com/google/devtools/build/lib/cmdline/LabelValidator.java index 0458469314..7d56f52ece 100644 --- a/src/main/java/com/google/devtools/build/lib/cmdline/LabelValidator.java +++ b/src/main/java/com/google/devtools/build/lib/cmdline/LabelValidator.java @@ -206,6 +206,13 @@ public final class LabelValidator { } /** + * Returns if the label starts with a repository (@whatever) or a package (//whatever). + */ + public static boolean isAbsolute(String label) { + return label.startsWith("//") || label.startsWith("@"); + } + + /** * Parses the given absolute label by verifying that it starts with "//". If it contains a ':', * then the part after that is the target name within the package, and the part before that (but * without the leading "//") is the package name. However, it performs no validation on these two @@ -217,9 +224,16 @@ public final class LabelValidator { * @throws BadLabelException if {@code absName} starts with "//" */ public static PackageAndTarget parseAbsoluteLabel(String absName) throws BadLabelException { - if (!absName.startsWith("//")) { + if (!isAbsolute(absName)) { throw new BadLabelException("invalid label: " + absName); } + if (absName.startsWith("@")) { + int endOfRepo = absName.indexOf("//"); + if (endOfRepo < 0) { + throw new BadLabelException("invalid fully-qualified label: " + absName); + } + absName = absName.substring(endOfRepo); + } // Find the package/suffix separation: int colonIndex = absName.indexOf(':'); int splitAt = colonIndex >= 0 ? colonIndex : absName.length(); 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 dee9659e8d..c10b252227 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 @@ -81,6 +81,7 @@ public abstract class TargetPattern implements Serializable { @VisibleForTesting static String normalize(String path) { Preconditions.checkArgument(!path.startsWith("/")); + Preconditions.checkArgument(!path.startsWith("@")); Iterator<String> it = SLASH_SPLITTER.split(path).iterator(); List<String> pieces = new ArrayList<>(); while (it.hasNext()) { @@ -502,6 +503,16 @@ public abstract class TargetPattern implements Serializable { // constant (see lib/blaze/commands/target-syntax.txt). String originalPattern = pattern; + final boolean includesRepo = pattern.startsWith("@"); + String repoName = ""; + if (includesRepo) { + int pkgStart = pattern.indexOf("//"); + if (pkgStart < 0) { + throw new TargetParsingException("Couldn't find package in target " + pattern); + } + repoName = pattern.substring(0, pkgStart); + pattern = pattern.substring(pkgStart); + } final boolean isAbsolute = pattern.startsWith("//"); // We now absolutize non-absolute target patterns. @@ -553,9 +564,9 @@ public abstract class TargetPattern implements Serializable { } - if (isAbsolute || pattern.contains(":")) { + if (includesRepo || isAbsolute || pattern.contains(":")) { PackageAndTarget packageAndTarget; - String fullLabel = "//" + pattern; + String fullLabel = repoName + "//" + pattern; try { packageAndTarget = LabelValidator.validateAbsoluteLabel(fullLabel); } catch (BadLabelException e) { diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Label.java b/src/main/java/com/google/devtools/build/lib/syntax/Label.java index e1c28aa53f..5a744c0f6a 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/Label.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/Label.java @@ -135,7 +135,7 @@ public final class Label implements Comparable<Label>, Serializable { public static Label parseCommandLineLabel(String label, PathFragment workspaceRelativePath) throws SyntaxException { Preconditions.checkArgument(!workspaceRelativePath.isAbsolute()); - if (isAbsolute(label)) { + if (LabelValidator.isAbsolute(label)) { return parseAbsolute(label); } int index = label.indexOf(':'); @@ -150,13 +150,6 @@ public final class Label implements Comparable<Label>, Serializable { } /** - * Returns if the label starts with a repository (@whatever) or a package (//whatever). - */ - private static boolean isAbsolute(String label) { - return label.startsWith("//") || label.startsWith("@"); - } - - /** * Validates the given target name and returns a canonical String instance if it is valid. * Otherwise it throws a SyntaxException. */ @@ -351,7 +344,7 @@ public final class Label implements Comparable<Label>, Serializable { if (relName.length() == 0) { throw new SyntaxException("empty package-relative label"); } - if (isAbsolute(relName)) { + if (LabelValidator.isAbsolute(relName)) { return parseAbsolute(relName); } else if (relName.equals(":")) { throw new SyntaxException("':' is not a valid package-relative label"); diff --git a/src/test/shell/bazel/local_repository_test.sh b/src/test/shell/bazel/local_repository_test.sh index 3aa6363903..7b6f993adb 100755 --- a/src/test/shell/bazel/local_repository_test.sh +++ b/src/test/shell/bazel/local_repository_test.sh @@ -138,7 +138,8 @@ public class BallPit { } EOF - bazel fetch //zoo:ball-pit || fail "Fetch failed" + bazel build @endangered//carnivore:mongoose >& $TEST_log || \ + fail "Expected build to succeed" bazel run //zoo:ball-pit >& $TEST_log expect_log "Tra-la!" } |