Skip to content

Commit b87e546

Browse files
committed
Support extension in jsonschema.json
Signed-off-by: Juan Cruz Viotti <[email protected]>
1 parent eb00206 commit b87e546

File tree

13 files changed

+250
-4
lines changed

13 files changed

+250
-4
lines changed

DEPENDENCIES

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
vendorpull https://github.com/sourcemeta/vendorpull 1dcbac42809cf87cb5b045106b863e17ad84ba02
2-
core https://github.com/sourcemeta/core 7072e2109db2d1ca504c3ceab7a61dcf1397aaee
2+
core https://github.com/sourcemeta/core 626949ede75fb77ac4a919a24af0ade6f776751d
33
jsonbinpack https://github.com/sourcemeta/jsonbinpack abd40e41050d14d74af1fddb5c397de5cca3b13c
44
blaze https://github.com/sourcemeta/blaze 53d6ba77c26e613b2803f044c2852d4441bfb0a1
55
hydra https://github.com/sourcemeta/hydra af9f2c54709d620872ead0c3f8f683c15a0fa702

docs/configuration.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ describes the available configuration options:
4848
| `baseUri` | String | The base URI for your schemas (**not used in this CLI yet**) | - |
4949
| `path` | String | Relative path to the directory containing your schemas | Directory containing `jsonschema.json` |
5050
| `defaultDialect` | String | The default JSON Schema dialect to use when a schema doesn't specify `$schema` | - |
51+
| `extension` | String / String[] | The schema extension/s used by the project | `.json` / `.yaml` / `.yml` |
5152
| `resolve` | Object | A mapping of URIs to local file paths or other URIs for schema resolution remapping | `{}` |
5253

5354
Lookup Algorithm

src/input.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <sourcemeta/core/json.h>
66
#include <sourcemeta/core/jsonpointer.h>
77
#include <sourcemeta/core/options.h>
8+
#include <sourcemeta/core/schemaconfig.h>
89
#include <sourcemeta/core/yaml.h>
910

1011
#include "configuration.h"
@@ -30,13 +31,14 @@ struct InputJSON {
3031
}
3132
};
3233

