diff --git a/docs/jq.md b/docs/jq.md index 79cf3ea..75b9ae9 100644 --- a/docs/jq.md +++ b/docs/jq.md @@ -7,7 +7,7 @@ Public API for jq ## jq
-jq(name, srcs, filter, filter_file, args, out, kwargs)
+jq(name, srcs, filter, filter_file, args, out, data, expand_args, kwargs)
 
Invoke jq with a filter on a set of json input files. @@ -127,6 +127,8 @@ genrule( | filter_file | File containing filter expression (alternative to filter) | None | | args | Additional args to pass to jq | [] | | out | Name of the output json file; defaults to the rule name plus ".json" | None | +| data | List of additional files. May be empty. | [] | +| expand_args | Run bazel's location-expansion on the args. | False | | kwargs | Other common named parameters such as tags or visibility | none | diff --git a/lib/jq.bzl b/lib/jq.bzl index 80203c2..f972246 100644 --- a/lib/jq.bzl +++ b/lib/jq.bzl @@ -8,7 +8,7 @@ _jq_rule = rule( toolchains = ["@aspect_bazel_lib//lib:jq_toolchain_type"], ) -def jq(name, srcs, filter = None, filter_file = None, args = [], out = None, **kwargs): +def jq(name, srcs, filter = None, filter_file = None, args = [], out = None, data = [], expand_args = False, **kwargs): """Invoke jq with a filter on a set of json input files. For jq documentation, see https://stedolan.github.io/jq/. @@ -117,6 +117,7 @@ def jq(name, srcs, filter = None, filter_file = None, args = [], out = None, **k Args: name: Name of the rule srcs: List of input files. May be empty. + data: List of additional files. May be empty. filter: Filter expression (https://stedolan.github.io/jq/manual/#Basicfilters). Subject to stamp variable replacements, see [Stamping](./stamping.md). When stamping is enabled, a variable named "STAMP" will be available in the filter. @@ -125,6 +126,7 @@ def jq(name, srcs, filter = None, filter_file = None, args = [], out = None, **k filter_file: File containing filter expression (alternative to `filter`) args: Additional args to pass to jq + expand_args: Run bazel's location-expansion on the args. out: Name of the output json file; defaults to the rule name plus ".json" **kwargs: Other common named parameters such as `tags` or `visibility` """ @@ -139,5 +141,7 @@ def jq(name, srcs, filter = None, filter_file = None, args = [], out = None, **k filter_file = filter_file, args = args, out = out, + expand_args = expand_args, + data = data, **kwargs ) diff --git a/lib/private/BUILD.bazel b/lib/private/BUILD.bazel index fe9b06d..a0e0924 100644 --- a/lib/private/BUILD.bazel +++ b/lib/private/BUILD.bazel @@ -159,7 +159,10 @@ bzl_library( name = "jq", srcs = ["jq.bzl"], visibility = ["//lib:__subpackages__"], - deps = ["//lib:stamping"], + deps = [ + ":expand_locations", + "//lib:stamping", + ], ) bzl_library( diff --git a/lib/private/jq.bzl b/lib/private/jq.bzl index aa03d8a..7c8a493 100644 --- a/lib/private/jq.bzl +++ b/lib/private/jq.bzl @@ -1,6 +1,7 @@ """Implementation for jq rule""" load("//lib:stamping.bzl", "STAMP_ATTRS", "maybe_stamp") +load(":expand_locations.bzl", "expand_locations") _jq_attrs = dict({ "srcs": attr.label_list( @@ -8,9 +9,13 @@ _jq_attrs = dict({ mandatory = True, allow_empty = True, ), + "data": attr.label_list( + allow_files = True, + ), "filter": attr.string(), "filter_file": attr.label(allow_single_file = True), "args": attr.string_list(), + "expand_args": attr.bool(), "out": attr.output(), "_parse_status_file_filter": attr.label( allow_single_file = True, @@ -18,12 +23,25 @@ _jq_attrs = dict({ ), }, **STAMP_ATTRS) +def _expand_locations(ctx, s): + # `.split(" ")` is a work-around https://github.com/bazelbuild/bazel/issues/10309 + # TODO: If the string has intentional spaces or if one or more of the expanded file + # locations has a space in the name, we will incorrectly split it into multiple arguments + return expand_locations(ctx, s, targets = ctx.attr.data).split(" ") + def _jq_impl(ctx): jq_bin = ctx.toolchains["@aspect_bazel_lib//lib:jq_toolchain_type"].jqinfo.bin out = ctx.outputs.out or ctx.actions.declare_file(ctx.attr.name + ".json") - args = ctx.attr.args + if ctx.attr.expand_args: + args = [] + for a in ctx.attr.args: + args += _expand_locations(ctx, a) + else: + args = ctx.attr.args + inputs = ctx.files.srcs[:] + inputs += ctx.files.data if not ctx.attr.filter and not ctx.attr.filter_file: fail("Must provide a filter or a filter_file") diff --git a/lib/tests/jq/BUILD.bazel b/lib/tests/jq/BUILD.bazel index d87e69c..c1d16f5 100644 --- a/lib/tests/jq/BUILD.bazel +++ b/lib/tests/jq/BUILD.bazel @@ -79,6 +79,26 @@ diff_test( file2 = "null.json", ) +# Data files are passed in correctly +jq( + name = "case_data_input_flag", + srcs = [], + args = [ + "--slurpfile", + "a", + "$(location a_pretty.json)", + ], + data = ["a_pretty.json"], + expand_args = True, + filter = "$a[0]", +) + +diff_test( + name = "case_data_input_flag_test", + file1 = ":case_data_input_flag", + file2 = "a_pretty.json", +) + # Load filter from file jq( name = "case_filter_file",