Add expand_template rule (#330)
Resolves: https://github.com/bazelbuild/bazel-skylib/issues/191
An example of how this can be useful can be found here: https://github.com/catchorg/Catch2/pull/2387/files
Could be also helpful here: https://github.com/AcademySoftwareFoundation/openexr/blob/8587f4eed1d396a9c545d59e7b231d9d4b2cd8ef/BUILD.bazel#L21
diff --git a/README.md b/README.md
index 58e0878..3c4ec2b 100644
--- a/README.md
+++ b/README.md
@@ -60,6 +60,7 @@
* [analysis_test](docs/analysis_test_doc.md)
* [build_test](docs/build_test_doc.md)
* [copy_file](docs/copy_file_doc.md)
+* [expand_template](docs/expand_template_doc.md)
* [write_file](docs/write_file_doc.md)
## Writing a new module
diff --git a/docs/BUILD b/docs/BUILD
index 873e26c..284db3c 100644
--- a/docs/BUILD
+++ b/docs/BUILD
@@ -38,6 +38,11 @@
)
stardoc_with_diff_test(
+ bzl_library_target = "//rules:expand_template",
+ out_label = "//docs:expand_template_doc.md",
+)
+
+stardoc_with_diff_test(
bzl_library_target = "//rules:native_binary",
out_label = "//docs:native_binary_doc.md",
)
diff --git a/docs/expand_template_doc.md b/docs/expand_template_doc.md
new file mode 100755
index 0000000..b086829
--- /dev/null
+++ b/docs/expand_template_doc.md
@@ -0,0 +1,33 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+A rule that performes template expansion.
+
+
+<a id="#expand_template"></a>
+
+## expand_template
+
+<pre>
+expand_template(<a href="#expand_template-name">name</a>, <a href="#expand_template-template">template</a>, <a href="#expand_template-substitutions">substitutions</a>, <a href="#expand_template-out">out</a>)
+</pre>
+
+Template expansion
+
+This performs a simple search over the template file for the keys in substitutions,
+and replaces them with the corresponding values.
+
+There is no special syntax for the keys.
+To avoid conflicts, you would need to explicitly add delimiters to the key strings, for example "{KEY}" or "@KEY@".
+
+
+**PARAMETERS**
+
+
+| Name | Description | Default Value |
+| :------------- | :------------- | :------------- |
+| <a id="expand_template-name"></a>name | The name of the rule. | none |
+| <a id="expand_template-template"></a>template | The template file to expand | none |
+| <a id="expand_template-substitutions"></a>substitutions | A dictionary mapping strings to their substitutions | none |
+| <a id="expand_template-out"></a>out | The destination of the expanded file | none |
+
+
diff --git a/rules/BUILD b/rules/BUILD
index f7017bb..b89495e 100644
--- a/rules/BUILD
+++ b/rules/BUILD
@@ -33,6 +33,11 @@
)
bzl_library(
+ name = "expand_template",
+ srcs = ["expand_template.bzl"],
+)
+
+bzl_library(
name = "native_binary",
srcs = ["native_binary.bzl"],
deps = ["//rules/private:copy_file_private"],
diff --git a/rules/expand_template.bzl b/rules/expand_template.bzl
new file mode 100644
index 0000000..58f1920
--- /dev/null
+++ b/rules/expand_template.bzl
@@ -0,0 +1,55 @@
+# Copyright 2022 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.
+
+"""A rule that performes template expansion.
+"""
+
+def _expand_template_impl(ctx):
+ ctx.actions.expand_template(
+ template = ctx.file.template,
+ output = ctx.outputs.out,
+ substitutions = ctx.attr.substitutions,
+ )
+
+_expand_template = rule(
+ implementation = _expand_template_impl,
+ attrs = {
+ "template": attr.label(mandatory = True, allow_single_file = True),
+ "substitutions": attr.string_dict(mandatory = True),
+ "out": attr.output(mandatory = True),
+ },
+ output_to_genfiles = True,
+)
+
+def expand_template(name, template, substitutions, out):
+ """Template expansion
+
+ This performs a simple search over the template file for the keys in substitutions,
+ and replaces them with the corresponding values.
+
+ There is no special syntax for the keys.
+ To avoid conflicts, you would need to explicitly add delimiters to the key strings, for example "{KEY}" or "@KEY@".
+
+ Args:
+ name: The name of the rule.
+ template: The template file to expand
+ out: The destination of the expanded file
+ substitutions: A dictionary mapping strings to their substitutions
+ """
+ _expand_template(
+ name = name,
+ template = template,
+ substitutions = substitutions,
+ out = out,
+ )
diff --git a/tests/expand_template/BUILD b/tests/expand_template/BUILD
new file mode 100644
index 0000000..0607111
--- /dev/null
+++ b/tests/expand_template/BUILD
@@ -0,0 +1,57 @@
+# Copyright 2022 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.
+
+# This package aids testing the 'diff_test' rule.
+
+load("//rules:expand_template.bzl", "expand_template")
+
+expand_template(
+ name = "filled_template",
+ out = "foo/test.yaml",
+ substitutions = {
+ "@name@": "test",
+ "@version@": "1.1.1",
+ },
+ template = "test.tpl.yaml",
+)
+
+sh_test(
+ name = "template_test",
+ srcs = ["template_test.sh"],
+ data = [
+ "foo/test.yaml",
+ ":filled_template",
+ "//tests:unittest.bash",
+ ],
+ deps = [
+ "@bazel_tools//tools/bash/runfiles",
+ ],
+)
+
+expand_template(
+ name = "version",
+ out = "version.h",
+ substitutions = {
+ "@VERSION@": "2.3.4",
+ },
+ template = "version.h.in",
+)
+
+cc_test(
+ name = "test",
+ srcs = [
+ "test.cc",
+ ":version",
+ ],
+)
diff --git a/tests/expand_template/template_test.sh b/tests/expand_template/template_test.sh
new file mode 100755
index 0000000..dcddf2c
--- /dev/null
+++ b/tests/expand_template/template_test.sh
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+
+# Copyright 2022 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.
+
+# --- begin runfiles.bash initialization v2 ---
+# Copy-pasted from the Bazel Bash runfiles library v2.
+set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
+source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
+ source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
+ source "$0.runfiles/$f" 2>/dev/null || \
+ source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
+ source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
+ { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
+# --- end runfiles.bash initialization v2 ---
+
+source "$(rlocation bazel_skylib/tests/unittest.bash)" \
+ || { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }
+
+function test_expand_template() {
+ cat "$(rlocation bazel_skylib/tests/expand_template/foo/test.yaml)" >"$TEST_log"
+ expect_log 'name: test'
+ expect_log 'version: 1.1.1'
+}
+
+run_suite "expand_template_tests test suite"
\ No newline at end of file
diff --git a/tests/expand_template/test.cc b/tests/expand_template/test.cc
new file mode 100644
index 0000000..3b13e7a
--- /dev/null
+++ b/tests/expand_template/test.cc
@@ -0,0 +1,27 @@
+// Copyright 2022 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.
+
+#include "tests/expand_template/version.h"
+
+#include <cstring>
+
+int main(int argc, char **argv) {
+ // VERSION should be "2.3.4"
+ if(strcmp(VERSION, "2.3.4") == 0) {
+ return 0; // success
+ }
+ else {
+ return 1; // failure
+ }
+}
diff --git a/tests/expand_template/test.tpl.yaml b/tests/expand_template/test.tpl.yaml
new file mode 100644
index 0000000..03d9fdd
--- /dev/null
+++ b/tests/expand_template/test.tpl.yaml
@@ -0,0 +1,2 @@
+name: @name@
+version: @version@
diff --git a/tests/expand_template/version.h.in b/tests/expand_template/version.h.in
new file mode 100644
index 0000000..deb8418
--- /dev/null
+++ b/tests/expand_template/version.h.in
@@ -0,0 +1 @@
+#define VERSION "@VERSION@"
\ No newline at end of file