Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/bundle.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ jsonschema bundle <schema.json|.yaml>
[--resolve/-r <schemas-or-directories> ...]
[--extension/-e <extension>] [--ignore/-i <schemas-or-directories>]
[--without-id/-w] [--default-dialect/-d <uri>] [--json/-j]
[--indentation/-n <spaces>]
[--configuration/-C <path>] [--color auto|always|never]
```

Expand All @@ -25,6 +26,9 @@ to resolve remote references in advance and inline them into the given schema
for local consumption or further distribution. The JSON Schema CLI supports
this functionality through the `bundle` command.

Use `--indentation/-n` to set how many spaces each level of nesting of the
result is laid out with, which defaults to two.

> [!WARNING]
> A popular use case for JSON Schema is providing auto-completion for code
> editors. If you plan to use your bundled schema for this, keep in mind that
Expand Down
5 changes: 4 additions & 1 deletion docs/upgrade.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jsonschema upgrade <schema.json|.yaml> [--to/-t draft4|draft6|draft7|2019-09|202
[--header/-H "<name>: <value>"]
[--resolve/-r <schemas-or-directories> ...]
[--default-dialect/-d <uri>] [--configuration/-C <path>]
[--color auto|always|never]
[--indentation/-n <spaces>] [--color auto|always|never]
```

> [!NOTE]
Expand All @@ -21,6 +21,9 @@ specifications into account, including re-writing references that point at
locations whose path has changed. By default, schemas are upgraded to the
latest supported dialect, and the result is printed to standard output.

Use `--indentation/-n` to set how many spaces each level of nesting of the
result is laid out with, which defaults to two.

For example, consider the following Draft 3 schema:

