# Jsonnet Rules ## Rules * [`jsonnet_library`](#jsonnet_library) * [`jsonnet_to_json`](#jsonnet_to_json) * [`jsonnet_to_json_test`](#jsonnet_to_json_test) ## Overview These are build rules for working with [Jsonnet][jsonnet] files with Bazel. [jsonnet]: http://google.github.io/jsonnet/doc/ ## Setup To use the Jsonnet rules, simply copy the contents of `jsonnet.WORKSPACE` into your `WORKSPACE` file. ## jsonnet_library ```python jsonnet_library(name, srcs, deps, imports) ```
Attribute Description
name Name, required

A unique name for this rule.

srcs List of Labels, required

List of .jsonnet files that comprises this Jsonnet library.

deps List of labels, optional

List of targets that are required by the srcs Jsonnet files.

imports List of strings, optional

List of import -J flags to be passed to the jsonnet compiler.

### Example Suppose you have the following directory structure: ``` [workspace]/ WORKSPACE configs/ BUILD backend.jsonnet frontend.jsonnet ``` You can use the `jsonnet_library` rule to build a collection of `.jsonnet` files that can be imported by other `.jsonnet` files as dependencies: `configs/BUILD`: ```python load("/tools/build_defs/jsonnet/jsonnet", "jsonnet_library") jsonnet_library( name = "configs", srcs = [ "backend.jsonnet", "frontend.jsonnet", ], ) ``` ## jsonnet_to_json ```python jsonnet_to_json(name, src, deps, outs, multiple_outputs, imports, vars, code_vars) ```
Attribute Description
name Name, required

A unique name for this rule.

This name will be used as the name of the JSON file generated by this rule.

src Label, required

The .jsonnet file to convert to JSON.

deps List of labels, optional

List of targets that are required by the src Jsonnet file.

outs List of Filenames, optional

Names of the output .json files to be generated by this rule.

If you are generating only a single JSON file and are not using jsonnet multiple output files, then this attribute should only contain the file name of the JSON file you are generating.

If you are generating multiple JSON files using jsonnet multiple file output (jsonnet -m), then list the file names of all the JSON files to be generated. The file names specified here must match the file names specified in your src Jsonnet file.

For the case where multiple file output is used but only for generating one output file, set the multiple_outputs attribute to 1 to explicitly enable the -m flag for multiple file output.

multiple_outputs bool, optional, default 0

Set to 1 to explicitly enable multiple file output via the jsonnet -m flag.

This is used for the case where multiple file output is used but only for generating a single output file. For example:

local foo = import "foo.jsonnet";

{
  "foo.json": foo,
}

imports List of strings, optional

List of import -J flags to be passed to the jsonnet compiler.

vars String dict, optional

Map of variables to pass to jsonnet via --var key=value.

code_vars String dict, optional

Map of code variables to pass to jsonnet via --code-var key=value.

### Example Suppose you have the following directory structure: ``` [workspace]/ WORKSPACE workflows/ BUILD workflow.jsonnet wordcount.jsonnet intersection.jsonnet ``` Say that `workflow.jsonnet` is a base configuration library for a workflow scheduling system and `wordcount.jsonnet` and `intersection.jsonnet` both import `workflow.jsonnet` to define workflows for performing a wordcount and intersection of two files, respectively. First, create a `jsonnet_library` target with `workflow.jsonnet`: `workflows/BUILD`: ```python load("/tools/build_defs/jsonnet/jsonnet", "jsonnet_library") jsonnet_library( name = "workflow", srcs = ["workflow.jsonnet"], ) ``` To compile `wordcount.jsonnet` and `intersection.jsonnet` to JSON, define two `jsonnet_to_json` targets: ```python jsonnet_to_json( name = "wordcount", src = "wordcount.jsonnet", outs = ["wordcount.json"], deps = [":workflow"], ) jsonnet_to_json( name = "intersection", src = "intersection.jsonnet", outs = ["intersection.json"], deps = [":workflow"], ) ``` ### Example: Multiple output files To use Jsonnet's [multiple output files][multiple-output-files], suppose you add a file `shell-workflows.jsonnet` that imports `wordcount.jsonnet` and `intersection.jsonnet`: `workflows/shell-workflows.jsonnet`: ``` local wordcount = import "workflows/wordcount.jsonnet"; local intersection = import "workflows/intersection.jsonnet"; { "wordcount-workflow.json": wordcount, "intersection-workflow.json": intersection, } ``` To compile `shell-workflows.jsonnet` into the two JSON files, `wordcount-workflow.json` and `intersection-workflow.json`, first create a `jsonnet_library` target containing the two files that `shell-workflows.jsonnet` depends on: ```python jsonnet_library( name = "shell-workflows-lib", srcs = [ "wordcount.jsonnet", "intersection.jsonnet", ], deps = [":workflow"], ) ``` Then, create a `jsonnet_to_json` target and set `outs` to the list of output files to indicate that multiple output JSON files are generated: ```python jsonnet_to_json( name = "shell-workflows", src = "shell-workflows.jsonnet", deps = [":shell-workflows-lib"], outs = [ "wordcount-workflow.jsonnet", "intersection-workflow.jsonnet", ], ) ``` [multiple-output-files]: http://google.github.io/jsonnet/doc/commandline.html ## jsonnet_to_json_test ```python jsonnet_to_json_test(name, src, deps, imports, golden, error=0, regex=False) ```
Attribute Description
name Name, required

