aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java15
-rw-r--r--src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java49
2 files changed, 61 insertions, 3 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
index e6b3a513fb..523c9c758d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
@@ -557,13 +557,23 @@ public final class SkylarkRuleContext {
}
}
+ private boolean isForAspect() {
+ return ruleAttributesCollection != null;
+ }
+
@SkylarkCallable(
doc =
"Creates a file object with the given filename, in the current package. "
+ DOC_NEW_FILE_TAIL
)
public Artifact newFile(String filename) {
- return newFile(ruleContext.getBinOrGenfilesDirectory(), filename);
+ return newFile(newFileRoot(), filename);
+ }
+
+ private Root newFileRoot() {
+ return isForAspect()
+ ? getConfiguration().getBinDirectory()
+ : ruleContext.getBinOrGenfilesDirectory();
}
// Kept for compatibility with old code.
@@ -578,8 +588,7 @@ public final class SkylarkRuleContext {
public Artifact newFile(Artifact baseArtifact, String newBaseName) {
PathFragment original = baseArtifact.getRootRelativePath();
PathFragment fragment = original.replaceName(newBaseName);
- Root root = ruleContext.getBinOrGenfilesDirectory();
- return ruleContext.getDerivedArtifact(fragment, root);
+ return ruleContext.getDerivedArtifact(fragment, newFileRoot());
}
// Kept for compatibility with old code.
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
index e81fffb29b..b8489b90e3 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
@@ -15,6 +15,7 @@ package com.google.devtools.build.lib.skylark;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.fail;
import com.google.common.base.Function;
@@ -531,6 +532,54 @@ public class SkylarkAspectsTest extends AnalysisTestCase {
}
@Test
+ public void aspectOutputsToBinDirectory() throws Exception {
+ scratch.file("foo/extension.bzl",
+ "def _aspect_impl(target, ctx):",
+ " file = ctx.new_file('aspect-output-' + target.label.name)",
+ " ctx.file_action(file, 'data')",
+ " return struct(aspect_file = file)",
+ "my_aspect = aspect(_aspect_impl)",
+ "def _rule_impl(ctx):",
+ " pass",
+ "rule_bin_out = rule(_rule_impl, output_to_genfiles=False)",
+ "rule_gen_out = rule(_rule_impl, output_to_genfiles=True)",
+ "def _main_rule_impl(ctx):",
+ " s = set()",
+ " for d in ctx.attr.deps:",
+ " s = s | set([d.aspect_file])",
+ " return struct(aspect_files = s)",
+ "main_rule = rule(_main_rule_impl,",
+ " attrs = { 'deps' : attr.label_list(aspects = [my_aspect]) },",
+ ")"
+ );
+
+ scratch.file("foo/BUILD",
+ "load('extension', 'rule_bin_out', 'rule_gen_out', 'main_rule')",
+ "rule_bin_out(name = 'rbin')",
+ "rule_gen_out(name = 'rgen')",
+ "main_rule(name = 'main', deps = [':rbin', ':rgen'])"
+ );
+ AnalysisResult analysisResult = update(ImmutableList.<String>of(), "//foo:main");
+ ConfiguredTarget target = analysisResult.getTargetsToBuild().iterator().next();
+ NestedSet<Artifact> aspectFiles =
+ ((SkylarkNestedSet) target.getProvider(SkylarkProviders.class).getValue("aspect_files"))
+ .getSet(Artifact.class);
+ assertThat(transform(aspectFiles, new Function<Artifact, String>() {
+ @Override
+ public String apply(Artifact artifact) {
+ return artifact.getFilename();
+ }
+ })).containsExactly("aspect-output-rbin", "aspect-output-rgen");
+ for (Artifact aspectFile : aspectFiles) {
+ String rootPath = aspectFile.getRoot().getExecPath().toString();
+ assertWithMessage("Artifact %s should not be in genfiles", aspectFile)
+ .that(rootPath).doesNotContain("genfiles");
+ assertWithMessage("Artifact %s should be in bin", aspectFile)
+ .that(rootPath).endsWith("bin");
+ }
+ }
+
+ @Test
public void testAspectFragmentAccessSuccess() throws Exception {
getConfiguredTargetForAspectFragment(
"ctx.fragments.cpp.compiler", "'cpp'", "", "", "");