Skip to content

Commit 32b12fd

Browse files
authored
Implement an install command (#654)
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent 350b49f commit 32b12fd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3171
-83
lines changed

.github/workflows/package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ jobs:
6969
steps:
7070
- name: Install dependencies (Alpine)
7171
if: matrix.platform.type == 'container'
72-
run: apk add --no-cache cmake make g++ zsh bash jq pipx git
72+
run: apk add --no-cache cmake make g++ zsh bash jq pipx git perl-utils
7373

7474
- name: Install pre-commit
7575
run: pipx install pre-commit

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ jobs:
6969

7070
- name: Install dependencies (Alpine)
7171
if: matrix.platform.type == 'container'
72-
run: apk add --no-cache cmake make g++ zsh bash jq shellcheck pipx git
72+
run: apk add --no-cache cmake make g++ zsh bash jq shellcheck pipx git perl-utils
7373

7474
- name: Install pre-commit
7575
run: pipx install pre-commit

DEPENDENCIES

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
vendorpull https://github.com/sourcemeta/vendorpull 1dcbac42809cf87cb5b045106b863e17ad84ba02
22
core https://github.com/sourcemeta/core 1f1d7951e85a8d20badd1a64f739cbdf8d2baff8
33
jsonbinpack https://github.com/sourcemeta/jsonbinpack 3898774a945ebf7392bad8a9015ead97a0518a19
4-
blaze https://github.com/sourcemeta/blaze 7019b65837396044116e21beecb264c47a2cd265
4+
blaze https://github.com/sourcemeta/blaze cb4ceae89411e939ae79d4cc6edf700e50efa93e
55
hydra https://github.com/sourcemeta/hydra c5f9542519bce7b6ac90ec8638329ef53aa46450
66
codegen https://github.com/sourcemeta/codegen 7733b3071cb140bc0d09406ebb9c3f306d71f7bf
77
ctrf https://github.com/ctrf-io/ctrf 93ea827d951390190171d37443bff169cf47c808

Dockerfile.test.alpine

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
FROM alpine:3.21
2-
RUN apk add --no-cache cmake make g++ zsh bash jq
2+
RUN apk add --no-cache cmake make g++ zsh bash jq perl-utils
33
WORKDIR /src
44
COPY CMakeLists.txt .
55
COPY cmake cmake

README.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,11 @@ documentation:
8686
- [`jsonschema codegen`](./docs/codegen.markdown) (for generating code from schemas)
8787
- [`jsonschema encode`](./docs/encode.markdown) (for binary compression)
8888
- [`jsonschema decode`](./docs/decode.markdown)
89+
- [`jsonschema install`](./docs/install.markdown) (for fetching external schema dependencies)
8990

9091
> See [`jsonschema.json`](./docs/configuration.markdown) for an _experimental_
9192
manifest for describing JSON Schema data models inspired by NPM's
92-
`package.json`.
93+
`package.json`, including dependency management.
9394

9495
Note that YAML is supported in most commands!
9596

completion/jsonschema.bash

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ _jsonschema() {
1111
previous=""
1212
fi
1313

14-
commands="validate metaschema compile test fmt lint bundle inspect canonicalize encode decode codegen version help"
14+
commands="validate metaschema compile test fmt lint bundle inspect canonicalize encode decode codegen install version help"
1515

16-
global_options="--verbose -v --resolve -r --default-dialect -d --json -j --http -h"
16+
global_options="--verbose -v --resolve -r --default-dialect -d --json -j --http -h --debug -g"
1717

1818
if [ "${COMP_CWORD}" -eq 1 ]
1919
then
@@ -173,6 +173,13 @@ _jsonschema() {
173173
COMPREPLY=( $(compgen -f -X '!*.json' -X '!*.yaml' -X '!*.yml' -- "${current}") )
174174
fi
175175
;;
176+
install)
177+
local options="--force -f"
178+
if [[ ${current} == -* ]]
179+
then
180+
COMPREPLY=( $(compgen -W "${options} ${global_options}" -- "${current}") )
181+
fi
182+
;;
176183
version|help)
177184
COMPREPLY=()
178185
;;

completion/jsonschema.zsh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ _jsonschema() {
1919
'encode:Encode JSON using JSON BinPack'
2020
'decode:Decode JSON using JSON BinPack'
2121
'codegen:Generate code from a JSON Schema'
22+
'install:Fetch and install external schema dependencies'
2223
'version:Print version information'
2324
'help:Print help information'
2425
)
@@ -30,6 +31,7 @@ _jsonschema() {
3031
'(--default-dialect -d)'{--default-dialect,-d}'[Specify default dialect URI]:dialect URI:_jsonschema_dialects'
3132
'(--json -j)'{--json,-j}'[Prefer JSON output if supported]'
3233
'(--http -h)'{--http,-h}'[Enable HTTP resolution]'
34+
'(--debug -g)'{--debug,-g}'[Enable debug output]'
3335
)
3436

3537
_arguments -C \
@@ -140,6 +142,11 @@ _jsonschema() {
140142
'(--target -t)'{--target,-t}'[Specify target language]:target:(typescript)' \
141143
'1:schema file:_files -g "*.json *.yaml *.yml"'
142144
;;
145+
install)
146+
_arguments \
147+
${global_options[@]} \
148+
'(--force -f)'{--force,-f}'[Re-fetch all dependencies]'
149+
;;
143150
version|help)
144151
;;
145152
esac