```json
Expand Down
3 changes: 2 additions & 1 deletion src/command_bundle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ auto sourcemeta::jsonschema::bundle(const sourcemeta::core::Options &options)
}

validate_http_headers(options);
const auto indentation{parse_indentation(options)};

const std::filesystem::path schema_path{options.positional().front()};
const bool schema_from_stdin = (schema_path == "-");
Expand Down Expand Up @@ -118,6 +119,6 @@ auto sourcemeta::jsonschema::bundle(const sourcemeta::core::Options &options)
schema_display_path, error.what());
}

sourcemeta::core::prettify(schema, std::cout);
sourcemeta::core::prettify(schema, std::cout, indentation);
std::cout << "\n";
}
3 changes: 2 additions & 1 deletion src/command_upgrade.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ auto sourcemeta::jsonschema::upgrade(const sourcemeta::core::Options &options)
const auto target_value{options.contains("to") ? options.at("to").front()
: std::string_view{"2020-12"}};
const auto target_dialect{parse_target_dialect(target_value)};
const auto indentation{parse_indentation(options)};

const std::filesystem::path schema_path{options.positional().front()};
const bool schema_from_stdin = (schema_path == "-");
Expand Down Expand Up @@ -197,6 +198,6 @@ auto sourcemeta::jsonschema::upgrade(const sourcemeta::core::Options &options)

sourcemeta::jsonschema::format_schema(schema, custom_resolver, dialect);

sourcemeta::core::prettify(schema, std::cout);
sourcemeta::core::prettify(schema, std::cout, indentation);
std::cout << "\n";
}
11 changes: 11 additions & 0 deletions src/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,13 @@ class InvalidJobsError : public std::runtime_error {
: std::runtime_error{"The --jobs option must be a positive integer"} {}
};

class InvalidIndentationError : public std::runtime_error {
public:
InvalidIndentationError()
: std::runtime_error{
"The --indentation option must be a non-negative integer"} {}
};

class InvalidLintRuleError : public std::runtime_error {
public:
InvalidLintRuleError(const std::string &message, std::string rule)
Expand Down Expand Up @@ -1652,6 +1659,10 @@ inline auto try_catch(const sourcemeta::core::Options &options,
const auto is_json{options.contains("json")};
print_exception(is_json, error);
return EXIT_INVALID_CLI_ARGUMENTS;
} catch (const InvalidIndentationError &error) {
const auto is_json{options.contains("json")};
print_exception(is_json, error);
return EXIT_INVALID_CLI_ARGUMENTS;
} catch (const InvalidOptionEnumerationValueError &error) {
const auto is_json{options.contains("json")};
print_exception(is_json, error);
Expand Down
4 changes: 4 additions & 0 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ constexpr std::string_view USAGE_COMMANDS{R"EOF( version / --version / -v

upgrade <schema.json|.yaml>
[--to/-t draft4|draft6|draft7|2019-09|2020-12]
[--indentation/-n <spaces>]

Upgrade the given schema to a newer JSON Schema dialect.
Defaults to the latest dialect (2020-12). Schemas that declare a
Expand All @@ -125,6 +126,7 @@ constexpr std::string_view USAGE_COMMANDS{R"EOF( version / --version / -v

bundle <schema.json|.yaml> [--extension/-e <extension>]
[--ignore/-i <schemas-or-directories>] [--without-id/-w]
[--indentation/-n <spaces>]

Perform JSON Schema Bundling on a schema to inline remote references,
printing the result to standard output.
Expand Down Expand Up @@ -283,6 +285,7 @@ auto jsonschema_main(const std::string &program, const std::string &command,
app.flag("without-id", {"w"});
app.option("extension", {"e"});
app.option("ignore", {"i"});
app.option("indentation", {"n"});
parse_options(app, argc, argv, {.skip = 1});
sourcemeta::jsonschema::bundle(app);
return EXIT_SUCCESS;
Expand Down Expand Up @@ -387,6 +390,7 @@ auto jsonschema_main(const std::string &program, const std::string &command,

if (command == "upgrade") {
app.option("to", {"t"});
app.option("indentation", {"n"});
parse_options(app, argc, argv, {.skip = 1});
sourcemeta::jsonschema::upgrade(app);
return EXIT_SUCCESS;
Expand Down
17 changes: 14 additions & 3 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,22 @@ inline auto parse_jobs(const sourcemeta::core::Options &options)

inline auto parse_indentation(const sourcemeta::core::Options &options)
-> std::size_t {
if (options.contains("indentation")) {
return std::stoull(std::string{options.at("indentation").front()});
if (!options.contains("indentation")) {
return 2;
}

return 2;
const std::string value{options.at("indentation").front()};
if (value.empty() || !std::ranges::all_of(value, [](const char character) {
return std::isdigit(static_cast<unsigned char>(character));
})) {
throw InvalidIndentationError{};
}

try {
return std::stoull(value);
} catch (const std::out_of_range &) {
throw InvalidIndentationError{};
}
}

inline auto format_assertion_tweaks(const sourcemeta::core::Options &options)
Expand Down
6 changes: 6 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ add_jsonschema_test(format/pass_yaml_anchor_without_alias)
add_jsonschema_test(format/pass_yaml_anchors_keep_ordering)
add_jsonschema_test(format/pass_yaml_keep_ordering)
add_jsonschema_test(format/pass_yaml_indentation)
add_jsonschema_test(format/fail_invalid_indentation)
add_jsonschema_test(format/pass_yaml_intact_mtime)
add_jsonschema_test(format/pass_yaml_stdin)
add_jsonschema_test(format/pass_yaml_directory)
Expand Down Expand Up @@ -682,6 +683,8 @@ add_jsonschema_test(bundle/pass_2020_12_http)
add_jsonschema_test(bundle/pass_resolve_single_default_dialect)
add_jsonschema_test(bundle/pass_boolean_schema_default_dialect)
add_jsonschema_test(bundle/pass_resolve_yaml)
add_jsonschema_test(bundle/pass_indentation)
add_jsonschema_test(bundle/fail_invalid_indentation)
add_jsonschema_test(bundle/pass_resolve_with_ignore)
add_jsonschema_test(bundle/pass_resolve_no_identifier)
add_jsonschema_test(bundle/pass_without_id)
Expand Down Expand Up @@ -874,6 +877,7 @@ add_jsonschema_test(lint/fail_lint_openapi_version)
add_jsonschema_test(lint/fail_lint_openapi_version_newer)
add_jsonschema_test(lint/fail_lint_openapi_version_malformed)
add_jsonschema_test(lint/fail_lint_openapi_version_not_a_string)
add_jsonschema_test(lint/fail_lint_invalid_indentation)
add_jsonschema_test(lint/fail_lint)
add_jsonschema_test(lint/fail_lint_color_always)
add_jsonschema_test(lint/fail_lint_color_never)
Expand Down Expand Up @@ -1209,6 +1213,8 @@ add_jsonschema_test(upgrade/pass_default_dialect)
add_jsonschema_test(upgrade/pass_configuration_option)
add_jsonschema_test(upgrade/pass_resolve)
add_jsonschema_test(upgrade/pass_yaml_input)
add_jsonschema_test(upgrade/pass_indentation)
add_jsonschema_test(upgrade/fail_invalid_indentation)
add_jsonschema_test(upgrade/pass_embedded_resources)
add_jsonschema_test(upgrade/fail_custom_metaschema_root)
add_jsonschema_test(upgrade/fail_custom_metaschema_nested)
Expand Down
27 changes: 27 additions & 0 deletions test/bundle/fail_invalid_indentation.clitest
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
WRITE schema.json UNTIL EOF
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com",
"$ref": "nested"
}
EOF

// Invalid CLI arguments
RUN bundle schema.json --indentation abc STDIN /dev/null IN . INTO result_0.txt EXPECTING 5

WRITE expected_0.txt UNTIL EOF
2> error: The --indentation option must be a non-negative integer
EOF

COMPARE result_0.txt AGAINST expected_0.txt

// Invalid CLI arguments
RUN bundle schema.json --indentation abc --json STDIN /dev/null IN . INTO result_1.txt EXPECTING 5

WRITE expected_1.txt UNTIL EOF
1> {
1> "error": "The --indentation option must be a non-negative integer"
1> }
EOF

COMPARE result_1.txt AGAINST expected_1.txt
34 changes: 34 additions & 0 deletions test/bundle/pass_indentation.clitest
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
WRITE schema.json UNTIL EOF
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com",
"$ref": "nested"
}
EOF

WRITE remote.json UNTIL EOF
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/nested",
"type": "string"
}
EOF

RUN bundle schema.json --resolve remote.json --indentation 4 STDIN /dev/null IN . INTO result.txt EXPECTING 0

WRITE expected.txt UNTIL EOF
1> {
1> "$schema": "https://json-schema.org/draft/2020-12/schema",
1> "$id": "https://example.com",
1> "$ref": "nested",
1> "$defs": {
1> "https://example.com/nested": {
1> "$schema": "https://json-schema.org/draft/2020-12/schema",
1> "$id": "https://example.com/nested",
1> "type": "string"
1> }
1> }
1> }
EOF

COMPARE result.txt AGAINST expected.txt
26 changes: 26 additions & 0 deletions test/format/fail_invalid_indentation.clitest
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
WRITE schema.json UNTIL EOF
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "string"
}
EOF

// Invalid CLI arguments
RUN fmt schema.json --indentation abc STDIN /dev/null IN . INTO result_0.txt EXPECTING 5

WRITE expected_0.txt UNTIL EOF
2> error: The --indentation option must be a non-negative integer
EOF

COMPARE result_0.txt AGAINST expected_0.txt

// Invalid CLI arguments
RUN fmt schema.json --indentation abc --json STDIN /dev/null IN . INTO result_1.txt EXPECTING 5

WRITE expected_1.txt UNTIL EOF
1> {
1> "error": "The --indentation option must be a non-negative integer"
1> }
EOF

COMPARE result_1.txt AGAINST expected_1.txt
2 changes: 2 additions & 0 deletions test/help_command.clitest
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ WRITE expected.txt UNTIL EOF
1>
1> upgrade <schema.json|.yaml>
1> [--to/-t draft4|draft6|draft7|2019-09|2020-12]
1> [--indentation/-n <spaces>]
1>
1> Upgrade the given schema to a newer JSON Schema dialect.
1> Defaults to the latest dialect (2020-12). Schemas that declare a
Expand All @@ -135,6 +136,7 @@ WRITE expected.txt UNTIL EOF
1>
1> bundle <schema.json|.yaml> [--extension/-e <extension>]
1> [--ignore/-i <schemas-or-directories>] [--without-id/-w]
1> [--indentation/-n <spaces>]
1>
1> Perform JSON Schema Bundling on a schema to inline remote references,
1> printing the result to standard output.
Expand Down
2 changes: 2 additions & 0 deletions test/help_option_long.clitest
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ WRITE expected.txt UNTIL EOF
1>
1> [ANSI_BOLD_CYAN]upgrade[ANSI_RESET] <schema.json|.yaml>
1> [--to/-t draft4|draft6|draft7|2019-09|2020-12]
1> [--indentation/-n <spaces>]
1>
1> Upgrade the given schema to a newer JSON Schema dialect.
1> Defaults to the latest dialect (2020-12). Schemas that declare a
Expand All @@ -126,6 +127,7 @@ WRITE expected.txt UNTIL EOF
1>
1> [ANSI_BOLD_CYAN]bundle[ANSI_RESET] <schema.json|.yaml> [--extension/-e <extension>]
1> [--ignore/-i <schemas-or-directories>] [--without-id/-w]
1> [--indentation/-n <spaces>]
1>
1> Perform JSON Schema Bundling on a schema to inline remote references,
1> printing the result to standard output.
Expand Down
2 changes: 2 additions & 0 deletions test/help_option_short.clitest
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ WRITE expected.txt UNTIL EOF
1>
1> upgrade <schema.json|.yaml>
1> [--to/-t draft4|draft6|draft7|2019-09|2020-12]
1> [--indentation/-n <spaces>]
1>
1> Upgrade the given schema to a newer JSON Schema dialect.
1> Defaults to the latest dialect (2020-12). Schemas that declare a
Expand All @@ -123,6 +124,7 @@ WRITE expected.txt UNTIL EOF
1>
1> bundle <schema.json|.yaml> [--extension/-e <extension>]
1> [--ignore/-i <schemas-or-directories>] [--without-id/-w]
1> [--indentation/-n <spaces>]
1>
1> Perform JSON Schema Bundling on a schema to inline remote references,
1> printing the result to standard output.
Expand Down
26 changes: 26 additions & 0 deletions test/lint/fail_lint_invalid_indentation.clitest
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
WRITE schema.json UNTIL EOF
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "string"
}
EOF

// Invalid CLI arguments
RUN lint schema.json --indentation abc STDIN /dev/null IN . INTO result_0.txt EXPECTING 5

WRITE expected_0.txt UNTIL EOF
2> error: The --indentation option must be a non-negative integer
EOF

COMPARE result_0.txt AGAINST expected_0.txt

// Invalid CLI arguments
RUN lint schema.json --indentation abc --json STDIN /dev/null IN . INTO result_1.txt EXPECTING 5

WRITE expected_1.txt UNTIL EOF
1> {
1> "error": "The --indentation option must be a non-negative integer"
1> }
EOF

COMPARE result_1.txt AGAINST expected_1.txt
26 changes: 26 additions & 0 deletions test/upgrade/fail_invalid_indentation.clitest
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
WRITE schema.json UNTIL EOF
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string"
}
EOF

// Invalid CLI arguments
RUN upgrade schema.json --indentation abc STDIN /dev/null IN . INTO result_0.txt EXPECTING 5

WRITE expected_0.txt UNTIL EOF
2> error: The --indentation option must be a non-negative integer
EOF

COMPARE result_0.txt AGAINST expected_0.txt

// Invalid CLI arguments
RUN upgrade schema.json --indentation abc --json STDIN /dev/null IN . INTO result_1.txt EXPECTING 5

WRITE expected_1.txt UNTIL EOF
1> {
1> "error": "The --indentation option must be a non-negative integer"
1> }
EOF

COMPARE result_1.txt AGAINST expected_1.txt
Loading
Loading