aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Damien Martin-Guillerez <dmarting@google.com>2016-02-24 13:01:39 +0000
committerGravatar Philipp Wollermann <philwo@google.com>2016-02-24 18:00:17 +0000
commit70691a0ea0a5d80dfdac083aa626e01115c9b365 (patch)
treea01cc5ea0d53fabdd3b9abc3070ca85111bd9f9e
parent287094bead6cfe1b2d1655c2bd1431fd8fe03e82 (diff)
Implements repository_ctx.template
repository_ctx.template enable writing a file in the remote repository tree using a template and a list of substitution in a similar way as the ctx.template_action for regular skylark rule. Issue #893: Step 4 of http://goo.gl/OZV3o0. See http://goo.gl/fD4ZsY. -- MOS_MIGRATED_REVID=115439344
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java30
-rw-r--r--src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryIntegrationTest.java26
2 files changed, 56 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
index 45138da572..e2500dab2b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
@@ -33,6 +33,8 @@ import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkType;
import com.google.devtools.build.lib.syntax.Type;
+import com.google.devtools.build.lib.util.StringUtilities;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.RootedPath;
@@ -201,6 +203,34 @@ public class SkylarkRepositoryContext {
}
}
+ @SkylarkCallable(
+ name = "template",
+ doc =
+ "Generate a new file using a <code>template</code>. Every occurrence in "
+ + "<code>template</code> of a key of <code>substitutions</code> will be replaced by "
+ + "the corresponding value. The result is written in <code>path</code>."
+ )
+ public void createFileFromTemplate(
+ Object path, Object template, Map<String, String> substitutions)
+ throws RepositoryFunctionException, EvalException {
+ SkylarkPath p = getPath("template()", path);
+ SkylarkPath t = getPath("template()", template);
+ try {
+ checkInOutputDirectory(p);
+ makeDirectories(p.path);
+ String tpl = FileSystemUtils.readContent(t.path, StandardCharsets.UTF_8);
+ for (Map.Entry<String, String> substitution : substitutions.entrySet()) {
+ tpl =
+ StringUtilities.replaceAllLiteral(tpl, substitution.getKey(), substitution.getValue());
+ }
+ try (OutputStream stream = p.path.getOutputStream()) {
+ stream.write(tpl.getBytes(StandardCharsets.UTF_8));
+ }
+ } catch (IOException e) {
+ throw new RepositoryFunctionException(e, Transience.TRANSIENT);
+ }
+ }
+
// Create parent directories for the given path
private void makeDirectories(Path path) throws IOException {
if (!path.isRootDirectory()) {
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryIntegrationTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryIntegrationTest.java
index aaca4d0edb..dcdc6e40f0 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryIntegrationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryIntegrationTest.java
@@ -195,4 +195,30 @@ public class SkylarkRepositoryIntegrationTest extends BuildViewTestCase {
Object path = target.getTarget().getAssociatedRule().getAttributeContainer().getAttr("path");
assertThat(path).isEqualTo("foo");
}
+
+ @Test
+ public void testSkylarkRepositoryTemplate() throws Exception {
+ scratch.file("/repo2/bar.txt", "filegroup(name='{target}', srcs=['foo.txt'], path='{path}')");
+ scratch.file("/repo2/BUILD");
+ scratch.file("/repo2/WORKSPACE");
+ scratch.file(
+ "def.bzl",
+ "def _impl(ctx):",
+ " ctx.template('BUILD', Label('@repo2//:bar.txt'), {'{target}': 'bar', '{path}': 'foo'})",
+ " ctx.file('foo.txt', 'foo')",
+ "",
+ "repo = repository_rule(",
+ " implementation=_impl,",
+ " local=True)");
+ scratch.file(rootDirectory.getRelative("BUILD").getPathString());
+ scratch.overwriteFile(
+ rootDirectory.getRelative("WORKSPACE").getPathString(),
+ "local_repository(name='repo2', path='/repo2')",
+ "load('//:def.bzl', 'repo')",
+ "repo(name='foo')");
+ invalidatePackages();
+ ConfiguredTarget target = getConfiguredTarget("@foo//:bar");
+ Object path = target.getTarget().getAssociatedRule().getAttributeContainer().getAttr("path");
+ assertThat(path).isEqualTo("foo");
+ }
}