docs/configuration.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ describes the available configuration options:
5050
| `defaultDialect` | String | The default JSON Schema dialect to use when a schema doesn't specify `$schema` | - |
5151
| `extension` | String / String[] | The schema extension/s used by the project | `.json` / `.yaml` / `.yml` |
5252
| `resolve` | Object | A mapping of URIs to local file paths or other URIs for schema resolution remapping | `{}` |
53+
| `dependencies` | Object | A mapping of URIs to relative file paths for external schema dependencies to install (see [`jsonschema install`](./install.markdown)) | `{}` |
5354

5455
Lookup Algorithm
5556
----------------

docs/install.markdown

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
Installing Dependencies
2+
=======================
3+
4+
```sh
5+
jsonschema install
6+
[--force/-f] [--verbose/-v] [--debug/-g] [--json/-j]
7+
```
8+
9+
Many applications rely on consuming schemas authored and maintained by others.
10+
These schemas are typically published over HTTP(S) through registries like
11+
[schemas.sourcemeta.com](https://schemas.sourcemeta.com) (a free public
12+
registry) or self-hosted solutions like [Sourcemeta
13+
One](https://one.sourcemeta.com). While you could manually download these
14+
schemas or write a custom fetching script, doing so quickly gets complicated:
15+
schemas often reference other schemas that also need to be fetched, and the
16+
results need to be
17+
[bundled](https://json-schema.org/blog/posts/bundling-json-schema-compound-documents)
18+
to inline those references for local consumption. The `install` command solves
19+
this in a single step.
20+
21+
To get started, create a
22+
[`jsonschema.json`](./configuration.markdown) configuration file in your
23+
project and declare your dependencies as a mapping of schema URIs to local file
24+
paths. For example, to pull in the [JSON-RPC 2.0
25+
Response](https://schemas.sourcemeta.com/sourcemeta/std/v0/jsonrpc/v2.0/response)
26+
schema from the public registry:
27+
28+
```json
29+
{
30+
"dependencies": {
31+
"https://schemas.sourcemeta.com/sourcemeta/std/v0/jsonrpc/v2.0/response": "./vendor/response.json"
32+
}
33+
}
34+
```
35+
36+
Then run `jsonschema install`. Each dependency is fetched, bundled, and written
37+
to the specified path. A `jsonschema.lock.json` lock file is created alongside
38+
`jsonschema.json` to record the hash of each installed dependency. On
39+
subsequent runs, only dependencies that are missing, modified, or not yet
40+
tracked in the lock file are fetched again.
41+
42+
> [!TIP]
43+
> We recommend committing `jsonschema.lock.json` to version control (similar to
44+
> `package-lock.json`) to enable reproducible installs across environments.
45+
46+
> [!WARNING]
47+
> If a dependency uses a custom meta-schema that is itself an external
48+
> dependency, make sure to list both the meta-schema and the schema that uses
49+
> it in the `dependencies` map. The install command will resolve the
50+
> meta-schema during bundling regardless of processing order. We are working
51+
> on resolving this automatically in a future release.
52+
53+
Examples
54+
--------
55+
56+
### Install all dependencies
57+
58+
```sh
59+
jsonschema install
60+
```
61+
62+
### Force re-fetch all dependencies
63+
64+
```sh
65+
jsonschema install --force
66+
```
67+
68+
### Install with verbose output
69+
70+
```sh
71+
jsonschema install --verbose
72+
```

src/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ add_executable(jsonschema_cli
1212
command_decode.cc
1313
command_compile.cc
1414
command_canonicalize.cc
15-
command_codegen.cc)
15+
command_codegen.cc
16+
command_install.cc)
1617

1718
sourcemeta_add_default_options(PRIVATE jsonschema_cli)
1819
set_target_properties(jsonschema_cli PROPERTIES OUTPUT_NAME jsonschema)

0 commit comments

Comments
 (0)