| def _jinja2_template_impl(ctx): |
| out = ctx.outputs.out |
| parameters = dict(ctx.attr.parameters) |
| parameters.update(ctx.attr.list_parameters) |
| |
| # For now we don't really want the user to worry about which configuration |
| # to pull the file from. We don't yet have a use case for pulling the same |
| # file from multiple configurations. We point Jinja at all the configuration |
| # roots. |
| include_dirs = depset([ |
| file.root.path or "." |
| for file in ctx.files.includes |
| ]).to_list() |
| |
| args = ctx.actions.args() |
| args.add(ctx.file.src) |
| args.add(json.encode(parameters)) |
| args.add(out) |
| args.add_all(include_dirs, before_each = "--include_dir") |
| if ctx.file.parameters_file: |
| args.add("--replacements_file", ctx.file.parameters_file) |
| args.add_all(ctx.files.filter_srcs, before_each = "--filter_file") |
| |
| ctx.actions.run( |
| inputs = ctx.files.src + ctx.files.includes + ctx.files.parameters_file + ctx.files.filter_srcs, |
| tools = [ctx.executable._jinja2], |
| progress_message = "Generating " + out.short_path, |
| outputs = [out], |
| executable = ctx.executable._jinja2, |
| arguments = [args], |
| ) |
| |
| return [DefaultInfo(files = depset([out])), OutputGroupInfo(out = depset([out]))] |
| |
| jinja2_template_rule = rule( |
| attrs = { |
| "out": attr.output( |
| mandatory = True, |
| doc = """The file to generate using the template. If using the jinja2_template macro below, this will automatically be populated with the contents of the `name` parameter.""", |
| ), |
| "src": attr.label( |
| mandatory = True, |
| allow_single_file = True, |
| doc = """The jinja2 template file to expand.""", |
| ), |
| "parameters": attr.string_dict( |
| mandatory = False, |
| default = {}, |
| doc = """The string parameters to supply to Jinja2.""", |
| ), |
| "list_parameters": attr.string_list_dict( |
| mandatory = False, |
| default = {}, |
| doc = """The string list parameters to supply to Jinja2.""", |
| ), |
| "parameters_file": attr.label( |
| allow_single_file = True, |
| doc = """A JSON file whose contents are supplied as parameters to Jinja2.""", |
| ), |
| "includes": attr.label_list( |
| allow_files = True, |
| doc = """Files which are included by the template.""", |
| ), |
| "filter_srcs": attr.label_list( |
| allow_files = [".py"], |
| doc = """Files that are sourced for filters. |
| Needs to have a register_filters function defined.""", |
| ), |
| "_jinja2": attr.label( |
| default = "//tools/build_rules:jinja2_generator", |
| cfg = "exec", |
| executable = True, |
| ), |
| }, |
| implementation = _jinja2_template_impl, |
| doc = """Expands a jinja2 template given parameters.""", |
| ) |
| |
| def jinja2_template(name, src, parameters = {}, list_parameters = {}, **kwargs): |
| # Since the `out` field will be set to `name`, and the name for the rule must |
| # differ from `out`, name the rule as the `name` plus a suffix |
| rule_name = name + "_rule" |
| |
| jinja2_template_rule( |
| name = rule_name, |
| out = name, |
| src = src, |
| parameters = parameters, |
| list_parameters = list_parameters, |
| **kwargs |
| ) |