A unique name for this rule.

This name will be used as the name of the JSON file generated by this rule.

src Label, required

The .jsonnet file to convert to JSON.

deps List of labels, optional

List of targets that are required by the src Jsonnet file.

imports List of strings, optional

List of import -J flags to be passed to the jsonnet compiler.

vars String dict, optional

Map of variables to pass to jsonnet via --var key=value.

code_vars String dict, optional

Map of code variables to pass to jsonnet via --code-var key=value.

golden Label, optional

The expected (combined stdout and stderr) output to compare to the output of running jsonnet on src.

error Integer, optional, default is 0

The expected error code from running jsonnet on src.

regex bool, optional, default is False

Set to 1 if golden contains a regex used to match the output of running jsonnet on src.

### Example Suppose you have the following directory structure: ``` [workspace]/ WORKSPACE config/ BUILD base_config.jsonnet test_config.jsonnet test_config.json ``` Suppose that `base_config.jsonnet` is a library Jsonnet file, containing the base configuration for a service. Suppose that `test_config.jsonnet` is a test configuration file that is used to test `base_config.jsonnet`, and `test_config.json` is the expected JSON output from compiling `test_config.jsonnet`. The `jsonnet_to_json_test` rule can be used to verify that compiling a Jsonnet file produces the expected JSON output. Simply define a `jsonnet_to_json_test` target and provide the input test Jsonnet file and the `golden` file containing the expected JSON output: `config/BUILD`: ```python load( "/tools/build_defs/jsonnet/jsonnet", "jsonnet_library", "jsonnet_to_json_test", ) jsonnet_library( name = "base_config", srcs = ["base_config.jsonnet"], ) jsonnet_to_json_test( name = "test_config_test", src = "test_config", deps = [":base_config"], golden = "test_config.json", ) ``` To run the test: `bazel test //config:test_config_test` ### Example: Negative tests Suppose you have the following directory structure: ``` [workspace]/ WORKSPACE config/ BUILD base_config.jsonnet invalid_config.jsonnet invalid_config.output ``` Suppose that `invalid_config.jsonnet` is a Jsonnet file used to verify that an invalid config triggers an assertion in `base_config.jsonnet`, and `invalid_config.output` is the expected error output. The `jsonnet_to_json_test` rule can be used to verify that compiling a Jsonnet file results in an expected error code and error output. Simply define a `jsonnet_to_json_test` target and provide the input test Jsonnet file, the expected error code in the `error` attribute, and the `golden` file containing the expected error output: `config/BUILD`: ```python load( "/tools/build_defs/jsonnet/jsonnet", "jsonnet_library", "jsonnet_to_json_test", ) jsonnet_library( name = "base_config", srcs = ["base_config.jsonnet"], ) jsonnet_to_json_test( name = "invalid_config_test", src = "invalid_config", deps = [":base_config"], golden = "invalid_config.output", error = 1, ) ``` To run the test: `bazel test //config:invalid_config_test`