aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Florian Weikert <fwe@google.com>2015-10-06 14:06:28 +0000
committerGravatar Lukacs Berki <lberki@google.com>2015-10-07 07:09:13 +0000
commita75b7b7cdd28cb6709131f36e951a904a7ebb734 (patch)
tree4c9774be3548c052799f0c9e79e88b3f7dc57828 /src
parentdf593e90a34dc379d1c762ee8ef83bc0207c130d (diff)
Rules created by Skylark Macros now store the workspace-relative path of the respective macro in the attribute "generator_location".
-- MOS_MIGRATED_REVID=104757928
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java27
2 files changed, 25 insertions, 3 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
index a7b7ae6ee8..6a1fa38b43 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
@@ -207,6 +207,7 @@ public class BaseRuleClasses {
.nonconfigurable("low-level attribute, used in TargetUtils without configurations"))
.add(attr("generator_name", STRING).undocumented("internal"))
.add(attr("generator_function", STRING).undocumented("internal"))
+ .add(attr("generator_location", STRING).undocumented("internal"))
.add(attr("testonly", BOOLEAN).value(testonlyDefault)
.nonconfigurable("policy decision: rules testability should be consistent"))
.add(attr("features", STRING_LIST).orderIndependent())
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
index eba884e4c4..b3f4037442 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
@@ -111,7 +111,8 @@ public class RuleFactory {
ruleClass + " cannot be in the WORKSPACE file " + "(used by " + label + ")");
}
- AttributesAndLocation generator = generatorAttributesForMacros(attributeValues, env, location);
+ AttributesAndLocation generator =
+ generatorAttributesForMacros(attributeValues, env, location, label);
try {
return ruleClass.createRuleWithLabel(
pkgBuilder, label, generator.attributes, eventHandler, ast, generator.location);
@@ -197,7 +198,7 @@ public class RuleFactory {
* <p>Otherwise, it returns the given attributes without any changes.
*/
private static AttributesAndLocation generatorAttributesForMacros(
- Map<String, Object> args, @Nullable Environment env, Location location) {
+ Map<String, Object> args, @Nullable Environment env, Location location, Label label) {
// Returns the original arguments if a) there is only the rule itself on the stack
// trace (=> no macro) or b) the attributes have already been set by Python pre-processing.
if (env == null) {
@@ -218,18 +219,38 @@ public class RuleFactory {
BaseFunction function = topCall.second;
String name = generator.getNameArg();
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
+
builder.putAll(args);
builder.put("generator_name", (name == null) ? args.get("name") : name);
builder.put("generator_function", function.getName());
+
if (generator.getLocation() != null) {
location = generator.getLocation();
+ builder.put("generator_location", getRelativeLocation(location, label));
}
try {
return new AttributesAndLocation(builder.build(), location);
} catch (IllegalArgumentException ex) {
- // Just to play it safe.
+ // We just fall back to the default case and swallow any messages.
return new AttributesAndLocation(args, location);
}
}
+
+ /**
+ * Uses the given label to retrieve the workspace-relative path of the given location.
+ */
+ private static String getRelativeLocation(Location location, Label label) {
+ String absolutePath = Location.printPathAndLine(location);
+ // Instead of using this substring-based approach, we would prefer to construct the path from
+ // the label itself, e.g.
+ // buildFileLabel.getPackageFragment().getRelative(buildFileLabel.getName()).getPathString().
+ // However, this seems to conflict with python pre-processing since we had seen cases where the
+ // label of the BUILD file is something like //package:BUILD while the location is actually
+ // /path/to/workspace/package/with/subpackage/BUILD. Consequently, we would lose the
+ // "with/subpackage" part.
+ int pos = absolutePath.indexOf(label.getPackageName());
+ Preconditions.checkArgument(pos > -1, "Cannot retrieve relative path for %s", absolutePath);
+ return absolutePath.substring(pos);
+ }
}