From 9d5a4b3fd51de869cd9f7c2ea06c3b4376bc6bc0 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Thu, 4 Apr 2024 09:43:26 +0200 Subject: [PATCH] Switch from Skydoc to Stardoc Fixes: #177 --- .bazelci/presubmit.yml | 10 + MODULE.bazel | 1 + WORKSPACE | 35 ---- docs/BUILD | 10 - docs/BUILD.bazel | 10 + docs/MODULE.bazel | 13 ++ docs/WORKSPACE | 1 - docs/jsonnet.md | 404 +++++++++++++++++++++++++++++++++++++++++ docs/main.css | 3 - jsonnet/BUILD | 15 +- 10 files changed, 452 insertions(+), 50 deletions(-) delete mode 100644 docs/BUILD create mode 100644 docs/BUILD.bazel create mode 100644 docs/MODULE.bazel delete mode 100644 docs/WORKSPACE create mode 100644 docs/jsonnet.md delete mode 100755 docs/main.css diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 2b8765b..b273d67 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -11,6 +11,16 @@ tasks: build_targets: - //... + docs: + name: docs + platform: ${{ platform }} + working_directory: docs + test_flags: + - --define + - jsonnet_port=${{ jsonnet_port }} + test_targets: + - //... + examples: name: examples platform: ${{ platform }} diff --git a/MODULE.bazel b/MODULE.bazel index 716b5b1..296d7c4 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -4,5 +4,6 @@ module( repo_name = "io_bazel_rules_jsonnet", ) +bazel_dep(name = "bazel_skylib", version = "1.5.0") bazel_dep(name = "jsonnet", version = "0.20.0") bazel_dep(name = "jsonnet_go", version = "0.20.0", repo_name = "google_jsonnet_go") diff --git a/WORKSPACE b/WORKSPACE index 6613962..33346a4 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,12 +1,5 @@ workspace(name = "io_bazel_rules_jsonnet") -load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") - -local_repository( - name = "docs", - path = "docs", -) - load("//jsonnet:jsonnet.bzl", "jsonnet_repositories") jsonnet_repositories() @@ -18,31 +11,3 @@ jsonnet_go_repositories() load("@google_jsonnet_go//bazel:deps.bzl", "jsonnet_go_dependencies") jsonnet_go_dependencies(go_sdk_version = "1.17.8") - -# Used for documenting Jsonnet rules. -# TODO: Move this to docs/WORKSPACE when recursive repositories are enabled. -git_repository( - name = "io_bazel_rules_sass", - remote = "https://github.com/bazelbuild/rules_sass.git", - commit = "a28d5ec04b32daef96299b22bb2fbd961c3febe6", # release 1.15.3 - shallow_since = "1546636230 +0000" -) - -load("@io_bazel_rules_sass//:package.bzl", "rules_sass_dependencies") - -rules_sass_dependencies() - -load("@io_bazel_rules_sass//:defs.bzl", "sass_repositories") - -sass_repositories() - -git_repository( - name = "io_bazel_skydoc", - remote = "https://github.com/bazelbuild/skydoc.git", - commit = "4ea7b8257d11ac33eef7e9daadbedbfe375d9236", # release 0.2.0 - shallow_since = "1543532884 -0500", -) - -load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories") - -skydoc_repositories() diff --git a/docs/BUILD b/docs/BUILD deleted file mode 100644 index 3bad158..0000000 --- a/docs/BUILD +++ /dev/null @@ -1,10 +0,0 @@ -package(default_visibility = ["//visibility:private"]) - -load("@io_bazel_skydoc//skylark:skylark.bzl", "skylark_doc") - -skylark_doc( - name = "jsonnet-docs", - srcs = ["@io_bazel_rules_jsonnet//jsonnet:jsonnet.bzl"], - format = "html", - site_root = "https://bazelbuild.github.io/rules_jsonnet", -) diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel new file mode 100644 index 0000000..713c582 --- /dev/null +++ b/docs/BUILD.bazel @@ -0,0 +1,10 @@ +load("@aspect_bazel_lib//lib:docs.bzl", "stardoc_with_diff_test", "update_docs") + +stardoc_with_diff_test( + name = "jsonnet", + bzl_library_target = "@rules_jsonnet//jsonnet:jsonnet", +) + +update_docs( + name = "update", +) diff --git a/docs/MODULE.bazel b/docs/MODULE.bazel new file mode 100644 index 0000000..be65ee9 --- /dev/null +++ b/docs/MODULE.bazel @@ -0,0 +1,13 @@ +module( + name = "docs", + version = "0.0.0", +) + +bazel_dep(name = "aspect_bazel_lib", version = "2.7.0") +bazel_dep(name = "stardoc", version = "0.6.2") + +bazel_dep(name = "rules_jsonnet", version = "0.5.0") +local_path_override( + module_name = "rules_jsonnet", + path = "..", +) diff --git a/docs/WORKSPACE b/docs/WORKSPACE deleted file mode 100644 index 88a2683..0000000 --- a/docs/WORKSPACE +++ /dev/null @@ -1 +0,0 @@ -workspace(name = "docs") diff --git a/docs/jsonnet.md b/docs/jsonnet.md new file mode 100644 index 0000000..627315e --- /dev/null +++ b/docs/jsonnet.md @@ -0,0 +1,404 @@ + + +Jsonnet Rules + +These are build rules for working with [Jsonnet][jsonnet] files with Bazel. + +[jsonnet]: https://jsonnet.org/ + +## Setup + +To use the Jsonnet rules, add the following to your `WORKSPACE` file to add the +external repositories for Jsonnet: + +```python +http_archive( + name = "io_bazel_rules_jsonnet", + urls = [ + "http://mirror.bazel.build/github.com/bazelbuild/rules_jsonnet/archive/0.0.2.tar.gz", + "https://github.com/bazelbuild/rules_jsonnet/archive/0.0.2.tar.gz", + ], + sha256 = "5f788c7719a02ed2483641365f194e9e5340fbe54963d6d6caa09f91454d38b8", + strip_prefix = "rules_jsonnet-0.0.2", +) +load("@io_bazel_rules_jsonnet//jsonnet:jsonnet.bzl", "jsonnet_repositories") + +jsonnet_repositories() +``` + + + +## jsonnet_library + +
+jsonnet_library(name, deps, srcs, data, imports, jsonnet)
+
+ +Creates a logical set of Jsonnet files. + +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("@io_bazel_rules_jsonnet//jsonnet:jsonnet.bzl", "jsonnet_library") + + jsonnet_library( + name = "configs", + srcs = [ + "backend.jsonnet", + "frontend.jsonnet", + ], + ) + ``` + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| deps | List of targets that are required by the `srcs` Jsonnet files. | List of labels | optional | `[]` | +| srcs | List of `.jsonnet` files that comprises this Jsonnet library | List of labels | optional | `[]` | +| data | - | List of labels | optional | `[]` | +| imports | List of import `-J` flags to be passed to the `jsonnet` compiler. | List of strings | optional | `[]` | +| jsonnet | A jsonnet binary | Label | optional | `"@rules_jsonnet//jsonnet:jsonnet_tool"` | + + + + +## jsonnet_to_json + +
+jsonnet_to_json(name, deps, src, data, outs, code_vars, ext_code, ext_code_envs, ext_code_file_vars,
+                ext_code_files, ext_str_envs, ext_str_file_vars, ext_str_files, ext_strs, extra_args,
+                imports, jsonnet, multiple_outputs, stamp_keys, tla_code, tla_code_envs,
+                tla_code_files, tla_str_envs, tla_str_files, tla_strs, vars, yaml_stream)
+
+ +Compiles Jsonnet code to JSON. + +Example: + ### Example + + 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`: + + ```python + 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: + + ```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.json", + "intersection-workflow.json", + ], + ) + ``` + + [multiple-output-files]: https://jsonnet.org/learning/getting_started.html#multi + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| deps | List of targets that are required by the `srcs` Jsonnet files. | List of labels | optional | `[]` | +| src | The `.jsonnet` file to convert to JSON. | Label | optional | `None` | +| data | - | List of labels | optional | `[]` | +| outs | 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. | List of labels | required | | +| code_vars | Deprecated (use 'ext_code'). | Dictionary: String -> String | optional | `{}` | +| ext_code | - | Dictionary: String -> String | optional | `{}` | +| ext_code_envs | - | List of strings | optional | `[]` | +| ext_code_file_vars | - | List of strings | optional | `[]` | +| ext_code_files | - | List of labels | optional | `[]` | +| ext_str_envs | - | List of strings | optional | `[]` | +| ext_str_file_vars | - | List of strings | optional | `[]` | +| ext_str_files | - | List of labels | optional | `[]` | +| ext_strs | - | Dictionary: String -> String | optional | `{}` | +| extra_args | - | List of strings | optional | `[]` | +| imports | List of import `-J` flags to be passed to the `jsonnet` compiler. | List of strings | optional | `[]` | +| jsonnet | A jsonnet binary | Label | optional | `"@rules_jsonnet//jsonnet:jsonnet_tool"` | +| multiple_outputs | Set to `True` 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,
}
| Boolean | optional | `False` | +| stamp_keys | - | List of strings | optional | `[]` | +| tla_code | - | Dictionary: String -> String | optional | `{}` | +| tla_code_envs | - | List of strings | optional | `[]` | +| tla_code_files | - | Dictionary: Label -> String | optional | `{}` | +| tla_str_envs | - | List of strings | optional | `[]` | +| tla_str_files | - | Dictionary: Label -> String | optional | `{}` | +| tla_strs | - | Dictionary: String -> String | optional | `{}` | +| vars | Deprecated (use 'ext_strs'). | Dictionary: String -> String | optional | `{}` | +| yaml_stream | - | Boolean | optional | `False` | + + + + +## jsonnet_to_json_test + +
+jsonnet_to_json_test(name, deps, src, data, canonicalize_golden, code_vars, error, ext_code,
+                     ext_code_envs, ext_code_file_vars, ext_code_files, ext_str_envs,
+                     ext_str_file_vars, ext_str_files, ext_strs, extra_args, golden, imports, jsonnet,
+                     output_file_contents, regex, stamp_keys, tla_code, tla_code_envs, tla_code_files,
+                     tla_str_envs, tla_str_files, tla_strs, vars, yaml_stream)
+
+ +Compiles Jsonnet code to JSON and checks the output. + +Example: + 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`: + + ```python + 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` + + ### Example: Negative tests + + 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`: + + ```python + 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` + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| deps | List of targets that are required by the `srcs` Jsonnet files. | List of labels | optional | `[]` | +| src | The `.jsonnet` file to convert to JSON. | Label | optional | `None` | +| data | - | List of labels | optional | `[]` | +| canonicalize_golden | - | Boolean | optional | `True` | +| code_vars | Deprecated (use 'ext_code'). | Dictionary: String -> String | optional | `{}` | +| error | The expected error code from running `jsonnet` on `src`. | Integer | optional | `0` | +| ext_code | - | Dictionary: String -> String | optional | `{}` | +| ext_code_envs | - | List of strings | optional | `[]` | +| ext_code_file_vars | - | List of strings | optional | `[]` | +| ext_code_files | - | List of labels | optional | `[]` | +| ext_str_envs | - | List of strings | optional | `[]` | +| ext_str_file_vars | - | List of strings | optional | `[]` | +| ext_str_files | - | List of labels | optional | `[]` | +| ext_strs | - | Dictionary: String -> String | optional | `{}` | +| extra_args | - | List of strings | optional | `[]` | +| golden | The expected (combined stdout and stderr) output to compare to the output of running `jsonnet` on `src`. | Label | optional | `None` | +| imports | List of import `-J` flags to be passed to the `jsonnet` compiler. | List of strings | optional | `[]` | +| jsonnet | A jsonnet binary | Label | optional | `"@rules_jsonnet//jsonnet:jsonnet_tool"` | +| output_file_contents | - | Boolean | optional | `True` | +| regex | Set to 1 if `golden` contains a regex used to match the output of running `jsonnet` on `src`. | Boolean | optional | `False` | +| stamp_keys | - | List of strings | optional | `[]` | +| tla_code | - | Dictionary: String -> String | optional | `{}` | +| tla_code_envs | - | List of strings | optional | `[]` | +| tla_code_files | - | Dictionary: Label -> String | optional | `{}` | +| tla_str_envs | - | List of strings | optional | `[]` | +| tla_str_files | - | Dictionary: Label -> String | optional | `{}` | +| tla_strs | - | Dictionary: String -> String | optional | `{}` | +| vars | Deprecated (use 'ext_strs'). | Dictionary: String -> String | optional | `{}` | +| yaml_stream | - | Boolean | optional | `False` | + + + + +## JsonnetLibraryInfo + +
+JsonnetLibraryInfo()
+
+ + + +**FIELDS** + + + + + +## jsonnet_repositories + +
+jsonnet_repositories()
+
+ +Adds the external dependencies needed for the Jsonnet rules. + + + diff --git a/docs/main.css b/docs/main.css deleted file mode 100755 index f506e12..0000000 --- a/docs/main.css +++ /dev/null @@ -1,3 +0,0 @@ -body{background-color:#fafafa}pre,code{font-family:'Liberation Mono', Consolas, Monaco, 'Andale Mono', monospace}pre{background-color:#eee;padding:20px;overflow-x:auto;word-wrap:normal}pre code{overflow-wrap:normal;white-space:pre}code{display:inline-block;font-size:90%;white-space:pre-wrap}.mdl-layout__drawer{background-color:#fff}.mdl-layout__drawer .mdl-layout-title{border-bottom:1px solid #e0e0e0;padding-left:24px}.drawer-nav ul{list-style:none;padding-left:0}.drawer-nav ul li{display:block;padding:0}.drawer-nav ul li ul li a{padding-left:44px;font-weight:400}.drawer-nav ul li a{display:block;flex-shrink:0;padding:15px 0 15px 22px;margin:0;font-weight:600;color:#757575;line-height:1em;text-decoration:none;cursor:pointer}.drawer-nav ul li a:active,.drawer-nav ul li a:hover{background-color:#f0f0f0}.drawer-nav ul li.active a{color:#4caf50;font-weight:500}h1.page-title{font-size:34px;font-weight:400;line-height:40px;margin-bottom:30px;color:#4caf50}p.lead{font-size:20px;line-height:32px}table{border-collapse:collapse;border-spacing:0;background-color:#fff;table-layout:auto}table thead th{background-color:#fafafa;border:1px solid #eee;color:#757575;padding:12px 12px 12px 24px;vertical-align:top}table tbody td{border:1px solid #eee;padding:12px 12px 12px 24px;vertical-align:top}table.params-table{width:100%}table.params-table col.col-param{width:25%}table.params-table col.col-description{width:75%}table.overview-table{width:100%}table.overview-table col.col-name{width:25%}table.overview-table col.col-description{width:75%}table.overview-table td p{margin:0}hr{margin-top:80px;margin-bottom:80px}nav.toc{border-left:5px solid #4caf50;padding-left:20px;margin-bottom:48px}nav.toc h1,nav.toc h2{font-size:15px;line-height:16px;padding-bottom:12px;margin-bottom:0;font-weight:400;color:#757575}nav.toc ul{list-style:none;margin-top:0;padding-left:0}nav.toc ul li{font-size:20px;line-height:40px}nav.toc ul li a{color:#4caf50}.page-content{margin-left:auto;margin-right:auto;padding-top:60px;padding-bottom:60px;width:760px}.page-content a{text-decoration:none}.page-content h1{font-size:34px;font-weight:400;line-height:40px;margin-bottom:30px;color:#4caf50}.page-content h2{font-size:24px;font-weight:400;line-height:32px;margin-bottom:30px;color:#4caf50}.page-content h3{font-size:20px;font-weight:400;line-height:32px;margin-bottom:30px;color:#4caf50}@media (max-width: 768px){.page-content{width:360px}}@media (min-width: 768px){.page-content{width:760px}}@media (min-width: 1476px){.page-content{width:1160px}}.mdl-mini-footer{padding-left:40px} - -/*# sourceMappingURL=main.css.map */ \ No newline at end of file diff --git a/jsonnet/BUILD b/jsonnet/BUILD index 37ff0e2..cfdafbf 100644 --- a/jsonnet/BUILD +++ b/jsonnet/BUILD @@ -1,7 +1,19 @@ -package(default_visibility = ["//visibility:public"]) +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") exports_files(["jsonnet.bzl"]) +bzl_library( + name = "bzl_srcs", + srcs = ["@bazel_tools//tools:bzl_srcs"], +) + +bzl_library( + name = "jsonnet", + srcs = ["jsonnet.bzl"], + deps = [":bzl_srcs"], + visibility = ["//visibility:public"], +) + py_binary( name = "stamper", srcs = ["stamper.py"], @@ -29,4 +41,5 @@ alias( "//jsonnet:port_cpp": "@jsonnet//cmd:jsonnet", "//conditions:default": "@google_jsonnet_go//cmd/jsonnet", }), + visibility = ["//visibility:public"], )