diff --git a/README.md b/README.md index 58e0878..3c4ec2b 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ s = shell.quote(p) * [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 @@ -37,6 +37,11 @@ stardoc_with_diff_test( out_label = "//docs:diff_test_doc.md", ) +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 @@ + + +A rule that performes template expansion. + + + + +## expand_template + +
+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@". + + +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| name | The name of the rule. | none | +| template | The template file to expand | none | +| substitutions | A dictionary mapping strings to their substitutions | none | +| 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 @@ -32,6 +32,11 @@ bzl_library( srcs = ["diff_test.bzl"], ) +bzl_library( + name = "expand_template", + srcs = ["expand_template.bzl"], +) + bzl_library( name = "native_binary", srcs = ["native_binary.bzl"], 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