"""Public API for yq""" load("//lib/private:yq.bzl", _is_split_operation = "is_split_operation", _yq_lib = "yq_lib") _yq_rule = rule( attrs = _yq_lib.attrs, implementation = _yq_lib.implementation, toolchains = ["@aspect_bazel_lib//lib:yq_toolchain_type"], ) def yq(name, srcs, expression = ".", args = [], outs = None, **kwargs): """Invoke yq with an expression on a set of input files. For yq documentation, see https://mikefarah.gitbook.io/yq. To use this rule you must register the yq toolchain in your WORKSPACE: ```starlark load("@aspect_bazel_lib//lib:repositories.bzl", "register_yq_toolchains") register_yq_toolchains() ``` Usage examples: ```starlark load("@aspect_bazel_lib//lib:yq.bzl", "yq") ``` ```starlark # Remove fields yq( name = "safe-config", srcs = ["config.yaml"], expression = "del(.credentials)", ) ``` ```starlark # Merge two yaml documents yq( name = "ab", srcs = [ "a.yaml", "b.yaml", ], expression = ". as $item ireduce ({}; . * $item )", ) ``` ```starlark # Split a yaml file into several files yq( name = "split", srcs = ["multidoc.yaml"], outs = [ "first.yml", "second.yml", ], args = [ "-s '.a'", # Split expression "--no-doc", # Exclude document separator -- ], ) ``` ```starlark # Convert a yaml file to json yq( name = "convert-to-json", srcs = ["foo.yaml"], args = ["-o=json"], outs = ["foo.json"], ) ``` ```starlark # Convert a json file to yaml yq( name = "convert-to-yaml", srcs = ["bar.json"], args = ["-P"], outs = ["bar.yaml"], ) ``` ```starlark # Call yq in a genrule genrule( name = "generate", srcs = ["farm.yaml"], outs = ["genrule_output.yaml"], cmd = "$(YQ_BIN) '.moo = \"cow\"' $(location farm.yaml) > $@", toolchains = ["@yq_toolchains//:resolved_toolchain"], ) ``` yq is capable of parsing and outputting to other formats. See their [docs](https://mikefarah.gitbook.io/yq) for more examples. Args: name: Name of the rule srcs: List of input file labels expression: yq expression (https://mikefarah.gitbook.io/yq/commands/evaluate). Defaults to the identity expression "." args: Additional args to pass to yq. Note that you do not need to pass _eval_ or _eval-all_ as this is handled automatically based on the number `srcs`. Passing the output format or the parse format is optional as these can be guessed based on the file extensions in `srcs` and `outs`. outs: Name of the output files. Defaults to a single output with the name plus a ".yaml" extension, or the extension corresponding to a passed output argment (e.g., "-o=json"). For split operations you must declare all outputs as the name of the output files depends on the expression. **kwargs: Other common named parameters such as `tags` or `visibility` """ args = args[:] if not _is_split_operation(args): # For split operations we can't predeclare outs because the name of the resulting files # depends on the expression. For non-split operations, set a default output file name # based on the name and the output format passed, defaulting to yaml. if not outs: outs = [name + ".yaml"] if "-o=json" in args or "--outputformat=json" in args: outs = [name + ".json"] if "-o=xml" in args or "--outputformat=xml" in args: outs = [name + ".xml"] elif "-o=props" in args or "--outputformat=props" in args: outs = [name + ".properties"] elif "-o=c" in args or "--outputformat=csv" in args: outs = [name + ".csv"] elif "-o=t" in args or "--outputformat=tsv" in args: outs = [name + ".tsv"] elif outs and len(outs) == 1: # If an output file with an extension was provided, try to set the corresponding output # argument if it wasn't already passed. if outs[0].endswith(".json") and "-o=json" not in args and "--outputformat=json" not in args: args.append("-o=json") elif outs[0].endswith(".xml") and "-o=xml" not in args and "--outputformat=xml" not in args: args.append("-o=xml") elif outs[0].endswith(".properties") and "-o=props" not in args and "--outputformat=props" not in args: args.append("-o=props") elif outs[0].endswith(".csv") and "-o=c" not in args and "--outputformat=csv" not in args: args.append("-o=c") elif outs[0].endswith(".tsv") and "-o=t" not in args and "--outputformat=tsv" not in args: args.append("-o=t") # If the input files are json or xml, set the parse flag if it isn't already set if len(srcs) > 0: if srcs[0].endswith(".json") and "-P" not in args: args.append("-P") elif srcs[0].endswith(".xml") and "-p=xml" not in args: args.append("-p=xml") _yq_rule( name = name, srcs = srcs, expression = expression, args = args, outs = outs, **kwargs )