return "invalid-pkg-filesystem.html"; | return "invalid-pkg-filesystem.html"; | ||||
case errc::unknown_test_driver: | case errc::unknown_test_driver: | ||||
return "unknown-test-driver.html"; | return "unknown-test-driver.html"; | ||||
case errc::invalid_pkg_name: | |||||
case errc::invalid_pkg_id: | |||||
return "invalid-pkg-ident.html"; | |||||
case errc::sdist_exists: | |||||
return "sdist-exists.html"; | |||||
case errc::dependency_resolve_failure: | |||||
return "dep-res-failure.html"; | |||||
case errc::dup_lib_name: | |||||
return "dup-lib-name.html"; | |||||
case errc::unknown_usage_name: | |||||
return "unknown-usage.html"; | |||||
case errc::none: | case errc::none: | ||||
break; | break; | ||||
} | } | ||||
return R"( | return R"( | ||||
`dds` has a pre-defined set of built-in test drivers, and the one specified is | `dds` has a pre-defined set of built-in test drivers, and the one specified is | ||||
not recognized. Check the documentation for more information. | not recognized. Check the documentation for more information. | ||||
)"; | |||||
case errc::invalid_pkg_id: | |||||
return R"(Package IDs must follow a strict format of <name>@<version>.)"; | |||||
case errc::invalid_pkg_name: | |||||
return R"(Package names allow a limited set of characters and must not be empty.)"; | |||||
case errc::sdist_exists: | |||||
return R"( | |||||
By default, `dds` will not overwrite source distributions that already exist | |||||
(either in the repository or a filesystem path). Such an action could | |||||
potentially destroy important data. | |||||
)"; | |||||
case errc::dependency_resolve_failure: | |||||
return R"( | |||||
The dependency resolution algorithm failed to resolve the requirements of the | |||||
project. The algorithm's explanation should give enough information to infer | |||||
why there is no possible solution. You may need to reconsider your dependency | |||||
versions to avoid conflicts. | |||||
)"; | |||||
case errc::dup_lib_name: | |||||
return R"( | |||||
`dds` cannot build code correctly when there is more than one library that has | |||||
claimed the same name. It is possible that the duplicate name appears in a | |||||
dependency and is not an issue in your own project. Consult the output to see | |||||
which packages are claiming the library name. | |||||
)"; | |||||
case errc::unknown_usage_name: | |||||
return R"( | |||||
A `Uses` or `Links` field for a library specifies a library of an unknown name. | |||||
Check your spelling, and check that the package containing the library is | |||||
available, either from the `package.dds` or from the `INDEX.lmi` that was used | |||||
for the build. | |||||
)"; | )"; | ||||
case errc::none: | case errc::none: | ||||
break; | break; | ||||
case errc::invalid_pkg_filesystem: | case errc::invalid_pkg_filesystem: | ||||
return "The filesystem structure of the package/library is invalid. <- (Seeing this text " | return "The filesystem structure of the package/library is invalid. <- (Seeing this text " | ||||
"is a `dds` bug. Please report it.)"; | "is a `dds` bug. Please report it.)"; | ||||
case errc::invalid_pkg_id: | |||||
return "A package identifier is invalid <- (Seeing this text is a `dds` bug. Please " | |||||
"report it.)"; | |||||
case errc::invalid_pkg_name: | |||||
return "A package name is invalid <- (Seeing this text is a `dds` bug. Please report it.)"; | |||||
case errc::sdist_exists: | |||||
return "The source ditsribution already exists at the destination <- (Seeing this text is " | |||||
"a `dds` bug. Please report it.)"; | |||||
case errc::unknown_test_driver: | case errc::unknown_test_driver: | ||||
return "The specified Test-Driver is not known to `dds`"; | return "The specified Test-Driver is not known to `dds`"; | ||||
case errc::dependency_resolve_failure: | |||||
return "`dds` was unable to find a solution for the package dependencies given."; | |||||
case errc::dup_lib_name: | |||||
return "More than one library has claimed the same name."; | |||||
case errc::unknown_usage_name: | |||||
return "A `Uses` or `Links` field names a library that isn't recognized."; | |||||
case errc::none: | case errc::none: | ||||
break; | break; | ||||
} | } |
git_clone_failure, | git_clone_failure, | ||||
sdist_ident_mismatch, | sdist_ident_mismatch, | ||||
sdist_exists, | |||||
corrupted_build_db, | corrupted_build_db, | ||||
invalid_version_range_string, | invalid_version_range_string, | ||||
invalid_version_string, | invalid_version_string, | ||||
invalid_pkg_id, | |||||
invalid_pkg_name, | |||||
invalid_config_key, | invalid_config_key, | ||||
unknown_test_driver, | unknown_test_driver, | ||||
dependency_resolve_failure, | |||||
dup_lib_name, | |||||
unknown_usage_name, | |||||
invalid_lib_filesystem, | invalid_lib_filesystem, | ||||
invalid_pkg_filesystem, | invalid_pkg_filesystem, |
#include <dds/package/id.hpp> | #include <dds/package/id.hpp> | ||||
#include <dds/error/errors.hpp> | |||||
#include <spdlog/fmt/fmt.h> | #include <spdlog/fmt/fmt.h> | ||||
#include <tuple> | #include <tuple> | ||||
package_id package_id::parse(std::string_view s) { | package_id package_id::parse(std::string_view s) { | ||||
auto at_pos = s.find('@'); | auto at_pos = s.find('@'); | ||||
if (at_pos == s.npos) { | if (at_pos == s.npos) { | ||||
throw std::runtime_error(fmt::format("Invalid package ID string '{}'", s)); | |||||
throw_user_error<errc::invalid_pkg_id>("Invalid package ID '{}'", s); | |||||
} | } | ||||
auto name = s.substr(0, at_pos); | auto name = s.substr(0, at_pos); | ||||
: name(n) | : name(n) | ||||
, version(std::move(v)) { | , version(std::move(v)) { | ||||
if (name.find('@') != name.npos) { | if (name.find('@') != name.npos) { | ||||
throw std::runtime_error( | |||||
fmt::format("Invalid package name '{}' (The '@' character is not allowed)")); | |||||
throw_user_error<errc::invalid_pkg_name>( | |||||
"Invalid package name '{}' (The '@' character is not allowed)"); | |||||
} | } | ||||
} | } | ||||
lm_reject_dym{{"Name", "Namespace", "Version", "Depends", "Test-Driver"}}); | lm_reject_dym{{"Name", "Namespace", "Version", "Depends", "Test-Driver"}}); | ||||
if (ret.pkg_id.name.empty()) { | if (ret.pkg_id.name.empty()) { | ||||
throw std::runtime_error( | |||||
fmt::format("'Name' field in [{}] may not be an empty string", fpath.string())); | |||||
throw_user_error<errc::invalid_pkg_name>("'Name' field in [{}] may not be an empty string", | |||||
fpath.string()); | |||||
} | } | ||||
if (version_str.empty()) { | if (version_str.empty()) { | ||||
throw std::runtime_error( | |||||
fmt::format("'Version' field in [{}] may not be an empty string", fpath.string())); | |||||
throw_user_error< | |||||
errc::invalid_version_string>("'Version' field in [{}] may not be an empty string", | |||||
fpath.string()); | |||||
} | } | ||||
if (opt_test_driver) { | if (opt_test_driver) { | ||||
auto& test_driver_str = *opt_test_driver; | auto& test_driver_str = *opt_test_driver; |
#include "./repo.hpp" | #include "./repo.hpp" | ||||
#include <dds/catalog/catalog.hpp> | #include <dds/catalog/catalog.hpp> | ||||
#include <dds/error/errors.hpp> | |||||
#include <dds/solve/solve.hpp> | #include <dds/solve/solve.hpp> | ||||
#include <dds/source/dist.hpp> | #include <dds/source/dist.hpp> | ||||
#include <dds/util/paths.hpp> | #include <dds/util/paths.hpp> | ||||
auto msg = fmt::format("Source distribution '{}' is already available in the local repo", | auto msg = fmt::format("Source distribution '{}' is already available in the local repo", | ||||
sd.path.string()); | sd.path.string()); | ||||
if (ife_action == if_exists::throw_exc) { | if (ife_action == if_exists::throw_exc) { | ||||
throw std::runtime_error(msg); | |||||
throw_user_error<errc::sdist_exists>(msg); | |||||
} else if (ife_action == if_exists::ignore) { | } else if (ife_action == if_exists::ignore) { | ||||
spdlog::warn(msg); | spdlog::warn(msg); | ||||
return; | return; |
#include "./solve.hpp" | #include "./solve.hpp" | ||||
#include <dds/error/errors.hpp> | |||||
#include <pubgrub/solve.hpp> | #include <pubgrub/solve.hpp> | ||||
#include <range/v3/range/conversion.hpp> | #include <range/v3/range/conversion.hpp> | ||||
} catch (const solve_fail_exc& failure) { | } catch (const solve_fail_exc& failure) { | ||||
spdlog::error("Dependency resolution has failed! Explanation:"); | spdlog::error("Dependency resolution has failed! Explanation:"); | ||||
pubgrub::generate_explaination(failure, explainer()); | pubgrub::generate_explaination(failure, explainer()); | ||||
throw; | |||||
throw_user_error<errc::dependency_resolve_failure>(); | |||||
} | } | ||||
} | } |
auto dest = fs::absolute(params.dest_path); | auto dest = fs::absolute(params.dest_path); | ||||
if (fs::exists(dest)) { | if (fs::exists(dest)) { | ||||
if (!params.force) { | if (!params.force) { | ||||
throw std::runtime_error( | |||||
fmt::format("Destination path '{}' already exists", dest.string())); | |||||
throw_user_error<errc::sdist_exists>("Destination path '{}' already exists", | |||||
dest.string()); | |||||
} | } | ||||
} | } | ||||
#include "./usage_reqs.hpp" | #include "./usage_reqs.hpp" | ||||
#include <dds/build/plan/compile_file.hpp> | #include <dds/build/plan/compile_file.hpp> | ||||
#include <dds/error/errors.hpp> | |||||
#include <dds/util/algo.hpp> | #include <dds/util/algo.hpp> | ||||
#include <spdlog/fmt/fmt.h> | #include <spdlog/fmt/fmt.h> | ||||
auto pair = std::pair(library_key{ns, name}, lm::library{}); | auto pair = std::pair(library_key{ns, name}, lm::library{}); | ||||
auto [inserted, did_insert] = _reqs.try_emplace(library_key{ns, name}, lm::library()); | auto [inserted, did_insert] = _reqs.try_emplace(library_key{ns, name}, lm::library()); | ||||
if (!did_insert) { | if (!did_insert) { | ||||
throw std::runtime_error( | |||||
fmt::format("More than one library is registered as {}/{}", ns, name)); | |||||
throw_user_error<errc::dup_lib_name>("More than one library is registered as `{}/{}'", | |||||
ns, | |||||
name); | |||||
} | } | ||||
return inserted->second; | return inserted->second; | ||||
} | } | ||||
std::vector<fs::path> usage_requirement_map::link_paths(const lm::usage& key) const { | std::vector<fs::path> usage_requirement_map::link_paths(const lm::usage& key) const { | ||||
auto req = get(key); | auto req = get(key); | ||||
if (!req) { | if (!req) { | ||||
throw std::runtime_error( | |||||
fmt::format("Unable to find linking requirement '{}/{}'", key.namespace_, key.name)); | |||||
throw_user_error<errc::unknown_usage_name>("Unable to find linking requirement '{}/{}'", | |||||
key.namespace_, | |||||
key.name); | |||||
} | } | ||||
std::vector<fs::path> ret; | std::vector<fs::path> ret; | ||||
if (req->linkable_path) { | if (req->linkable_path) { | ||||
std::vector<fs::path> ret; | std::vector<fs::path> ret; | ||||
auto lib = get(usage.namespace_, usage.name); | auto lib = get(usage.namespace_, usage.name); | ||||
if (!lib) { | if (!lib) { | ||||
throw std::runtime_error( | |||||
fmt::format("Cannot find non-existent usage requirements for '{}/{}'", | |||||
usage.namespace_, | |||||
usage.name)); | |||||
throw_user_error< | |||||
errc::unknown_usage_name>("Cannot find non-existent usage requirements for '{}/{}'", | |||||
usage.namespace_, | |||||
usage.name); | |||||
} | } | ||||
extend(ret, lib->include_paths); | extend(ret, lib->include_paths); | ||||
for (const auto& transitive : lib->uses) { | for (const auto& transitive : lib->uses) { |