|
|
@@ -4,7 +4,7 @@ |
|
|
|
#include <dds/util/string.hpp> |
|
|
|
|
|
|
|
#include <json5/parse_data.hpp> |
|
|
|
#include <semester/decomp.hpp> |
|
|
|
#include <semester/walk.hpp> |
|
|
|
|
|
|
|
#include <spdlog/fmt/fmt.h> |
|
|
|
|
|
|
@@ -40,46 +40,27 @@ dependency_manifest dependency_manifest::from_file(path_ref fpath) { |
|
|
|
auto data = json5::parse_data(content); |
|
|
|
|
|
|
|
dependency_manifest depman; |
|
|
|
using namespace semester::decompose_ops; |
|
|
|
auto res = semester::decompose( |
|
|
|
using namespace semester::walk_ops; |
|
|
|
auto res = walk.try_walk( // |
|
|
|
data, |
|
|
|
try_seq{ |
|
|
|
require_type<json5::data::mapping_type>{ |
|
|
|
"The root of a dependency manifest must be an object (mapping)"}, |
|
|
|
mapping{ |
|
|
|
if_key{"$schema", just_accept}, |
|
|
|
if_key{"depends", |
|
|
|
require_type<json5::data::mapping_type>{ |
|
|
|
"`depends` must be a mapping between package names and version ranges"}, |
|
|
|
mapping{[&](auto pkg_name, const json5::data& range_str_) { |
|
|
|
if (!range_str_.is_string()) { |
|
|
|
throw_user_error<errc::invalid_pkg_manifest>( |
|
|
|
"Issue in dependency manifest: Dependency for '{}' must be a " |
|
|
|
"range string", |
|
|
|
pkg_name); |
|
|
|
} |
|
|
|
try { |
|
|
|
auto rng = semver::range::parse_restricted(range_str_.as_string()); |
|
|
|
dependency dep{std::string(pkg_name), {rng.low(), rng.high()}}; |
|
|
|
depman.dependencies.push_back(std::move(dep)); |
|
|
|
} catch (const semver::invalid_range&) { |
|
|
|
throw_user_error<errc::invalid_version_range_string>( |
|
|
|
"Invalid version range string '{}' in dependency declaration " |
|
|
|
"for '{}'", |
|
|
|
range_str_.as_string(), |
|
|
|
pkg_name); |
|
|
|
} |
|
|
|
return semester::dc_accept; |
|
|
|
}}}, |
|
|
|
[&](auto key, auto&&) { |
|
|
|
return semester::dc_reject_t{ |
|
|
|
fmt::format("Unknown key `{}` in dependency manifest", key)}; |
|
|
|
}}, |
|
|
|
require_type<json5::data::mapping_type>{ |
|
|
|
"The root of a dependency manifest must be a JSON object"}, |
|
|
|
mapping{ |
|
|
|
required_key{ |
|
|
|
"depends", |
|
|
|
"A 'depends' key is required", |
|
|
|
require_type<json5::data::array_type>{"'depends' must be an array of strings"}, |
|
|
|
for_each{ |
|
|
|
require_type<std::string>{"Each dependency should be a string"}, |
|
|
|
put_into(std::back_inserter(depman.dependencies), |
|
|
|
[](const std::string& str) { |
|
|
|
return dependency::parse_depends_string(str); |
|
|
|
}), |
|
|
|
}, |
|
|
|
}, |
|
|
|
}); |
|
|
|
auto rej = std::get_if<semester::dc_reject_t>(&res); |
|
|
|
if (rej) { |
|
|
|
throw_user_error<errc::invalid_pkg_manifest>(rej->message); |
|
|
|
} |
|
|
|
|
|
|
|
res.throw_if_rejected<user_error<errc::invalid_pkg_manifest>>(); |
|
|
|
|
|
|
|
return depman; |
|
|
|
} |