aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java
diff options
context:
space:
mode:
authorGravatar dslomov <dslomov@google.com>2017-06-27 14:38:45 +0200
committerGravatar Marcel Hlopko <hlopko@google.com>2017-06-27 15:06:32 +0200
commit2e84e7ccba814253bf1402242c2ba6dab9293c6e (patch)
tree09594e73f3dcf1218194cdebba86f3114be7fd09 /src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java
parentc5ddd422180b85e44a39bb7f7b6119be6a44918b (diff)
Add 'ctx.actions' and implement 'ctx.action.declare_file'.
RELNOTES: None. PiperOrigin-RevId: 160264501
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java110
1 files changed, 110 insertions, 0 deletions
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
new file mode 100644
index 0000000000..6157392a68
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java
@@ -0,0 +1,110 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.rules;
+
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.skylarkinterface.Param;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.Printer;
+import com.google.devtools.build.lib.syntax.Runtime;
+import com.google.devtools.build.lib.vfs.PathFragment;
+
+/**
+ * Provides a Skylark interface for all action creation needs.
+ */
+@SkylarkModule(
+ name = "actions",
+ category = SkylarkModuleCategory.BUILTIN,
+ doc = "Module providing functions to create actions."
+)
+
+public class SkylarkActionFactory implements SkylarkValue {
+ private final SkylarkRuleContext context;
+ private RuleContext ruleContext;
+
+
+ public SkylarkActionFactory(SkylarkRuleContext context, RuleContext ruleContext) {
+ this.context = context;
+ this.ruleContext = ruleContext;
+ }
+
+ Root newFileRoot() throws EvalException {
+ return context.isForAspect()
+ ? ruleContext.getConfiguration().getBinDirectory(ruleContext.getRule().getRepository())
+ : ruleContext.getBinOrGenfilesDirectory();
+ }
+
+
+ @SkylarkCallable(
+ name = "declare_file",
+ doc =
+ "Declares that rule or aspect creates a file with the given filename. "
+ + "If <code>sibling</code> is not specified, file name is relative to "
+ + "package directory, otherwise the file is in the same directory as "
+ + "<code>sibling</code>. "
+ + "You must create an action that generates the file. <br>"
+ + "Files that are specified in rule's outputs do not need to be declared and are "
+ + "available through <a href=\"ctx.html#outputs\">ctx.outputs</a>.",
+ parameters = {
+ @Param(
+ name = "filename",
+ type = String.class,
+ doc =
+ "If no 'sibling' provided, path of the new file, relative "
+ + "to the current package. Otherwise a base name for a file "
+ + "('sibling' determines a directory)."
+ ),
+ @Param(
+ name = "sibling",
+ doc = "A file that lives in the same directory as the newly created file.",
+ type = Artifact.class,
+ noneable = true,
+ positional = false,
+ named = true,
+ defaultValue = "None"
+ )
+ }
+ )
+ public Artifact declareFile(String filename, Object sibling) throws EvalException {
+ context.checkMutable("actions.declareFile");
+ if (Runtime.NONE.equals(sibling)) {
+ return ruleContext.getPackageRelativeArtifact(filename, newFileRoot());
+ } else {
+ PathFragment original = ((Artifact) sibling).getRootRelativePath();
+ PathFragment fragment = original.replaceName(filename);
+ return ruleContext.getDerivedArtifact(fragment, newFileRoot());
+ }
+ }
+
+ @Override
+ public boolean isImmutable() {
+ return context.isImmutable();
+ }
+
+ @Override
+ public void write(Appendable buffer, char quotationMark) {
+ Printer.append(buffer, "actions for");
+ context.write(buffer, quotationMark);
+ }
+
+ void nullify() {
+ ruleContext = null;
+ }
+}