Skip to content

Commit

Permalink
Support YAML input in most commands (#212)
Browse files Browse the repository at this point in the history
Fixes: #91
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti authored Jan 15, 2025
1 parent e1a31da commit 777c3da
Show file tree
Hide file tree
Showing 22 changed files with 400 additions and 7 deletions.
2 changes: 2 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ documentation:
- [`jsonschema encode`](./docs/encode.markdown) (for binary compression)
- [`jsonschema decode`](./docs/decode.markdown)

Note that YAML is supported in most commands!

Installation
------------

Expand Down
2 changes: 1 addition & 1 deletion docs/bundle.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Bundling
========

```sh
jsonschema bundle <schema.json>
jsonschema bundle <schema.json|.yaml>
[--http/-h] [--verbose/-v] [--resolve/-r <schemas-or-directories> ...]
[--extension/-e <extension>] [--ignore/-i <schemas-or-directories>]
[--without-id/-w]
Expand Down
2 changes: 2 additions & 0 deletions docs/format.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ conventions. Just as code-formatters like
`fmt` command to format schemas based on industry-standard conventions and to
check their adherence on a continuous integration environment.

**This command does not support YAML schemas yet.**

Examples
--------

Expand Down
2 changes: 1 addition & 1 deletion docs/frame.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Framing
=======

```sh
jsonschema frame <schema.json> [--json/-j] [--verbose/-v]
jsonschema frame <schema.json|.yaml> [--json/-j] [--verbose/-v]
```

To evaluate a schema, an implementation will first scan it to determine the
Expand Down
2 changes: 2 additions & 0 deletions docs/lint.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ automatically fix many of them.
> not related to APIs. If you are working with JSON Schema for API
> specifications, you should make use of both linters together!
**The `--fix/-f` option is not supported when passing YAML schemas.**

Examples
--------

Expand Down
2 changes: 1 addition & 1 deletion docs/validate.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Validating
> JSON Schema Draft 3 and older are not supported at this point in time.
```sh
jsonschema validate <schema.json> <instance.json|.jsonl...> [--http/-h]
jsonschema validate <schema.json|.yaml> <instance.json|.jsonl|.yaml...> [--http/-h]
[--verbose/-v] [--resolve/-r <schemas-or-directories> ...] [--benchmark/-b]
[--extension/-e <extension>] [--ignore/-i <schemas-or-directories>] [--trace/-t]
```
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ target_link_libraries(jsonschema_cli PRIVATE sourcemeta::jsontoolkit::uri)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::jsontoolkit::json)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::jsontoolkit::jsonl)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::jsontoolkit::jsonschema)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::jsontoolkit::yaml)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::alterschema::engine)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::alterschema::linter)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::hydra::httpclient)
Expand Down
6 changes: 6 additions & 0 deletions src/command_fmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ auto sourcemeta::jsonschema::cli::fmt(

for (const auto &entry : for_each_json(options.at(""), parse_ignore(options),
parse_extensions(options))) {
if (entry.first.extension() == ".yaml" ||
entry.first.extension() == ".yml") {
std::cerr << "This command does not support YAML input files yet\n";
return EXIT_FAILURE;
}

if (options.contains("c") || options.contains("check")) {
log_verbose(options) << "Checking: " << entry.first.string() << "\n";
std::ifstream input{entry.first};
Expand Down
6 changes: 6 additions & 0 deletions src/command_lint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ auto sourcemeta::jsonschema::cli::lint(
for_each_json(options.at(""), parse_ignore(options),
parse_extensions(options))) {
log_verbose(options) << "Linting: " << entry.first.string() << "\n";
if (entry.first.extension() == ".yaml" ||
entry.first.extension() == ".yml") {
std::cerr << "The --fix option is not supported for YAML input files\n";
return EXIT_FAILURE;
}

auto copy = entry.second;
bundle.apply(copy, sourcemeta::jsontoolkit::default_schema_walker,
resolver(options));
Expand Down
8 changes: 5 additions & 3 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Global Options:
Commands:
validate <schema.json> <instance.json|.jsonl...> [--http/-h]
validate <schema.json|.yaml> <instance.json|.jsonl|.yaml...> [--http/-h]
[--benchmark/-b] [--extension/-e <extension>]
[--ignore/-i <schemas-or-directories>] [--trace/-t]
Expand All @@ -43,19 +43,21 @@ Global Options:
[--ignore/-i <schemas-or-directories>]
Format the input schemas in-place or check they are formatted.
This command does not support YAML schemas yet.
lint [schemas-or-directories...] [--fix/-f] [--extension/-e <extension>]
[--ignore/-i <schemas-or-directories>]
Lint the input schemas and potentially fix the reported issues.
The --fix/-f option is not supported when passing YAML schemas.
bundle <schema.json> [--http/-h] [--extension/-e <extension>]
bundle <schema.json|.yaml> [--http/-h] [--extension/-e <extension>]
[--ignore/-i <schemas-or-directories>] [--without-id/-w]
Perform JSON Schema Bundling on a schema to inline remote references,
printing the result to standard output.
frame <schema.json> [--json/-j]
frame <schema.json|.yaml> [--json/-j]
Statically analyse a schema to display schema locations and
references in a human-readable manner.
Expand Down
9 changes: 8 additions & 1 deletion src/utils.cc
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include <sourcemeta/hydra/httpclient.h>

#include <sourcemeta/jsontoolkit/json.h>
#include <sourcemeta/jsontoolkit/jsonschema.h>
#include <sourcemeta/jsontoolkit/uri.h>
#include <sourcemeta/jsontoolkit/yaml.h>

#include "utils.h"

Expand Down Expand Up @@ -106,7 +108,10 @@ namespace sourcemeta::jsonschema::cli {

auto read_file(const std::filesystem::path &path)
-> sourcemeta::jsontoolkit::JSON {
// TODO: Extend to support YAML
if (path.extension() == ".yaml" || path.extension() == ".yml") {
return sourcemeta::jsontoolkit::from_yaml(path);
}

return sourcemeta::jsontoolkit::from_file(path);
}

Expand Down Expand Up @@ -329,6 +334,8 @@ auto parse_extensions(

if (result.empty()) {
result.insert({".json"});
result.insert({".yaml"});
result.insert({".yml"});
}

return result;
Expand Down
10 changes: 10 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ add_jsonschema_test_unix(format_invalid_path)
add_jsonschema_test_unix(format_directory)
add_jsonschema_test_unix(format_cwd)
add_jsonschema_test_unix(format_multi_extension)
add_jsonschema_test_unix(format_yaml)
add_jsonschema_test_unix(format_check_yaml)
add_jsonschema_test_unix(format_check_single_fail)
add_jsonschema_test_unix(format_check_single_pass)
add_jsonschema_test_unix(format_directory_ignore_directory)
Expand Down Expand Up @@ -71,12 +73,14 @@ add_jsonschema_test_unix(validate/pass_many)
add_jsonschema_test_unix(validate/pass_many_verbose)
add_jsonschema_test_unix(validate/fail_many)
add_jsonschema_test_unix(validate/fail_many_verbose)
add_jsonschema_test_unix(validate/fail_yaml)

# Metaschema
add_jsonschema_test_unix(metaschema/pass_trace)
add_jsonschema_test_unix(metaschema/fail_trace)
add_jsonschema_test_unix(metaschema/fail_directory)
add_jsonschema_test_unix(metaschema/fail_single)
add_jsonschema_test_unix(metaschema/fail_yaml)
add_jsonschema_test_unix(metaschema/fail_non_schema)
add_jsonschema_test_unix(metaschema/pass_cwd)
add_jsonschema_test_unix(metaschema/pass_single)
Expand Down Expand Up @@ -109,6 +113,7 @@ add_jsonschema_test_unix(test/fail_test_case_non_boolean_valid)
add_jsonschema_test_unix(test/fail_true_resolve_fragment)
add_jsonschema_test_unix(test/pass_empty)
add_jsonschema_test_unix(test/pass_empty_verbose)
add_jsonschema_test_unix(test/pass_single_yaml)
add_jsonschema_test_unix(test/pass_single_resolve)
add_jsonschema_test_unix(test/pass_single_resolve_verbose)
add_jsonschema_test_unix(test/pass_single_resolve_fragment)
Expand All @@ -127,6 +132,7 @@ add_jsonschema_test_unix(bundle/pass_resolve_directory)
add_jsonschema_test_unix(bundle/pass_resolve_directory_verbose)
add_jsonschema_test_unix(bundle/pass_resolve_metaschema)
add_jsonschema_test_unix(bundle/pass_resolve_single)
add_jsonschema_test_unix(bundle/pass_resolve_yaml)
add_jsonschema_test_unix(bundle/pass_resolve_with_ignore)
add_jsonschema_test_unix(bundle/pass_without_id)
add_jsonschema_test_unix(bundle/pass_without_id_verbose)
Expand All @@ -140,6 +146,7 @@ add_jsonschema_test_unix(bundle/fail_unknown_metaschema)

# Frame
add_jsonschema_test_unix(frame/pass)
add_jsonschema_test_unix(frame/pass_yaml)
add_jsonschema_test_unix(frame/fail_no_schema)
add_jsonschema_test_unix(frame/fail_schema_invalid_json)
add_jsonschema_test_unix(frame/fail_unknown_metaschema)
Expand All @@ -148,6 +155,9 @@ add_jsonschema_test_unix(frame/fail_unknown_metaschema)
add_jsonschema_test_unix(lint/pass_lint_fix)
add_jsonschema_test_unix(lint/pass_lint_no_fix)
add_jsonschema_test_unix(lint/fail_lint)
add_jsonschema_test_unix(lint/fail_lint_yaml)
add_jsonschema_test_unix(lint/fail_lint_fix_yaml)
add_jsonschema_test_unix(lint/fail_lint_fix_yml)

# Encode
add_jsonschema_test_unix(encode/pass_schema_less)
Expand Down
42 changes: 42 additions & 0 deletions test/bundle/pass_resolve_yaml.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << 'EOF' > "$TMP/schema.yaml"
$schema: https://json-schema.org/draft/2020-12/schema
$id: https://example.com
$ref: nested
EOF

cat << 'EOF' > "$TMP/remote.yaml"
$schema: https://json-schema.org/draft/2020-12/schema
$id: https://example.com/nested
type: string
EOF

"$1" bundle "$TMP/schema.yaml" --resolve "$TMP/remote.yaml" > "$TMP/result.json"

cat << 'EOF' > "$TMP/expected.json"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com",
"$ref": "nested",
"$defs": {
"https://example.com/nested": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/nested",
"type": "string"
}
}
}
EOF

diff "$TMP/result.json" "$TMP/expected.json"

# Must come out formatted
"$1" fmt "$TMP/result.json" --check
22 changes: 22 additions & 0 deletions test/format_check_yaml.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << 'EOF' > "$TMP/schema.yaml"
type: 1
$schema: http://json-schema.org/draft-04/schema#
EOF

"$1" fmt "$TMP/schema.yaml" --check 2>"$TMP/stderr.txt" && CODE="$?" || CODE="$?"
test "$CODE" = "1" || exit 1

cat << EOF > "$TMP/error.txt"
This command does not support YAML input files yet
EOF

diff "$TMP/stderr.txt" "$TMP/error.txt"
29 changes: 29 additions & 0 deletions test/format_yaml.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << 'EOF' > "$TMP/schema.yaml"
additionalProperties: false
title: Hello World
EOF

"$1" fmt "$TMP/schema.yaml" 2>"$TMP/stderr.txt" && CODE="$?" || CODE="$?"
test "$CODE" = "1" || exit 1

cat << EOF > "$TMP/error.txt"
This command does not support YAML input files yet
EOF

diff "$TMP/stderr.txt" "$TMP/error.txt"

cat << EOF > "$TMP/expected.yaml"
additionalProperties: false
title: Hello World
EOF

diff "$TMP/schema.yaml" "$TMP/expected.yaml"
88 changes: 88 additions & 0 deletions test/frame/pass_yaml.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << 'EOF' > "$TMP/schema.yaml"
$schema: https://json-schema.org/draft/2020-12/schema
$id: https://example.com
$ref: '#/$defs/string'
$defs:
string: { type: string }
EOF

"$1" frame "$TMP/schema.yaml" > "$TMP/result.txt"

cat << 'EOF' > "$TMP/expected.txt"
(LOCATION) URI: https://example.com
Type : Static
Schema : https://example.com
Pointer :
Base URI : https://example.com
Relative Pointer :
Dialect : https://json-schema.org/draft/2020-12/schema
Base Dialect : https://json-schema.org/draft/2020-12/schema
(POINTER) URI: https://example.com#/$defs
Type : Static
Schema : https://example.com
Pointer : /$defs
Base URI : https://example.com
Relative Pointer : /$defs
Dialect : https://json-schema.org/draft/2020-12/schema
Base Dialect : https://json-schema.org/draft/2020-12/schema
(SUBSCHEMA) URI: https://example.com#/$defs/string
Type : Static
Schema : https://example.com
Pointer : /$defs/string
Base URI : https://example.com
Relative Pointer : /$defs/string
Dialect : https://json-schema.org/draft/2020-12/schema
Base Dialect : https://json-schema.org/draft/2020-12/schema
(POINTER) URI: https://example.com#/$defs/string/type
Type : Static
Schema : https://example.com
Pointer : /$defs/string/type
Base URI : https://example.com
Relative Pointer : /$defs/string/type
Dialect : https://json-schema.org/draft/2020-12/schema
Base Dialect : https://json-schema.org/draft/2020-12/schema
(POINTER) URI: https://example.com#/$id
Type : Static
Schema : https://example.com
Pointer : /$id
Base URI : https://example.com
Relative Pointer : /$id
Dialect : https://json-schema.org/draft/2020-12/schema
Base Dialect : https://json-schema.org/draft/2020-12/schema
(POINTER) URI: https://example.com#/$ref
Type : Static
Schema : https://example.com
Pointer : /$ref
Base URI : https://example.com
Relative Pointer : /$ref
Dialect : https://json-schema.org/draft/2020-12/schema
Base Dialect : https://json-schema.org/draft/2020-12/schema
(POINTER) URI: https://example.com#/$schema
Type : Static
Schema : https://example.com
Pointer : /$schema
Base URI : https://example.com
Relative Pointer : /$schema
Dialect : https://json-schema.org/draft/2020-12/schema
Base Dialect : https://json-schema.org/draft/2020-12/schema
(REFERENCE) URI: /$ref
Type : Static
Destination : https://example.com#/$defs/string
- (w/o fragment) : https://example.com
- (fragment) : /$defs/string
(REFERENCE) URI: /$schema
Type : Static
Destination : https://json-schema.org/draft/2020-12/schema
- (w/o fragment) : https://json-schema.org/draft/2020-12/schema
EOF

diff "$TMP/result.txt" "$TMP/expected.txt"
Loading

0 comments on commit 777c3da

Please sign in to comment.