diff --git a/.bazelversion b/.bazelversion index 5e8f65f..9c47c19 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1,4 +1,4 @@ -4.2.0 +5.0.0-pre.20211011.2 # The first line of this file is used by Bazelisk and Bazel to be sure # the right version of Bazel is used to build and test this repo. # This also defines which version is used on CI. diff --git a/BUILD.bazel b/BUILD.bazel index dc1cc22..4faf351 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -17,7 +17,6 @@ gazelle( pkg_tar( name = "bazel_lib-" + VERSION, srcs = [ - "LICENSE", "README.md", "version.bzl", "//lib:package_content", diff --git a/WORKSPACE b/WORKSPACE index 199482f..ef688a5 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -10,6 +10,11 @@ load(":internal_deps.bzl", "bazel_lib_internal_deps") # Fetch deps needed only locally for development bazel_lib_internal_deps() +# For running our own unit tests +load("@bazel_skylib//lib:unittest.bzl", "register_unittest_toolchains") + +register_unittest_toolchains() + ############################################ # Gazelle, for generating bzl_library targets load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") diff --git a/docs/expand_make_vars.md b/docs/expand_make_vars.md index de8fb22..658fb15 100644 --- a/docs/expand_make_vars.md +++ b/docs/expand_make_vars.md @@ -2,6 +2,33 @@ Public API for expanding variables + + +## expand_template + +
+expand_template(name, data, is_executable, out, substitutions, template)
+
+ +Template expansion + +This performs a simple search over the template file for the keys in substitutions, +and replaces them with the corresponding values. + + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| data | List of targets for additional lookup information. | List of labels | optional | [] | +| is_executable | Whether to mark the output file as executable. | Boolean | optional | False | +| out | Where to write the expanded file. | Label | required | | +| substitutions | Mapping of strings to substitutions. | Dictionary: String -> String | required | | +| template | The template file to expand. | Label | required | | + + ## expand_locations diff --git a/lib/expand_make_vars.bzl b/lib/expand_make_vars.bzl index 134749b..527a2c3 100644 --- a/lib/expand_make_vars.bzl +++ b/lib/expand_make_vars.bzl @@ -3,8 +3,10 @@ load( "//lib/private:expand_make_vars.bzl", _expand_locations = "expand_locations", + _expand_template = "expand_template", _expand_variables = "expand_variables", ) expand_locations = _expand_locations expand_variables = _expand_variables +expand_template = _expand_template diff --git a/lib/private/expand_make_vars.bzl b/lib/private/expand_make_vars.bzl index b1f6371..ab4c21e 100644 --- a/lib/private/expand_make_vars.bzl +++ b/lib/private/expand_make_vars.bzl @@ -162,3 +162,47 @@ def expand_variables(ctx, s, outs = [], output_dir = False, attribute_name = "ar additional_substitutions["RULEDIR"] = "/".join([o for o in rule_dir if o]) return ctx.expand_make_variables(attribute_name, s, additional_substitutions) + +def _expand_template_impl(ctx): + ctx.actions.expand_template( + template = ctx.file.template, + output = ctx.outputs.out, + substitutions = { + k: expand_locations(v, ctx.attr.data) + for k, v in ctx.attr.substitutions.items() + }, + is_executable = ctx.attr.is_executable, + ) + +expand_template = rule( + doc = """Template expansion + +This performs a simple search over the template file for the keys in substitutions, +and replaces them with the corresponding values. +""", + implementation = _expand_template_impl, + attrs = { + "template": attr.label( + doc = "The template file to expand.", + mandatory = True, + allow_single_file = True, + ), + "substitutions": attr.string_dict( + doc = "Mapping of strings to substitutions.", + mandatory = True, + ), + "out": attr.output( + doc = "Where to write the expanded file.", + mandatory = True, + ), + "is_executable": attr.bool( + doc = "Whether to mark the output file as executable.", + default = False, + mandatory = False, + ), + "data": attr.label_list( + doc = "List of targets for additional lookup information.", + allow_files = True, + ), + }, +) diff --git a/lib/private/params_file.bzl b/lib/private/params_file.bzl index 12c5a2a..db61435 100644 --- a/lib/private/params_file.bzl +++ b/lib/private/params_file.bzl @@ -2,9 +2,6 @@ load("//lib/private:expand_make_vars.bzl", "expand_locations") -_DOC = """Generates a params file from a list of arguments.""" - -# See params_file macro below for docstrings _ATTRS = { "args": attr.string_list(), "data": attr.label_list(allow_files = True), @@ -53,5 +50,4 @@ params_file = rule( implementation = _impl, provides = [DefaultInfo], attrs = _ATTRS, - doc = _DOC, ) diff --git a/lib/tests/BUILD.bazel b/lib/tests/BUILD.bazel new file mode 100644 index 0000000..580c74e --- /dev/null +++ b/lib/tests/BUILD.bazel @@ -0,0 +1,3 @@ +load(":expand_make_vars_test.bzl", "expand_make_vars_test_suite") + +expand_make_vars_test_suite(name = "expand_make_vars_test") diff --git a/lib/tests/expand_make_vars_test.bzl b/lib/tests/expand_make_vars_test.bzl new file mode 100644 index 0000000..e63c6f4 --- /dev/null +++ b/lib/tests/expand_make_vars_test.bzl @@ -0,0 +1,29 @@ +"""Unit tests for starlark helpers +See https://docs.bazel.build/versions/main/skylark/testing.html#for-testing-starlark-utilities +""" + +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("//lib/private:expand_make_vars.bzl", "expand_variables") + +def _variables_test_impl(ctx): + env = unittest.begin(ctx) + capture_subs = {} + fake_ctx = struct( + bin_dir = struct(path = "bazel-bin"), + label = struct( + workspace_root = "my-wksp", + package = "path/to", + ), + expand_make_variables = lambda attr, expr, subs: capture_subs.update(subs), + ) + expand_variables(fake_ctx, "output=$(@D)") + expected = {"@D": "bazel-bin/my-wksp/path/to", "RULEDIR": "bazel-bin/my-wksp/path/to"} + asserts.equals(env, expected, capture_subs) + return unittest.end(env) + +# The unittest library requires that we export the test cases as named test rules, +# but their names are arbitrary and don't appear anywhere. +t0_test = unittest.make(_variables_test_impl) + +def expand_make_vars_test_suite(name): + unittest.suite(name, t0_test)