33-
inline auto parse_extensions(const sourcemeta::core::Options &options)
34+
inline auto parse_extensions(
35+
const sourcemeta::core::Options &options,
36+
const std::optional<sourcemeta::core::SchemaConfig> &configuration)
3437
-> std::set<std::string> {
3538
std::set<std::string> result;
3639

3740
if (options.contains("extension")) {
3841
for (const auto &extension : options.at("extension")) {
39-
LOG_VERBOSE(options) << "Using extension: " << extension << "\n";
4042
if (extension.starts_with('.')) {
4143
result.emplace(extension);
4244
} else {
@@ -47,6 +49,22 @@ inline auto parse_extensions(const sourcemeta::core::Options &options)
4749
}
4850
}
4951

52+
if (configuration.has_value()) {
53+
for (const auto &extension : configuration.value().extension) {
54+
if (extension.starts_with('.')) {
55+
result.emplace(extension);
56+
} else {
57+
std::ostringstream normalised_extension;
58+
normalised_extension << '.' << extension;
59+
result.emplace(normalised_extension.str());
60+
}
61+
}
62+
}
63+
64+
for (const auto &extension : result) {
65+
LOG_VERBOSE(options) << "Using extension: " << extension << "\n";
66+
}
67+
5068
if (result.empty()) {
5169
result.insert({".json"});
5270
result.insert({".yaml"});
@@ -131,18 +149,19 @@ inline auto for_each_json(const std::vector<std::string_view> &arguments,
131149
const sourcemeta::core::Options &options)
132150
-> std::vector<InputJSON> {
133151
const auto blacklist{parse_ignore(options)};
134-
const auto extensions{parse_extensions(options)};
135152
std::vector<InputJSON> result;
136153

137154
if (arguments.empty()) {
138155
const auto current_path{std::filesystem::current_path()};
139156
const auto configuration_path{find_configuration(current_path)};
140157
const auto &configuration{read_configuration(options, configuration_path)};
158+
const auto extensions{parse_extensions(options, configuration)};
141159
handle_json_entry(configuration.has_value()
142160
? configuration.value().absolute_path
143161
: current_path,
144162
blacklist, extensions, result);
145163
} else {
164+
const auto extensions{parse_extensions(options, std::nullopt)};
146165
for (const auto &entry : arguments) {
147166
handle_json_entry(entry, blacklist, extensions, result);
148167
}

test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ add_jsonschema_test_unix(format/pass_check_single_indentation)
4949
add_jsonschema_test_unix(format/pass_single_indentation)
5050
add_jsonschema_test_unix(format/pass_single_intact_mtime)
5151
add_jsonschema_test_unix(format/pass_config_path)
52+
add_jsonschema_test_unix(format/pass_config_path_custom_extension)
53+
add_jsonschema_test_unix(format/pass_config_path_custom_extension_union)
5254
add_jsonschema_test_unix(format/fail_no_dialect)
5355
add_jsonschema_test_unix(format/fail_unknown_metaschema)
5456
add_jsonschema_test_unix(format/pass_default_dialect)

test/format/pass_config_path.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ cd "$TMP/bar"
3030

3131
cat << EOF > "$TMP/expected.txt"
3232
Using configuration file: $(realpath "$TMP")/jsonschema.json
33+
Using extension: .json
34+
Using extension: .yaml
35+
Using extension: .yml
3336
Formatting: $(realpath "$TMP")/foo/schema.json
3437
EOF
3538

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/bin/sh
2+
3+
set -o errexit
4+
set -o nounset
5+
6+
TMP="$(mktemp -d)"
7+
clean() { rm -rf "$TMP"; }
8+
trap clean EXIT
9+
10+
mkdir -p "$TMP/foo"
11+
mkdir -p "$TMP/bar"
12+
13+
# This file should be formatted (matches .schema.json extension)
14+
cat << 'EOF' > "$TMP/foo/example.schema.json"
15+
{
16+
"$schema": "https://json-schema.org/draft/2020-12/schema",
17+
"additionalProperties": false,
18+
"title": "Hello World",
19+
"properties": {"foo": {}, "bar": {}}
20+
}
21+
EOF
22+
23+
# This file should NOT be formatted (only .json, not .schema.json)
24+
cat << 'EOF' > "$TMP/foo/other.json"
25+
{
26+
"$schema": "https://json-schema.org/draft/2020-12/schema",
27+
"additionalProperties": false,
28+
"title": "Other",
29+
"properties": {"foo": {}, "bar": {}}
30+
}
31+
EOF
32+
33+
cat << 'EOF' > "$TMP/jsonschema.json"
34+
{
35+
"path": "./foo",
36+
"extension": ".schema.json"
37+
}
38+
EOF
39+
40+
cd "$TMP/bar"
41+
"$1" fmt --verbose >"$TMP/output.txt" 2>&1
42+
43+
cat << EOF > "$TMP/expected.txt"
44+
Using configuration file: $(realpath "$TMP")/jsonschema.json
45+
Using extension: .schema.json
46+
Formatting: $(realpath "$TMP")/foo/example.schema.json
47+
EOF
48+
49+
diff "$TMP/output.txt" "$TMP/expected.txt"
50+
51+
cat << 'EOF' > "$TMP/expected.json"
52+
{
53+
"$schema": "https://json-schema.org/draft/2020-12/schema",
54+
"title": "Hello World",
55+
"properties": {
56+
"foo": {},
57+
"bar": {}
58+
},
59+
"additionalProperties": false
60+
}
61+
EOF
62+
63+
diff "$TMP/foo/example.schema.json" "$TMP/expected.json"
64+
65+
cat << 'EOF' > "$TMP/expected_other.json"
66+
{
67+
"$schema": "https://json-schema.org/draft/2020-12/schema",
68+
"additionalProperties": false,
69+
"title": "Other",
70+
"properties": {"foo": {}, "bar": {}}
71+
}
72+
EOF
73+
74+
diff "$TMP/foo/other.json" "$TMP/expected_other.json"
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/bin/sh
2+
3+
set -o errexit
4+
set -o nounset
5+
6+
TMP="$(mktemp -d)"
7+
clean() { rm -rf "$TMP"; }
8+
trap clean EXIT
9+
10+
mkdir -p "$TMP/foo"
11+
mkdir -p "$TMP/bar"
12+
13+
# This file should be formatted (matches .schema.json from config)
14+
cat << 'EOF' > "$TMP/foo/example.schema.json"
15+
{
16+
"$schema": "https://json-schema.org/draft/2020-12/schema",
17+
"additionalProperties": false,
18+
"title": "Schema JSON",
19+
"properties": {"foo": {}, "bar": {}}
20+
}
21+
EOF
22+
23+
# This file should be formatted (matches .my.json from --extension)
24+
cat << 'EOF' > "$TMP/foo/example.my.json"
25+
{
26+
"$schema": "https://json-schema.org/draft/2020-12/schema",
27+
"additionalProperties": false,
28+
"title": "My JSON",
29+
"properties": {"foo": {}, "bar": {}}
30+
}
31+
EOF
32+
33+
# This file should NOT be formatted (only .json, not .schema.json or .my.json)
34+
cat << 'EOF' > "$TMP/foo/other.json"
35+
{
36+
"$schema": "https://json-schema.org/draft/2020-12/schema",
37+
"additionalProperties": false,
38+
"title": "Other",
39+
"properties": {"foo": {}, "bar": {}}
40+
}
41+
EOF
42+
43+
cat << 'EOF' > "$TMP/jsonschema.json"
44+
{
45+
"path": "./foo",
46+
"extension": ".schema.json"
47+
}
48+
EOF
49+
50+
cd "$TMP/bar"
51+
"$1" fmt --verbose --extension .my.json >"$TMP/output.txt" 2>&1
52+
53+
cat << EOF > "$TMP/expected.txt"
54+
Using configuration file: $(realpath "$TMP")/jsonschema.json
55+
Using extension: .my.json
56+
Using extension: .schema.json
57+
Formatting: $(realpath "$TMP")/foo/example.my.json
58+
Formatting: $(realpath "$TMP")/foo/example.schema.json
59+
EOF
60+
61+
diff "$TMP/output.txt" "$TMP/expected.txt"
62+
63+
cat << 'EOF' > "$TMP/expected_schema.json"
64+
{
65+
"$schema": "https://json-schema.org/draft/2020-12/schema",
66+
"title": "Schema JSON",
67+
"properties": {
68+
"foo": {},
69+
"bar": {}
70+
},
71+
"additionalProperties": false
72+
}
73+
EOF
74+
75+
diff "$TMP/foo/example.schema.json" "$TMP/expected_schema.json"
76+
77+
cat << 'EOF' > "$TMP/expected_my.json"
78+
{
79+
"$schema": "https://json-schema.org/draft/2020-12/schema",
80+
"title": "My JSON",
81+
"properties": {
82+
"foo": {},
83+
"bar": {}
84+
},
85+
"additionalProperties": false
86+
}
87+
EOF
88+
89+
diff "$TMP/foo/example.my.json" "$TMP/expected_my.json"
90+
91+
cat << 'EOF' > "$TMP/expected_other.json"
92+
{
93+
"$schema": "https://json-schema.org/draft/2020-12/schema",
94+
"additionalProperties": false,
95+
"title": "Other",
96+
"properties": {"foo": {}, "bar": {}}
97+
}
98+
EOF
99+
100+
diff "$TMP/foo/other.json" "$TMP/expected_other.json"

test/lint/pass_config_path.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ cd "$TMP/bar"
3333

3434
cat << EOF > "$TMP/expected.txt"
3535
Using configuration file: $(realpath "$TMP")/jsonschema.json
36+
Using extension: .json
37+
Using extension: .yaml
38+
Using extension: .yml
3639
Linting: $(realpath "$TMP")/foo/schema.json
3740
EOF
3841

test/metaschema/fail_config_path_enoent.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ test "$CODE" = "1" || exit 1
2121

2222
cat << EOF > "$TMP/expected.txt"
2323
Using configuration file: $(realpath "$TMP")/jsonschema.json
24+
Using extension: .json
25+
Using extension: .yaml
26+
Using extension: .yml
2427
error: No such file or directory
2528
at file path $(realpath "$TMP")/nonexistent
2629
EOF

test/metaschema/pass_config_path.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ cd "$TMP/bar"
2828

2929
cat << EOF > "$TMP/expected.txt"
3030
Using configuration file: $(realpath "$TMP")/jsonschema.json
31+
Using extension: .json
32+
Using extension: .yaml
33+
Using extension: .yml
3134
ok: $(realpath "$TMP")/foo/schema.json
3235
matches http://json-schema.org/draft-04/schema#
3336
EOF

0 commit comments

Comments
 (0)