diff options
author | 2017-06-27 14:38:45 +0200 | |
---|---|---|
committer | 2017-06-27 15:06:32 +0200 | |
commit | 2e84e7ccba814253bf1402242c2ba6dab9293c6e (patch) | |
tree | 09594e73f3dcf1218194cdebba86f3114be7fd09 /src/main/java/com/google/devtools/build/lib/rules/SkylarkActionFactory.java | |
parent | c5ddd422180b85e44a39bb7f7b6119be6a44918b (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.java | 110 |
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; + } +} |