aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java93
1 files changed, 80 insertions, 13 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 8f5351fd8c..875e89ff74 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -358,10 +358,10 @@ public final class RuleContext extends TargetContext
@Override
public void attributeError(String attrName, String message) {
reportError(rule.getAttributeLocation(attrName),
- prefixAttributeMessage(Attribute.isImplicit(attrName)
- ? "(an implicit dependency)"
- : attrName,
- message));
+ prefixAttributeMessage(Attribute.isImplicit(attrName)
+ ? "(an implicit dependency)"
+ : attrName,
+ message));
}
/**
@@ -373,10 +373,10 @@ public final class RuleContext extends TargetContext
@Override
public void attributeWarning(String attrName, String message) {
reportWarning(rule.getAttributeLocation(attrName),
- prefixAttributeMessage(Attribute.isImplicit(attrName)
- ? "(an implicit dependency)"
- : attrName,
- message));
+ prefixAttributeMessage(Attribute.isImplicit(attrName)
+ ? "(an implicit dependency)"
+ : attrName,
+ message));
}
private String prefixAttributeMessage(String attrName, String message) {
@@ -424,8 +424,12 @@ public final class RuleContext extends TargetContext
* signature.
*/
private Artifact internalCreateOutputArtifact(Target target) {
+ Preconditions.checkState(
+ target.getLabel().getPackageIdentifier().equals(getLabel().getPackageIdentifier()),
+ "Creating output artifact for target '%s' in different package than the rule '%s' "
+ + "being analyzed", target.getLabel(), getLabel());
Root root = getBinOrGenfilesDirectory();
- return getAnalysisEnvironment().getDerivedArtifact(Util.getWorkspaceRelativePath(target), root);
+ return getPackageRelativeArtifact(target.getName(), root);
}
/**
@@ -440,6 +444,71 @@ public final class RuleContext extends TargetContext
: getConfiguration().getGenfilesDirectory();
}
+ /**
+ * Creates an artifact in a directory that is unique to the package that contains the rule,
+ * thus guaranteeing that it never clashes with artifacts created by rules in other packages.
+ */
+ public Artifact getPackageRelativeArtifact(String relative, Root root) {
+ return getPackageRelativeArtifact(new PathFragment(relative), root);
+ }
+
+ /**
+ * Creates an artifact in a directory that is unique to the package that contains the rule,
+ * thus guaranteeing that it never clashes with artifacts created by rules in other packages.
+ */
+ public Artifact getPackageRelativeArtifact(PathFragment relative, Root root) {
+ return getDerivedArtifact(getPackageDirectory().getRelative(relative), root);
+ }
+
+ /**
+ * Returns the root-relative path fragment under which output artifacts of this rule should go.
+ *
+ * <p>Note that:
+ * <ul>
+ * <li>This doesn't guarantee that there are no clashes with rules in the same package.
+ * <li>If possible, {@link #getPackageRelativeArtifact(PathFragment, Root)} should be used
+ * instead of this method.
+ * </ul>
+ *
+ * Ideally, user-visible artifacts should all have corresponding output file targets, all others
+ * should go into a rule-specific directory.
+ * {@link #getUniqueDirectoryArtifact(String, PathFragment, Root)}) ensures that this is the case.
+ */
+ public PathFragment getPackageDirectory() {
+ return getLabel().getPackageIdentifier().getPathFragment();
+ }
+
+ /**
+ * Creates an artifact under a given root with the given root-relative path.
+ *
+ * <p>Verifies that it is in the root-relative directory corresponding to the package of the rule,
+ * thus ensuring that it doesn't clash with other artifacts generated by other rules using this
+ * method.
+ */
+ public Artifact getDerivedArtifact(PathFragment rootRelativePath, Root root) {
+ Preconditions.checkState(rootRelativePath.startsWith(getPackageDirectory()),
+ "Output artifact '%s' not under package directory '%s' for target '%s'",
+ rootRelativePath, getPackageDirectory(), getLabel());
+ return getAnalysisEnvironment().getDerivedArtifact(rootRelativePath, root);
+ }
+ /**
+ * Creates an artifact in a directory that is unique to the rule, thus guaranteeing that it never
+ * clashes with artifacts created by other rules.
+ */
+ public Artifact getUniqueDirectoryArtifact(
+ String uniqueDirectory, String relative, Root root) {
+ return getUniqueDirectoryArtifact(uniqueDirectory, new PathFragment(relative), root);
+ }
+
+ public Artifact getUniqueDirectoryArtifact(
+ String uniqueDirectory, PathFragment relative, Root root) {
+ return getDerivedArtifact(getUniqueDirectory(uniqueDirectory).getRelative(relative), root);
+ }
+
+ public PathFragment getArtifactPackagePrefix() {
+ return getLabel().getPackageIdentifier().getPathFragment();
+ }
+
private Attribute getAttribute(String attributeName) {
// TODO(bazel-team): We should check original rule for such attribute first, because aspect
// can't contain empty attribute. Consider changing type of prerequisiteMap from
@@ -982,9 +1051,7 @@ public final class RuleContext extends TargetContext
* Only use from Skylark. Returns the implicit output artifact for a given output path.
*/
public Artifact getImplicitOutputArtifact(String path) {
- Root root = getBinOrGenfilesDirectory();
- PathFragment packageFragment = getLabel().getPackageFragment();
- return getAnalysisEnvironment().getDerivedArtifact(packageFragment.getRelative(path), root);
+ return getPackageRelativeArtifact(path, getBinOrGenfilesDirectory());
}
/**
@@ -1061,7 +1128,7 @@ public final class RuleContext extends TargetContext
*/
public final Artifact getRelatedArtifact(PathFragment pathFragment, String extension) {
PathFragment file = FileSystemUtils.replaceExtension(pathFragment, extension);
- return getAnalysisEnvironment().getDerivedArtifact(file, getConfiguration().getBinDirectory());
+ return getDerivedArtifact(file, getConfiguration().getBinDirectory());
}
/**