Skip to content

Commit 825369f

Browse files
fmeumbazel-io
authored andcommitted
Add execution_requirements to ctx.actions.write
Since Bazel's only `FileWriteStrategy` doesn't execute a spawn, this can currently only affect the path mapping behavior of the action when supplying `Args` as content. This will make it possible to opt C++ rules into path mapping without any command line flags beyond `--experimental_output_paths=strip` in future PRs. Work towards bazelbuild#27732 Work towards bazelbuild#27591 Closes bazelbuild#28335. PiperOrigin-RevId: 859069420 Change-Id: I73db26fb1f37303f49931ab19cd12575536607fb
1 parent 93f3809 commit 825369f

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkActionFactory.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,12 @@ public void symlink(
358358
}
359359

360360
@Override
361-
public void write(FileApi output, Object content, Boolean isExecutable, Object mnemonicUnchecked)
361+
public void write(
362+
FileApi output,
363+
Object content,
364+
Boolean isExecutable,
365+
Object mnemonicUnchecked,
366+
Object executionRequirementsUnchecked)
362367
throws EvalException, InterruptedException {
363368
context.checkMutable("actions.write");
364369
RuleContext ruleContext = getRuleContext();
@@ -371,6 +376,11 @@ public void write(FileApi output, Object content, Boolean isExecutable, Object m
371376
FileWriteAction.create(
372377
ruleContext, (Artifact) output, (String) content, isExecutable, mnemonic);
373378
} else if (content instanceof Args args) {
379+
var unmodifiedExecutionRequirements =
380+
TargetUtils.getFilteredExecutionInfo(
381+
executionRequirementsUnchecked,
382+
ruleContext.getRule(),
383+
getSemantics().getBool(BuildLanguageOptions.INCOMPATIBLE_ALLOW_TAGS_PROPAGATION));
374384
action =
375385
new ParameterFileWriteAction(
376386
ruleContext.getActionOwner(),
@@ -380,7 +390,9 @@ public void write(FileApi output, Object content, Boolean isExecutable, Object m
380390
args.getParameterFileType(),
381391
isExecutable,
382392
mnemonic,
383-
ruleContext.getConfiguration().modifiedExecutionInfo(ImmutableMap.of(), mnemonic),
393+
ruleContext
394+
.getConfiguration()
395+
.modifiedExecutionInfo(unmodifiedExecutionRequirements, mnemonic),
384396
PathMappers.getOutputPathsMode(ruleContext.getConfiguration()));
385397
} else {
386398
throw new AssertionError("Unexpected type: " + content.getClass().getSimpleName());

src/main/java/com/google/devtools/build/lib/starlarkbuildapi/StarlarkActionFactoryApi.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,26 @@ void symlink(
373373
named = true,
374374
positional = false,
375375
doc = "A one-word description of the action, for example, CppCompile or GoLink."),
376+
@Param(
377+
name = "execution_requirements",
378+
allowedTypes = {
379+
@ParamType(type = Dict.class),
380+
@ParamType(type = NoneType.class),
381+
},
382+
defaultValue = "None",
383+
named = true,
384+
positional = false,
385+
doc =
386+
"Information for scheduling the action. See "
387+
+ "<a href=\"${link common-definitions#common.tags}\">tags</a> "
388+
+ "for useful keys."),
376389
})
377-
void write(FileApi output, Object content, Boolean isExecutable, Object mnemonicUnchecked)
390+
void write(
391+
FileApi output,
392+
Object content,
393+
Boolean isExecutable,
394+
Object mnemonicUnchecked,
395+
Object executionRequirementsUnchecked)
378396
throws EvalException, InterruptedException;
379397

380398
@StarlarkMethod(

src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleContextTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.google.common.collect.ImmutableMap;
3131
import com.google.common.collect.ImmutableSet;
3232
import com.google.common.collect.Iterables;
33+
import com.google.devtools.build.lib.actions.Action;
3334
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
3435
import com.google.devtools.build.lib.actions.Artifact;
3536
import com.google.devtools.build.lib.actions.CommandLine;
@@ -3129,6 +3130,33 @@ public void testFileWriteActionInterfaceWithArgsAndCustomMnemonic() throws Excep
31293130
assertThat(contentUnchecked).isEqualTo("foo123\n");
31303131
}
31313132

3133+
@Test
3134+
public void testFileWriteActionInterfaceWithArgsAndSupportsPathMapping() throws Exception {
3135+
useConfiguration("--experimental_output_paths=strip");
3136+
scratch.file(
3137+
"test/rules.bzl",
3138+
getSimpleUnderTestDefinition(
3139+
"args = ctx.actions.args()",
3140+
"args.add('foo123')",
3141+
"ctx.actions.write(output=out, content=args,"
3142+
+ " execution_requirements={'supports-path-mapping': ''})"),
3143+
testingRuleDefinition);
3144+
scratch.file("test/BUILD", simpleBuildDefinition);
3145+
StarlarkRuleContext ruleContext = createRuleContext("//test:testing");
3146+
setRuleContext(ruleContext);
3147+
ev.update("file", ev.eval("ruleContext.attr.dep[DefaultInfo].files.to_list()[0]"));
3148+
var action = (Action) ev.eval("ruleContext.attr.dep[Actions].by_file[file]");
3149+
ev.update("action", action);
3150+
3151+
assertThat(ev.eval("type(action)")).isEqualTo("Action");
3152+
assertThat(action.getExecutionInfo()).containsEntry("supports-path-mapping", "");
3153+
3154+
Object contentUnchecked = ev.eval("action.content");
3155+
assertThat(contentUnchecked).isInstanceOf(String.class);
3156+
// Args content ends the file with a newline
3157+
assertThat(contentUnchecked).isEqualTo("foo123\n");
3158+
}
3159+
31323160
@Test
31333161
public void testFileWriteActionInterfaceWithArgsContainingTreeArtifact() throws Exception {
31343162
scratch.file(

0 commit comments

Comments
 (0)