aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar Kristina Chodorow <kchodorow@google.com>2016-01-28 14:38:31 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2016-01-28 15:30:43 +0000
commitb6fbab7115c1567705e7bddc7b79bdee6313fce3 (patch)
tree174281e412f825660fe186c95e67b7af863cfaf8 /src/main/java/com/google
parent6d44cab8167cfae55cd5a26940018efcbaa43154 (diff)
Resolve repository-relative labels within the current repository
Using $(location //foo) from an external repository was resolving to @//foo, not @repo//foo, which generally wouldn't be in the main repository. This may also fix other cases where getRelative was resolving incorrectly. Fixes #819. -- MOS_MIGRATED_REVID=113256854
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/cmdline/Label.java26
-rw-r--r--src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/Package.java3
3 files changed, 15 insertions, 16 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
index 7e1046f8a1..b1bcffa482 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
@@ -49,6 +49,8 @@ public final class Label implements Comparable<Label>, Serializable, SkylarkPrin
* things to Bazel.
*/
private static final ImmutableSet<PathFragment> ABSOLUTE_PACKAGE_NAMES = ImmutableSet.of(
+ // Used for select
+ new PathFragment("conditions"),
// dependencies that are a function of the configuration
new PathFragment("tools/defaults"),
// Visibility is labels aren't actually targets
@@ -370,18 +372,26 @@ public final class Label implements Comparable<Label>, Serializable, SkylarkPrin
*/
@SkylarkCallable(name = "relative", doc =
"Resolves a label that is either absolute (starts with <code>//</code>) or relative to the"
- + " current package.<br>"
+ + " current package. If this label is in a remote repository, the argument will be resolved "
+ + "relative to that repository. If the argument contains a repository, it will be returned "
+ + "as-is. Reserved labels will also be returned as-is.<br>"
+ "For example:<br>"
+ "<pre class=language-python>\n"
+ "Label(\"//foo/bar:baz\").relative(\":quux\") == Label(\"//foo/bar:quux\")\n"
+ "Label(\"//foo/bar:baz\").relative(\"//wiz:quux\") == Label(\"//wiz:quux\")\n"
+ + "Label(\"@repo//foo/bar:baz\").relative(\"//wiz:quux\") == Label(\"@repo//wiz:quux\")\n"
+ + "Label(\"@repo//foo/bar:baz\").relative(\"//visibility:public\") == "
+ + "Label(\"//visibility:public\")\n"
+ + "Label(\"@repo//foo/bar:baz\").relative(\"@other//wiz:quux\") == "
+ + "Label(\"@other//wiz:quux\")\n"
+ "</pre>")
public Label getRelative(String relName) throws LabelSyntaxException {
if (relName.length() == 0) {
throw new LabelSyntaxException("empty package-relative label");
}
+
if (LabelValidator.isAbsolute(relName)) {
- return parseAbsolute(relName);
+ return resolveRepositoryRelative(parseAbsolute(relName));
} else if (relName.equals(":")) {
throw new LabelSyntaxException("':' is not a valid package-relative label");
} else if (relName.charAt(0) == ':') {
@@ -399,18 +409,6 @@ public final class Label implements Comparable<Label>, Serializable, SkylarkPrin
* repository would point back to the main repository, which is usually not what is intended.
*/
public Label resolveRepositoryRelative(Label relative) {
- if (relative.packageIdentifier.getRepository().getName().equals("@")) {
- try {
- return new Label(
- PackageIdentifier.create(
- PackageIdentifier.DEFAULT_REPOSITORY_NAME,
- relative.packageIdentifier.getPackageFragment()),
- relative.getName());
- } catch (LabelSyntaxException e) {
- throw new IllegalStateException(e);
- }
- }
-
if (packageIdentifier.getRepository().isDefault()
|| !relative.packageIdentifier.getRepository().isDefault()
|| ABSOLUTE_PACKAGE_NAMES.contains(relative.getPackageIdentifier().getPackageFragment())) {
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java
index 2aa253dcb1..6f5811d58a 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java
@@ -189,7 +189,7 @@ public final class RepositoryName implements Serializable {
* Returns the path at which this repository is mapped within the exec root.
*/
public PathFragment getPathFragment() {
- return isDefault()
+ return isDefault() || this.equals(PackageIdentifier.MAIN_REPOSITORY_NAME)
? PathFragment.EMPTY_FRAGMENT
: new PathFragment(Label.EXTERNAL_PATH_PREFIX).getRelative(strippedName());
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Package.java b/src/main/java/com/google/devtools/build/lib/packages/Package.java
index 51a496dc7a..1cfb443936 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Package.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Package.java
@@ -267,7 +267,8 @@ public class Package {
private static Path getSourceRoot(Path buildFile, PathFragment packageFragment) {
Path current = buildFile.getParentDirectory();
- for (int i = 0, len = packageFragment.segmentCount(); i < len && current != null; i++) {
+ for (int i = 0, len = packageFragment.segmentCount();
+ i < len && !packageFragment.equals(PathFragment.EMPTY_FRAGMENT); i++) {
current = current.getParentDirectory();
}
return current;