Introduce ctx.actions.write in place of ctx.file_action.
RELNOTES: None.
PiperOrigin-RevId: 160630261
diff --git a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
index ad2148a..574fa6a 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
@@ -578,7 +578,7 @@
@SkylarkCallable(
name = "content",
- doc = "For actions created by <a href=\"ctx.html#file_action\">ctx.file_action()</a> or "
+ doc = "For actions created by <a href=\"actions.html#write\">ctx.actions.write()</a> or "
+ "<a href=\"ctx.html#template_action\">ctx.template_action()</a>, the contents of the "
+ "file to be written.",
structField = true,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java
index 2bd1b4e..985c5f8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java
@@ -20,6 +20,7 @@
import com.google.devtools.build.lib.actions.extra.SpawnInfo;
import com.google.devtools.build.lib.analysis.PseudoAction;
import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.skylarkinterface.Param;
@@ -192,6 +193,38 @@
}
+ @SkylarkCallable(
+ name = "write",
+ doc = "Creates a file write action.",
+ parameters = {
+ @Param(
+ name = "output",
+ type = Artifact.class,
+ doc = "the output file.",
+ named = true
+ ),
+ @Param(
+ name = "content",
+ type = String.class,
+ doc = "the contents of the file.",
+ named = true
+ ),
+ @Param(
+ name = "is_executable",
+ type = Boolean.class,
+ defaultValue = "False",
+ doc = "whether the output file should be executable (default is False).",
+ named = true
+ )
+ }
+ )
+ public void write(Artifact output, String content, Boolean isExecutable)
+ throws EvalException {
+ context.checkMutable("actions.write");
+ FileWriteAction action =
+ FileWriteAction.create(ruleContext, output, content, isExecutable);
+ ruleContext.registerAction(action);
+ }
@Override
public boolean isImmutable() {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
index 9488165..6603d91 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
@@ -26,7 +26,6 @@
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
-import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
@@ -403,10 +402,10 @@
return builder.build();
}
- // TODO(bazel-team): improve this method to be more memory friendly
@SkylarkSignature(
name = "file_action",
- doc = "Creates a file write action.",
+ doc = "DEPRECATED. Use <a href =\"actions.html#write\">ctx.actions.write</a> instead. <br>"
+ + "Creates a file write action.",
objectType = SkylarkRuleContext.class,
returnType = Runtime.NoneType.class,
parameters = {
@@ -425,11 +424,9 @@
new BuiltinFunction("file_action") {
public Runtime.NoneType invoke(
SkylarkRuleContext ctx, Artifact output, String content, Boolean executable)
- throws EvalException, ConversionException {
+ throws EvalException {
ctx.checkMutable("file_action");
- FileWriteAction action =
- FileWriteAction.create(ctx.getRuleContext(), output, content, executable);
- ctx.getRuleContext().registerAction(action);
+ ctx.actions().write(output, content, executable);
return Runtime.NONE;
}
};
diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java
index 3ed9a39..b433443 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java
@@ -2796,7 +2796,7 @@
scratch.file(
"java/com/foo/reader.bzl",
"def _impl(ctx):",
- " ctx.file_action(",
+ " ctx.actions.write(",
" ctx.outputs.java,",
" '\\n'.join([",
" str(target.label) + ': ' + target[config_common.FeatureFlagInfo].value",
diff --git a/src/test/java/com/google/devtools/build/lib/rules/test/SkylarkTestingModuleTest.java b/src/test/java/com/google/devtools/build/lib/rules/test/SkylarkTestingModuleTest.java
index 4cde8ce..7aecef0 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/test/SkylarkTestingModuleTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/test/SkylarkTestingModuleTest.java
@@ -86,7 +86,7 @@
"examples/rule/apple_rules.bzl",
"def my_rule_test_impl(ctx):",
" exec_info = testing.ExecutionInfo({'local': ''})",
- " ctx.file_action(ctx.outputs.executable, '', True)",
+ " ctx.actions.write(ctx.outputs.executable, '', True)",
" return [exec_info]",
"my_rule_test = rule(implementation = my_rule_test_impl,",
" test = True,",
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 4b3740b..6b86b88 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
@@ -918,7 +918,7 @@
"MyAspect = aspect(implementation=_impl)",
"def _rule_impl(ctx):",
" g = ctx.actions.declare_file('g.txt')",
- " ctx.file_action(g, 'g')",
+ " ctx.actions.write(g, 'g')",
" return struct(output_groups = { 'duplicate' : depset([g]) })",
"my_rule = rule(_rule_impl)",
"def _noop(ctx):",
@@ -948,7 +948,7 @@
"test/aspect.bzl",
"def _a1_impl(target, ctx):",
" f = ctx.actions.declare_file(target.label.name + '_a1.txt')",
- " ctx.file_action(f, 'f')",
+ " ctx.actions.write(f, 'f')",
" return struct(output_groups = { 'a1_group' : depset([f]) })",
"",
"a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])",
@@ -980,7 +980,7 @@
"test/aspect.bzl",
"def _a1_impl(target, ctx):",
" f = ctx.actions.declare_file(target.label.name + '_a1.txt')",
- " ctx.file_action(f, 'f')",
+ " ctx.actions.write(f, 'f')",
" return [OutputGroupInfo(a1_group = depset([f]))]",
"",
"a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])",
@@ -1011,7 +1011,7 @@
"test/aspect.bzl",
"def _a1_impl(target, ctx):",
" f = ctx.actions.declare_file(target.label.name + '_a1.txt')",
- " ctx.file_action(f, 'f')",
+ " ctx.actions.write(f, 'f')",
" return struct(output_groups = { 'a1_group' : depset([f]) })",
"",
"a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])",
@@ -1023,7 +1023,7 @@
"my_rule1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1]) })",
"def _a2_impl(target, ctx):",
" g = ctx.actions.declare_file(target.label.name + '_a2.txt')",
- " ctx.file_action(g, 'f')",
+ " ctx.actions.write(g, 'f')",
" return struct(output_groups = { 'a2_group' : depset([g]) })",
"",
"a2 = aspect(implementation=_a2_impl, attr_aspects = ['dep'])",
@@ -1052,7 +1052,7 @@
"test/aspect.bzl",
"def _a1_impl(target, ctx):",
" f = ctx.actions.declare_file(target.label.name + '_a1.txt')",
- " ctx.file_action(f, 'f')",
+ " ctx.actions.write(f, 'f')",
" return [OutputGroupInfo(a1_group = depset([f]))]",
"",
"a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])",
@@ -1069,7 +1069,7 @@
"my_rule1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1]) })",
"def _a2_impl(target, ctx):",
" g = ctx.actions.declare_file(target.label.name + '_a2.txt')",
- " ctx.file_action(g, 'f')",
+ " ctx.actions.write(g, 'f')",
" return [OutputGroupInfo(a2_group = depset([g]))]",
"",
"a2 = aspect(implementation=_a2_impl, attr_aspects = ['dep'])",
@@ -1099,7 +1099,7 @@
"test/aspect.bzl",
"def _a1_impl(target, ctx):",
" f = ctx.actions.declare_file(target.label.name + '_a1.txt')",
- " ctx.file_action(f, 'f')",
+ " ctx.actions.write(f, 'f')",
" return struct(output_groups = { 'a1_group' : depset([f]) })",
"",
"a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])",
@@ -1111,7 +1111,7 @@
"my_rule1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1]) })",
"def _a2_impl(target, ctx):",
" g = ctx.actions.declare_file(target.label.name + '_a2.txt')",
- " ctx.file_action(g, 'f')",
+ " ctx.actions.write(g, 'f')",
" return struct(output_groups = { 'a1_group' : depset([g]) })",
"",
"a2 = aspect(implementation=_a2_impl, attr_aspects = ['dep'])",
@@ -1648,7 +1648,7 @@
"foo/extension.bzl",
"def _aspect_impl(target, ctx):",
" file = ctx.actions.declare_file('aspect-output-' + target.label.name)",
- " ctx.file_action(file, 'data')",
+ " ctx.actions.write(file, 'data')",
" return struct(aspect_file = file)",
"my_aspect = aspect(_aspect_impl)",
"def _rule_impl(ctx):",
@@ -1919,7 +1919,7 @@
"def _a3_impl(target,ctx):",
" value = []",
" f = ctx.actions.declare_file('a3.out')",
- " ctx.file_action(f, 'text')",
+ " ctx.actions.write(f, 'text')",
" for dep in ctx.rule.attr.deps:",
" if hasattr(dep, 'a3p'):",
" value += dep.a3p",
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
index eeb3900..14842fc 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
@@ -527,7 +527,7 @@
scratch.file(
"test/skylark/extension.bzl",
"def custom_rule_impl(ctx):",
- " ctx.file_action(output = ctx.outputs.executable, content = 'echo hello')",
+ " ctx.actions.write(output = ctx.outputs.executable, content = 'echo hello')",
" rf = ctx.runfiles(ctx.files.data)",
" return struct(runfiles = rf)",
"",
@@ -967,7 +967,7 @@
" command = 'echo')",
" ftb = depset(files)",
" for i in ctx.outputs.out:",
- " ctx.file_action(output=i, content='hi there')",
+ " ctx.actions.write(output=i, content='hi there')",
"",
"def output_func(attr1):",
" return {'o': attr1 + '.txt'}",
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
index 202bc66..f93a7e3 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
@@ -1561,7 +1561,7 @@
"def _undertest_impl(ctx):",
" out1 = ctx.outputs.out1",
" out2 = ctx.outputs.out2",
- " ctx.file_action(output=out1, content='foo123')",
+ " ctx.actions.write(output=out1, content='foo123')",
" ctx.action(outputs=[out2], inputs=[out1], command='cp ' + out1.path + ' ' + out2.path)",
" return struct(out1=out1, out2=out2)",
"undertest_rule = rule(",
@@ -1681,7 +1681,7 @@
public void testFileWriteActionInterface() throws Exception {
scratch.file("test/rules.bzl",
getSimpleUnderTestDefinition(
- "ctx.file_action(output=out, content='foo123')"),
+ "ctx.actions.write(output=out, content='foo123')"),
testingRuleDefinition);
scratch.file("test/BUILD",
simpleBuildDefinition);
@@ -1862,6 +1862,7 @@
"actions.declare_directory('foo.txt')",
"actions.declare_directory('foo.txt', sibling = file)",
"actions.do_nothing(mnemonic = 'foo', inputs = [file])",
+ "actions.write(file, 'foo')",
"check_placeholders('foo', [])",
"action(command = 'foo', outputs = [file])",
"file_action(file, 'foo')",
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
index 9677078..d908085 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
@@ -409,10 +409,10 @@
SkylarkRuleContext ruleContext = createRuleContext("//foo:foo");
evalRuleContextCode(
ruleContext,
- "ruleContext.file_action(",
+ "ruleContext.actions.write(",
" output = ruleContext.files.srcs[0],",
" content = 'hello world',",
- " executable = False)");
+ " is_executable = False)");
FileWriteAction action =
(FileWriteAction)
Iterables.getOnlyElement(
@@ -621,12 +621,12 @@
SkylarkRuleContext ruleContext = createRuleContext("//foo:foo");
checkErrorContains(
ruleContext,
- "method ctx.file_action(output: File, content: string, executable: bool) is not applicable "
- + "for arguments (File, int, bool): 'content' is 'int', but should be 'string'",
- "ruleContext.file_action(",
+ "Cannot convert parameter 'content' to type string, in method "
+ + "write(File output, int content, bool is_executable) of 'actions'",
+ "ruleContext.actions.write(",
" output = ruleContext.files.srcs[0],",
" content = 1,",
- " executable = False)");
+ " is_executable = False)");
}
@Test
@@ -1533,7 +1533,7 @@
" outs = ctx.outputs",
" for i in ctx.attr.srcs:",
" o = getattr(outs, 'foo_' + i.label.name)",
- " ctx.file_action(",
+ " ctx.actions.write(",
" output = o,",
" content = 'hoho')",
"",
diff --git a/src/test/shell/integration/bazel_worker_test.sh b/src/test/shell/integration/bazel_worker_test.sh
index 561336f..bde845e 100755
--- a/src/test/shell/integration/bazel_worker_test.sh
+++ b/src/test/shell/integration/bazel_worker_test.sh
@@ -110,6 +110,7 @@
for arg in ["--output_file=" + output.path] + ctx.attr.args:
argfile = ctx.new_file(ctx.bin_dir, "%s_worker_input_%s" % (ctx.label.name, idx))
ctx.file_action(output=argfile, content=arg)
+ ctx.actions.write(output=argfile, content=arg)
argfile_inputs.append(argfile)
flagfile_prefix = "@" if (idx % 2 == 0) else "--flagfile="
argfile_arguments.append(flagfile_prefix + argfile.path)
@@ -118,7 +119,7 @@
# Generate the "@"-file containing the command-line args for the unit of work.
argfile = ctx.new_file(ctx.bin_dir, "%s_worker_input" % ctx.label.name)
argfile_contents = "\n".join(["--output_file=" + output.path] + ctx.attr.args)
- ctx.file_action(output=argfile, content=argfile_contents)
+ ctx.actions.write(output=argfile, content=argfile_contents)
argfile_inputs.append(argfile)
argfile_arguments.append("@" + argfile.path)
diff --git a/src/test/shell/integration/build_event_stream_test.sh b/src/test/shell/integration/build_event_stream_test.sh
index ffe1b4c..8dbea70 100755
--- a/src/test/shell/integration/build_event_stream_test.sh
+++ b/src/test/shell/integration/build_event_stream_test.sh
@@ -99,7 +99,7 @@
def _simple_aspect_impl(target, ctx):
for orig_out in ctx.rule.attr.outs:
aspect_out = ctx.actions.declare_file(orig_out.name + ".aspect")
- ctx.file_action(
+ ctx.actions.write(
output=aspect_out,
content = "Hello from aspect")
return struct(output_groups={
diff --git a/src/test/shell/integration/discard_analysis_cache_test.sh b/src/test/shell/integration/discard_analysis_cache_test.sh
index eda5823..90386f1 100755
--- a/src/test/shell/integration/discard_analysis_cache_test.sh
+++ b/src/test/shell/integration/discard_analysis_cache_test.sh
@@ -71,7 +71,7 @@
result=depset()
for orig_out in target.files:
aspect_out = ctx.actions.declare_file(orig_out.basename + ".aspect")
- ctx.file_action(
+ ctx.actions.write(
output=aspect_out,
content = "Hello from aspect for %s" % orig_out.basename)
result += [aspect_out]
diff --git a/src/test/shell/integration/discard_graph_edges_test.sh b/src/test/shell/integration/discard_graph_edges_test.sh
index 2e05b01..2a6eb68 100755
--- a/src/test/shell/integration/discard_graph_edges_test.sh
+++ b/src/test/shell/integration/discard_graph_edges_test.sh
@@ -70,7 +70,7 @@
result=depset()
for orig_out in target.files:
aspect_out = ctx.actions.declare_file(orig_out.basename + ".aspect")
- ctx.file_action(
+ ctx.actions.write(
output=aspect_out,
content = "Hello from aspect for %s" % orig_out.basename)
result += [aspect_out]