From c877c33fa76a2e7471592c271965251ad9f4381c Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Tue, 9 Jun 2026 17:55:28 -0400 Subject: [PATCH 1/2] WIP Signed-off-by: Juan Cruz Viotti --- src/configuration/include/sourcemeta/blaze/configuration.h | 1 + src/configuration/parse.cc | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/configuration/include/sourcemeta/blaze/configuration.h b/src/configuration/include/sourcemeta/blaze/configuration.h index e8bab468b..4c772494a 100644 --- a/src/configuration/include/sourcemeta/blaze/configuration.h +++ b/src/configuration/include/sourcemeta/blaze/configuration.h @@ -57,6 +57,7 @@ struct SOURCEMETA_BLAZE_CONFIGURATION_EXPORT Configuration { bool absolute_path_explicit{false}; std::filesystem::path base_path; sourcemeta::core::JSON::String base; + sourcemeta::core::URI base_uri; std::optional default_dialect; std::unordered_set extension{".json", ".yml", ".yaml"}; diff --git a/src/configuration/parse.cc b/src/configuration/parse.cc index 59fa7b6e8..9035cffdd 100644 --- a/src/configuration/parse.cc +++ b/src/configuration/parse.cc @@ -100,6 +100,7 @@ auto Configuration::from_json(const sourcemeta::core::JSON &value, } result.base = base.recompose(); + result.base_uri = std::move(base); } catch (const sourcemeta::core::URIParseError &) { CONFIGURATION_ENSURE(false, "The baseUri property must represent a valid URI", @@ -107,8 +108,8 @@ auto Configuration::from_json(const sourcemeta::core::JSON &value, } } else { // Otherwise the base is the directory - result.base = - sourcemeta::core::URI::from_path(result.absolute_path).recompose(); + result.base_uri = sourcemeta::core::URI::from_path(result.absolute_path); + result.base = result.base_uri.recompose(); } result.default_dialect = From 062adde30b48438bd7eccbc0c606ee5946f3012a Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Tue, 9 Jun 2026 17:57:38 -0400 Subject: [PATCH 2/2] Add the `Configuration` base as a pre-parsed URI as `base_uri` Signed-off-by: Juan Cruz Viotti --- src/configuration/parse.cc | 9 +++---- .../configuration_add_dependency_test.cc | 6 +++++ test/configuration/configuration_json_test.cc | 27 +++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/configuration/parse.cc b/src/configuration/parse.cc index 9035cffdd..bce6980f5 100644 --- a/src/configuration/parse.cc +++ b/src/configuration/parse.cc @@ -92,15 +92,14 @@ auto Configuration::from_json(const sourcemeta::core::JSON &value, if (value.defines("baseUri")) { try { - sourcemeta::core::URI base{value.at("baseUri").to_string()}; - base.canonicalize(); - if (!base.is_absolute()) { + result.base_uri = sourcemeta::core::URI{value.at("baseUri").to_string()}; + result.base_uri.canonicalize(); + if (!result.base_uri.is_absolute()) { CONFIGURATION_ENSURE( false, "The baseUri property must be an absolute URI", {"baseUri"}); } - result.base = base.recompose(); - result.base_uri = std::move(base); + result.base = result.base_uri.recompose(); } catch (const sourcemeta::core::URIParseError &) { CONFIGURATION_ENSURE(false, "The baseUri property must represent a valid URI", diff --git a/test/configuration/configuration_add_dependency_test.cc b/test/configuration/configuration_add_dependency_test.cc index 8f57c0267..e6f2c18e2 100644 --- a/test/configuration/configuration_add_dependency_test.cc +++ b/test/configuration/configuration_add_dependency_test.cc @@ -10,6 +10,7 @@ TEST(Configuration_add_dependency, single) { sourcemeta::blaze::Configuration config; config.absolute_path = "/test/schemas"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.add_dependency("https://json-schema.org/draft/2020-12/schema", std::filesystem::path{"/test/vendor/2020-12.json"}); @@ -26,6 +27,7 @@ TEST(Configuration_add_dependency, multiple) { sourcemeta::blaze::Configuration config; config.absolute_path = "/test/schemas"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.add_dependency("https://json-schema.org/draft/2020-12/schema", std::filesystem::path{"/test/vendor/2020-12.json"}); @@ -47,6 +49,7 @@ TEST(Configuration_add_dependency, duplicate_uri) { sourcemeta::blaze::Configuration config; config.absolute_path = "/test/schemas"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.add_dependency("https://json-schema.org/draft/2020-12/schema", std::filesystem::path{"/test/vendor/2020-12.json"}); @@ -69,6 +72,7 @@ TEST(Configuration_add_dependency, uri_is_canonicalised) { sourcemeta::blaze::Configuration config; config.absolute_path = "/test/schemas"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.add_dependency("HTTP://Example.COM:80/draft/2020-12/schema", std::filesystem::path{"/test/vendor/2020-12.json"}); @@ -84,6 +88,7 @@ TEST(Configuration_add_dependency, duplicate_uri_after_canonicalisation) { sourcemeta::blaze::Configuration config; config.absolute_path = "/test/schemas"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.add_dependency("http://example.com/schema.json", std::filesystem::path{"/test/vendor/first.json"}); @@ -105,6 +110,7 @@ TEST(Configuration_add_dependency, duplicate_path) { sourcemeta::blaze::Configuration config; config.absolute_path = "/test/schemas"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.add_dependency("https://json-schema.org/draft/2020-12/schema", std::filesystem::path{"/test/vendor/schema.json"}); diff --git a/test/configuration/configuration_json_test.cc b/test/configuration/configuration_json_test.cc index 4ce7538ee..18311a8da 100644 --- a/test/configuration/configuration_json_test.cc +++ b/test/configuration/configuration_json_test.cc @@ -2,6 +2,7 @@ #include #include +#include #include "configuration_test_utils.h" @@ -39,6 +40,7 @@ TEST(Configuration_json, read_json_valid_1) { EXPECT_EQ(manifest.absolute_path, std::filesystem::path{"/test"} / "schemas"); EXPECT_TRUE(manifest.absolute_path_explicit); EXPECT_EQ(manifest.base, "https://schemas.sourcemeta.com"); + EXPECT_EQ(manifest.base_uri.recompose(), "https://schemas.sourcemeta.com"); EXPECT_TRUE(manifest.default_dialect.has_value()); EXPECT_EQ(manifest.default_dialect.value(), "http://json-schema.org/draft-07/schema#"); @@ -71,11 +73,27 @@ TEST(Configuration_json, read_json_valid_without_path) { EXPECT_EQ(manifest.absolute_path, std::filesystem::path{"/test"}); EXPECT_FALSE(manifest.absolute_path_explicit); EXPECT_EQ(manifest.base, "https://example.com"); + EXPECT_EQ(manifest.base_uri.recompose(), "https://example.com"); EXPECT_FALSE(manifest.default_dialect.has_value()); EXPECT_EQ(manifest.resolve.size(), 0); EXPECT_EQ(manifest.extra.size(), 0); } +TEST(Configuration_json, read_json_base_uri_defaults_to_absolute_path) { + std::unordered_map files; + files["/test/blaze.json"] = R"JSON({ + "path": "./schemas" + })JSON"; + + const auto manifest{sourcemeta::blaze::Configuration::read_json( + "/test/blaze.json", MAKE_READER(files))}; + + EXPECT_EQ(manifest.absolute_path, std::filesystem::path{"/test"} / "schemas"); + EXPECT_TRUE(manifest.absolute_path_explicit); + EXPECT_EQ(manifest.base, "file:///test/schemas"); + EXPECT_EQ(manifest.base_uri.recompose(), "file:///test/schemas"); +} + TEST(Configuration_json, to_json_all_fields) { sourcemeta::blaze::Configuration config; config.title = "Sourcemeta"; @@ -87,6 +105,7 @@ TEST(Configuration_json, to_json_all_fields) { config.absolute_path_explicit = true; config.base_path = "/test/schemas"; config.base = "https://schemas.sourcemeta.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.default_dialect = "http://json-schema.org/draft-07/schema#"; config.extension = {".json", ".yaml"}; config.resolve.emplace("https://other.com/single.json", "../single.json"); @@ -122,6 +141,7 @@ TEST(Configuration_json, to_json_minimal) { config.absolute_path = "/test"; config.absolute_path_explicit = true; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; const auto result{config.to_json()}; @@ -148,6 +168,7 @@ TEST(Configuration_json, to_json_with_extra) { config.absolute_path = "/test"; config.absolute_path_explicit = true; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.extra.assign("x-foo", sourcemeta::core::JSON{"bar"}); const auto result{config.to_json()}; @@ -286,6 +307,7 @@ TEST(Configuration_json, to_json_with_lint_rules) { config.absolute_path_explicit = true; config.base_path = "/test"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.lint.rules.emplace_back("/test/rules/my-rule.json"); config.lint.rules.emplace_back("/test/rules/other-rule.json"); @@ -308,6 +330,7 @@ TEST(Configuration_json, to_json_with_lint_rules_parent) { config.absolute_path_explicit = true; config.base_path = "/test"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.lint.rules.emplace_back("/other/rules/my-rule.json"); const auto result{config.to_json()}; @@ -327,6 +350,7 @@ TEST(Configuration_json, to_json_empty_lint) { sourcemeta::blaze::Configuration config; config.absolute_path = "/test"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; const auto result{config.to_json()}; @@ -374,6 +398,7 @@ TEST(Configuration_json, to_json_with_ignore) { config.absolute_path_explicit = true; config.base_path = "/test"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.ignore.emplace_back("/test/vendor"); config.ignore.emplace_back("/test/build"); @@ -394,6 +419,7 @@ TEST(Configuration_json, to_json_with_ignore_parent) { config.absolute_path_explicit = true; config.base_path = "/test"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; config.ignore.emplace_back("/other/vendor"); const auto result{config.to_json()}; @@ -411,6 +437,7 @@ TEST(Configuration_json, to_json_empty_ignore) { sourcemeta::blaze::Configuration config; config.absolute_path = "/test"; config.base = "https://example.com"; + config.base_uri = sourcemeta::core::URI{config.base}; const auto result{config.to_json()};