diff options
author | 2017-07-03 09:43:58 -0400 | |
---|---|---|
committer | 2017-07-05 10:56:44 -0400 | |
commit | 68aafa23dc44dc54823477e2155b746a821c9c2b (patch) | |
tree | 34f3ac44e9bff2a03ae0228a57c9bf7900a81d8a /src/main/java/com/google/devtools/build/lib | |
parent | 8b1281b180f637d4f35673f5cf9aa915b389d026 (diff) |
Implement ctx.actions.expand_template.
It also changes the return value of ctx.template_action to None, so a
very minor breaking change. There are no internal usages at least.
RELNOTES: None.
PiperOrigin-RevId: 160825636
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
3 files changed, 91 insertions, 41 deletions
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 4474a76cd3..26a68a5c7e 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 @@ -580,8 +580,8 @@ public abstract class AbstractAction implements Action, SkylarkValue { @SkylarkCallable( name = "content", 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.", + + "<a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a>," + + " the contents of the file to be written.", structField = true, allowReturnNones = true) public String getSkylarkContent() throws IOException { @@ -590,8 +590,9 @@ public abstract class AbstractAction implements Action, SkylarkValue { @SkylarkCallable( name = "substitutions", - doc = "For actions created by <a href=\"ctx.html#template_action\">" - + "ctx.template_action()</a>, an immutable dict holding the substitution mapping.", + doc = "For actions created by " + + "<a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a>," + + " an immutable dict holding the substitution mapping.", structField = true, allowReturnNones = true) public SkylarkDict<String, String> getSkylarkSubstitutions() { 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 2fad61119a..20f1fb18c4 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 @@ -25,6 +25,8 @@ 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.analysis.actions.SpawnAction; +import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction; +import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution; 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; @@ -43,6 +45,7 @@ import com.google.devtools.build.lib.syntax.SkylarkNestedSet; import com.google.devtools.build.lib.vfs.PathFragment; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.Map; import java.util.UUID; /** @@ -623,6 +626,82 @@ public class SkylarkActionFactory implements SkylarkValue { ruleContext.registerAction(builder.build(ruleContext)); } + @SkylarkCallable( + name = "expand_template", + doc = "Creates a template expansion action.", + parameters = { + @Param( + name = "template", + type = Artifact.class, + named = true, + positional = false, + doc = "the template file, which is a UTF-8 encoded text file." + ), + @Param( + name = "output", + type = Artifact.class, + named = true, + positional = false, + doc = "the output file, which is a UTF-8 encoded text file." + ), + @Param( + name = "substitutions", + type = SkylarkDict.class, + named = true, + positional = false, + doc = "substitutions to make when expanding the template." + ), + @Param( + name = "executable", + type = Boolean.class, + defaultValue = "False", + named = true, + positional = false, + doc = "whether the output file should be executable (default is False)." + ) + } + ) + public void expandTemplate( + Artifact template, + Artifact output, + SkylarkDict<?, ?> substitutionsUnchecked, + Boolean executable) + throws EvalException { + context.checkMutable("actions.expand_template"); + ImmutableList.Builder<Substitution> substitutionsBuilder = ImmutableList.builder(); + for (Map.Entry<String, String> substitution : + substitutionsUnchecked + .getContents(String.class, String.class, "substitutions") + .entrySet()) { + // ParserInputSource.create(Path) uses Latin1 when reading BUILD files, which might + // contain UTF-8 encoded symbols as part of template substitution. + // As a quick fix, the substitution values are corrected before being passed on. + // In the long term, fixing ParserInputSource.create(Path) would be a better approach. + substitutionsBuilder.add( + Substitution.of( + substitution.getKey(), convertLatin1ToUtf8(substitution.getValue()))); + } + TemplateExpansionAction action = + new TemplateExpansionAction( + ruleContext.getActionOwner(), + template, + output, + substitutionsBuilder.build(), + executable); + ruleContext.registerAction(action); + } + + /** + * Returns the proper UTF-8 representation of a String that was erroneously read using Latin1. + * @param latin1 Input string + * @return The input string, UTF8 encoded + */ + private static String convertLatin1ToUtf8(String latin1) { + return new String(latin1.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); + } + + + @Override public boolean isImmutable() { return context.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 1be40eb9d4..5b316bc5ff 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 @@ -24,8 +24,6 @@ import com.google.devtools.build.lib.analysis.LocationExpander; 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.TemplateExpansionAction; -import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.skylarkinterface.Param; @@ -46,7 +44,6 @@ import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.syntax.Type.ConversionException; import com.google.devtools.build.lib.vfs.PathFragment; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -403,9 +400,11 @@ public class SkylarkRuleImplementationFunctions { @SkylarkSignature( name = "template_action", - doc = "Creates a template expansion action.", + doc = "DEPRECATED. " + + "Use <a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a> instead." + + "<br>Creates a template expansion action.", objectType = SkylarkRuleContext.class, - returnType = TemplateExpansionAction.class, + returnType = Runtime.NoneType.class, parameters = { @Param(name = "self", type = SkylarkRuleContext.class, doc = "this context."), @Param( @@ -441,7 +440,7 @@ public class SkylarkRuleImplementationFunctions { ) private static final BuiltinFunction createTemplateAction = new BuiltinFunction("template_action", Arrays.<Object>asList(false)) { - public TemplateExpansionAction invoke( + public Runtime.NoneType invoke( SkylarkRuleContext ctx, Artifact template, Artifact output, @@ -449,40 +448,11 @@ public class SkylarkRuleImplementationFunctions { Boolean executable) throws EvalException, ConversionException { ctx.checkMutable("template_action"); - ImmutableList.Builder<Substitution> substitutionsBuilder = ImmutableList.builder(); - for (Map.Entry<String, String> substitution : - substitutionsUnchecked - .getContents(String.class, String.class, "substitutions") - .entrySet()) { - // ParserInputSource.create(Path) uses Latin1 when reading BUILD files, which might - // contain UTF-8 encoded symbols as part of template substitution. - // As a quick fix, the substitution values are corrected before being passed on. - // In the long term, fixing ParserInputSource.create(Path) would be a better approach. - substitutionsBuilder.add( - Substitution.of( - substitution.getKey(), convertLatin1ToUtf8(substitution.getValue()))); - } - TemplateExpansionAction action = - new TemplateExpansionAction( - ctx.getRuleContext().getActionOwner(), - template, - output, - substitutionsBuilder.build(), - executable); - ctx.getRuleContext().registerAction(action); - return action; + ctx.actions().expandTemplate(template, output, substitutionsUnchecked, executable); + return Runtime.NONE; } }; - /** - * Returns the proper UTF-8 representation of a String that was erroneously read using Latin1. - * @param latin1 Input string - * @return The input string, UTF8 encoded - */ - private static String convertLatin1ToUtf8(String latin1) { - return new String(latin1.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); - } - // TODO(bazel-team): Remove runfile states from Skylark. @SkylarkSignature(name = "runfiles", doc = "Creates a runfiles object.", |