Skip to content

Commit 8bc2005

Browse files
authored
Attempt to resolve file-based references without requiring --resolve (#430)
Fixes: #425 Signed-off-by: Juan Cruz Viotti <[email protected]>
1 parent d3d8d2f commit 8bc2005

File tree

5 files changed

+100
-4
lines changed

5 files changed

+100
-4
lines changed

src/error.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,25 @@ inline auto try_catch(const std::function<int()> &callback) noexcept -> int {
3737
error.path())
3838
.string()
3939
<< "\n";
40-
std::cerr << "\nThis is likely because you forgot to import such schema "
41-
"using --resolve/-r\n";
40+
41+
if (error.id().starts_with("file://")) {
42+
std::cerr << "\nThis is likely because the file does not exist\n";
43+
} else {
44+
std::cerr << "\nThis is likely because you forgot to import such schema "
45+
"using --resolve/-r\n";
46+
}
47+
4248
return EXIT_FAILURE;
4349
} catch (const sourcemeta::core::SchemaResolutionError &error) {
4450
std::cerr << "error: " << error.what() << "\n " << error.id() << "\n";
45-
std::cerr << "\nThis is likely because you forgot to import such schema "
46-
"using --resolve/-r\n";
51+
52+
if (error.id().starts_with("file://")) {
53+
std::cerr << "\nThis is likely because the file does not exist\n";
54+
} else {
55+
std::cerr << "\nThis is likely because you forgot to import such schema "
56+
"using --resolve/-r\n";
57+
}
58+
4759
return EXIT_FAILURE;
4860
} catch (const sourcemeta::core::SchemaUnknownDialectError &error) {
4961
std::cerr << "error: " << error.what() << "\n";

src/utils.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,17 @@ auto resolver(const std::map<std::string, std::vector<std::string>> &options,
308308
-> sourcemeta::core::SchemaResolver {
309309
sourcemeta::core::SchemaMapResolver dynamic_resolver{
310310
[remote, &options](std::string_view identifier) {
311+
const sourcemeta::core::URI uri{std::string{identifier}};
312+
if (uri.is_file()) {
313+
const auto path{uri.to_path()};
314+
log_verbose(options)
315+
<< "Attempting to read file reference from disk: "
316+
<< path.string() << "\n";
317+
if (std::filesystem::exists(path)) {
318+
return std::optional<sourcemeta::core::JSON>{read_file(path)};
319+
}
320+
}
321+
311322
if (remote) {
312323
return fallback_resolver(options, identifier);
313324
} else {

test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ add_jsonschema_test_unix(validate/pass_with_invalid_template)
9999
add_jsonschema_test_unix(validate/pass_with_invalid_template_verbose)
100100
add_jsonschema_test_unix(validate/pass_no_identifier_ref)
101101
add_jsonschema_test_unix(validate/pass_no_identifier_half_ref)
102+
add_jsonschema_test_unix(validate/pass_no_identifier_ref_without_resolve)
103+
add_jsonschema_test_unix(validate/fail_no_identifier_ref_without_resolve)
102104
add_jsonschema_test_unix(validate/fail_json)
103105
add_jsonschema_test_unix(validate/pass_json)
104106
add_jsonschema_test_unix(validate/pass_json_fast)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
cat << 'EOF' > "$TMP/schema.json"
11+
{
12+
"$schema": "https://json-schema.org/draft/2020-12/schema",
13+
"$ref": "./schemas/other.json"
14+
}
15+
EOF
16+
17+
cat << 'EOF' > "$TMP/instance.json"
18+
"foo bar"
19+
EOF
20+
21+
"$1" validate "$TMP/schema.json" "$TMP/instance.json" --verbose > "$TMP/output.txt" 2>&1 \
22+
&& CODE="$?" || CODE="$?"
23+
test "$CODE" = "1" || exit 1
24+
25+
cat << EOF > "$TMP/expected.txt"
26+
Attempting to read file reference from disk: $(realpath "$TMP")/schemas/other.json
27+
error: Could not resolve the reference to an external schema
28+
file://$(realpath "$TMP")/schemas/other.json
29+
30+
This is likely because the file does not exist
31+
EOF
32+
33+
diff "$TMP/output.txt" "$TMP/expected.txt"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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+
cat << 'EOF' > "$TMP/schema.json"
11+
{
12+
"$schema": "https://json-schema.org/draft/2020-12/schema",
13+
"$ref": "./schemas/other.json"
14+
}
15+
EOF
16+
17+
mkdir -p "$TMP/schemas"
18+
19+
cat << 'EOF' > "$TMP/schemas/other.json"
20+
{
21+
"$schema": "https://json-schema.org/draft/2020-12/schema",
22+
"type": "string"
23+
}
24+
EOF
25+
26+
cat << 'EOF' > "$TMP/instance.json"
27+
"foo bar"
28+
EOF
29+
30+
"$1" validate "$TMP/schema.json" "$TMP/instance.json" --verbose > "$TMP/output.txt" 2>&1
31+
32+
cat << EOF > "$TMP/expected.txt"
33+
Attempting to read file reference from disk: $(realpath "$TMP")/schemas/other.json
34+
ok: $(realpath "$TMP")/instance.json
35+
matches $(realpath "$TMP")/schema.json
36+
EOF
37+
38+
diff "$TMP/output.txt" "$TMP/expected.txt"

0 commit comments

Comments
 (0)