diff options
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java | 15 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java | 49 |
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'", "", "", ""); |