These are build rules for working with Jsonnet files with Bazel.
To use the Jsonnet rules, add the following to your WORKSPACE
file to add the
external repositories for Jsonnet:
http_archive(
name = "io_bazel_rules_jsonnet",
sha256 = "7f51f859035cd98bcf4f70dedaeaca47fe9fbae6b199882c516d67df416505da",
strip_prefix = "rules_jsonnet-0.3.0",
urls = ["https://github.com/bazelbuild/rules_jsonnet/archive/0.3.0.tar.gz"],
)
load("@io_bazel_rules_jsonnet//jsonnet:jsonnet.bzl", "jsonnet_repositories")
jsonnet_repositories()
load("@google_jsonnet_go//bazel:repositories.bzl", "jsonnet_go_repositories")
jsonnet_go_repositories()
load("@google_jsonnet_go//bazel:deps.bzl", "jsonnet_go_dependencies")
jsonnet_go_dependencies()
By default, Bazel will use the Go port of Jsonnet. To use the C++ port of Jsonnet instead, invoke Bazel with the --define jsonnet_port=cpp
command-line flag. To select the Go port explicitly, invoke Bazel with the --define jsonnet_port=go
command-line flag.
bazel Flag | Jsonnet Port |
---|---|
(none) | Go |
--define jsonnet_port=cpp |
C++ |
--define jsonnet_port=go |
Go |
Note that the primary development focus of the Jsonnet project is now with the Go port. This repository's support for using the C++ port is deprecated, and may be removed in a future release.
jsonnet_library(name, srcs, deps, imports)
Attributes | |
---|---|
name |
Name, required
A unique name for this rule. |
srcs |
List of Labels, required
List of |
deps |
List of labels, optional
List of targets that are required by the |
imports |
List of strings, optional
List of import |
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
:
load("@io_bazel_rules_jsonnet//jsonnet:jsonnet.bzl", "jsonnet_library")
jsonnet_library(
name = "configs",
srcs = [
"backend.jsonnet",
"frontend.jsonnet",
],
)
jsonnet_to_json(name, src, deps, outs, multiple_outputs, imports, stamp_keys, ext_strs, ext_str_envs, ext_code, ext_code_envs ext_str_files, ext_str_file_vars, ext_code_files, ext_code_file_vars, yaml_stream)
Attributes | |
---|---|
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 |
deps |
List of labels, optional
List of targets that are required by the |
outs |
List of Filenames, required
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 (
For the case where multiple file output is used but only for
generating one output file, set the |
multiple_outputs |
bool, optional, default 0
Set to 1 to explicitly enable multiple file output via the
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"; |
imports |
List of strings, optional
List of import |
stamp_keys |
List of strings, optional
Specify which variables in
To get outside variables provided by a script invoked via jsonnet_to_json( name = "...", ext_strs = { "cluster": "{CLUSTER}" }, stamp_keys = ["cluster"] ) $ cat .bazelrc build --workspace_status_command=./print-workspace-status.sh $ cat print-workspace-status.sh cat <<EOF VAR1 value1 # This can be overriden by users if they "export CLUSTER_OVERRIDE" CLUSTER ${CLUSTER_OVERRIDE:-default-value2} EOF |
ext_strs |
String dict, optional
Map of strings to pass to jsonnet as external variables via |
ext_str_envs |
String list, optional
List of env var names containing strings to pass to jsonnet as external variables via |
ext_code |
String dict, optional
Map of code to pass to jsonnet as external variables via
|
ext_code_envs |
String list, optional
List of env var names containing jsonnet code to pass to jsonnet as external variables via
|
ext_str_files |
List of labels, optional but needed together with file_vars
List of string files that map to the var name defined in file_vars at the same index and together are passed to jsonnet via
|
ext_str_file_vars |
List of string, optional but needed together with files
List of var names that maps to the file defined in files at the same index and together are passed to jsonnet via
|
ext_code_files |
String dict, optional
List of jsonnet code files that map to the var name defined in ext_code_file_vars at the same index and together are passed to jsonnet via
|
ext_code_file_vars |
String dict, optional
List of var names that maps to the code file defined in code_files at the same index and together are passed to jsonnet via
|
tla_strs |
String dict, optional
Map of strings to pass to jsonnet as top-level arguments via |
tla_str_envs |
String list, optional
List of env var names containing strings to pass to jsonnet as top-level arguments via |
tla_code |
String dict, optional
Map of code to pass to jsonnet as top-level arguments via
|
tla_code_envs |
String list, optional
List of env var names containing jsonnet code to pass to jsonnet as top-level arguments via
|
tla_str_files |
Label-keyed String dict, optional
Dict of labels referencing text files and a var name, passed to jsonnet via |
tla_code_files |
Label-keyed String dict, optional
Dict of labels referencing code files and a var name, passed to jsonnet via |
yaml_stream |
bool, optional, default is False
Set to 1 to write output as a YAML stream of JSON documents. |
Suppose you have the following directory structure:
[workspace]/
WORKSPACE
workflows/
BUILD
workflow.libsonnet
wordcount.jsonnet
intersection.jsonnet
Say that workflow.libsonnet
is a base configuration library for a workflow
scheduling system and wordcount.jsonnet
and intersection.jsonnet
both
import workflow.libsonnet
to define workflows for performing a wordcount and
intersection of two files, respectively.
First, create a jsonnet_library
target with workflow.libsonnet
:
workflows/BUILD
:
load("@io_bazel_rules_jsonnet//jsonnet:jsonnet.bzl", "jsonnet_library")
jsonnet_library(
name = "workflow",
srcs = ["workflow.libsonnet"],
)
To compile wordcount.jsonnet
and intersection.jsonnet
to JSON, define two
jsonnet_to_json
targets:
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"],
)
To use Jsonnet's 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:
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:
jsonnet_to_json(
name = "shell-workflows",
src = "shell-workflows.jsonnet",
deps = [":shell-workflows-lib"],
outs = [
"wordcount-workflow.json",
"intersection-workflow.json",
],
)
jsonnet_to_json_test(name, src, deps, imports, golden, error=0, regex=False, yaml_stream=False, stamp_keys, ext_strs, ext_str_envs, ext_code, ext_code_envs ext_str_files, ext_str_file_vars, ext_code_files, ext_code_file_vars)
Attributes | |
---|---|
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 |
deps |
List of labels, optional
List of targets that are required by the |
imports |
codefileList of strings, optional
List of import |
stamp_keys |
List of strings, optional
Specify which variables in `ext_strs` and `ext_code` should get stamped by listing the matching dict keys. To get outside variables provided by a script invoked via `--workspace_status_command` into the build. |
ext_strs |
String dict, optional
Map of strings to pass to jsonnet as external variables via |
ext_str_envs |
String list, optional
List of env var names containing strings to pass to jsonnet as external variables via |
ext_code |
String dict, optional
Map of code to pass to jsonnet as external variables via
|
ext_code_envs |
String list, optional
List of env var names containing jsonnet code to pass to jsonnet as external variables via
|
ext_str_files |
List of labels, optional but needed together with file_vars
List of string files that map to the var name defined in file_vars at the same index and together are passed to jsonnet via
|
ext_str_file_vars |
List of string, optional but needed together with files
List of var names that maps to the file defined in files at the same index and together are passed to jsonnet via
|
ext_code_files |
String dict, optional
List of jsonnet code files that map to the var name defined in ext_code_file_vars at the same index and together are passed to jsonnet via
|
ext_code_file_vars |
String dict, optional
List of var names that maps to the code file defined in code_files at the same index and together are passed to jsonnet via
|
golden |
Label, optional
The expected (combined stdout and stderr) output to compare to the
output of running |
error |
Integer, optional, default is 0
The expected error code from running |
regex |
bool, optional, default is False
Set to 1 if |
yaml_stream |
bool, optional, default is False
Set to 1 to write output as a YAML stream of JSON documents. |
Suppose you have the following directory structure:
[workspace]/
WORKSPACE
config/
BUILD
base_config.libsonnet
test_config.jsonnet
test_config.json
Suppose that base_config.libsonnet
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
:
load(
"@io_bazel_rules_jsonnet//jsonnet:jsonnet.bzl",
"jsonnet_library",
"jsonnet_to_json_test",
)
jsonnet_library(
name = "base_config",
srcs = ["base_config.libsonnet"],
)
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
Suppose you have the following directory structure:
[workspace]/
WORKSPACE
config/
BUILD
base_config.libsonnet
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
:
load(
"@io_bazel_rules_jsonnet//jsonnet:jsonnet.bzl",
"jsonnet_library",
"jsonnet_to_json_test",
)
jsonnet_library(
name = "base_config",
srcs = ["base_config.libsonnet"],
)
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