| sqlite3::exec(new_dep_st, | sqlite3::exec(new_dep_st, | ||||
| std::forward_as_tuple(db_pkg_id, | std::forward_as_tuple(db_pkg_id, | ||||
| dep.name, | dep.name, | ||||
| dep.version.to_string(), | |||||
| "[placeholder]")); | |||||
| dep.version_range.low().to_string(), | |||||
| dep.version_range.high().to_string())); | |||||
| } | } | ||||
| } | } | ||||
| assert(git_url); | assert(git_url); | ||||
| assert(git_ref); | assert(git_ref); | ||||
| auto deps = sqlite3::exec_iter<std::string, std::string>( // | |||||
| _stmt_cache, | |||||
| R"( | |||||
| SELECT dep_name, low | |||||
| FROM dds_cat_pkg_deps | |||||
| WHERE pkg_id = ? | |||||
| )"_sql, | |||||
| std::tie(pkg_id)) | |||||
| | ranges::views::transform([](auto&& pair) { | |||||
| const auto& [name, ver] = pair; | |||||
| return dependency{name, semver::version::parse(ver)}; | |||||
| }) // | |||||
| | ranges::to_vector; | |||||
| auto deps = dependencies_of(pk_id); | |||||
| return package_info{ | return package_info{ | ||||
| pk_id, | pk_id, | ||||
| deps, | |||||
| std::move(deps), | |||||
| git_remote_listing{ | git_remote_listing{ | ||||
| *git_url, | *git_url, | ||||
| *git_ref, | *git_ref, | ||||
| std::vector<dependency> catalog::dependencies_of(const package_id& pkg) const noexcept { | std::vector<dependency> catalog::dependencies_of(const package_id& pkg) const noexcept { | ||||
| return sqlite3::exec_iter<std::string, | return sqlite3::exec_iter<std::string, | ||||
| std::string, | |||||
| std::string>( // | std::string>( // | ||||
| _stmt_cache, | _stmt_cache, | ||||
| R"( | R"( | ||||
| FROM dds_cat_pkgs | FROM dds_cat_pkgs | ||||
| WHERE name = ? AND version = ? | WHERE name = ? AND version = ? | ||||
| ) | ) | ||||
| SELECT dep_name, low | |||||
| SELECT dep_name, low, high | |||||
| FROM dds_cat_pkg_deps | FROM dds_cat_pkg_deps | ||||
| WHERE pkg_id IN this_pkg_id | WHERE pkg_id IN this_pkg_id | ||||
| ORDER BY dep_name | ORDER BY dep_name | ||||
| )"_sql, | )"_sql, | ||||
| std::forward_as_tuple(pkg.name, pkg.version.to_string())) // | std::forward_as_tuple(pkg.name, pkg.version.to_string())) // | ||||
| | ranges::views::transform([](auto&& pair) { | | ranges::views::transform([](auto&& pair) { | ||||
| auto& [name, ver] = pair; | |||||
| return dependency{name, semver::version::parse(ver)}; | |||||
| auto& [name, low, high] = pair; | |||||
| return dependency{name, | |||||
| semver::range(semver::version::parse(low), | |||||
| semver::version::parse(high))}; | |||||
| }) // | }) // | ||||
| | ranges::to_vector; | | ranges::to_vector; | ||||
| } | } | ||||
| dep_name)); | dep_name)); | ||||
| info.deps.push_back({ | info.deps.push_back({ | ||||
| std::string(dep_name), | std::string(dep_name), | ||||
| semver::version::parse(std::string(dep_version)), | |||||
| semver::range::parse(std::string(dep_version)), | |||||
| }); | }); | ||||
| } | } | ||||
| db.store(dds::package_info{ | db.store(dds::package_info{ | ||||
| dds::package_id{"foo", semver::version::parse("1.2.3")}, | dds::package_id{"foo", semver::version::parse("1.2.3")}, | ||||
| { | { | ||||
| {"bar", semver::version::parse("1.2.5")}, | |||||
| {"baz", semver::version::parse("5.3.2")}, | |||||
| {"bar", semver::range::parse("=1.2.5")}, | |||||
| {"baz", semver::range::parse("^5.3.2")}, | |||||
| }, | }, | ||||
| dds::git_remote_listing{"http://example.com", "master", std::nullopt}, | dds::git_remote_listing{"http://example.com", "master", std::nullopt}, | ||||
| }); | }); | ||||
| "foo": { | "foo": { | ||||
| "1.2.3": { | "1.2.3": { | ||||
| "depends": { | "depends": { | ||||
| "bar": "4.2.1" | |||||
| "bar": "~4.2.1" | |||||
| }, | }, | ||||
| "git": { | "git": { | ||||
| "url": "http://example.com", | "url": "http://example.com", | ||||
| auto deps = db.dependencies_of(pkgs[0]); | auto deps = db.dependencies_of(pkgs[0]); | ||||
| REQUIRE(deps.size() == 1); | REQUIRE(deps.size() == 1); | ||||
| CHECK(deps[0].name == "bar"); | CHECK(deps[0].name == "bar"); | ||||
| CHECK(deps[0].version == semver::version::parse("4.2.1")); | |||||
| CHECK(deps[0].version_range == semver::range::parse("~4.2.1")); | |||||
| } | } |
| std::vector<dds::dependency> deps; | std::vector<dds::dependency> deps; | ||||
| for (const auto& dep : this->deps.Get()) { | for (const auto& dep : this->deps.Get()) { | ||||
| auto dep_id = dds::package_id::parse(dep); | auto dep_id = dds::package_id::parse(dep); | ||||
| deps.push_back({dep_id.name, dep_id.version}); | |||||
| assert(false && "TODO"); | |||||
| // deps.push_back({dep_id.name, dep_id.version}); | |||||
| } | } | ||||
| dds::package_info info{ident, std::move(deps), {}}; | dds::package_info info{ident, std::move(deps), {}}; | ||||
| int run() { | int run() { | ||||
| const auto man = parent.load_package_manifest(); | const auto man = parent.load_package_manifest(); | ||||
| for (const auto& dep : man.dependencies) { | for (const auto& dep : man.dependencies) { | ||||
| std::cout << dep.name << " " << dep.version.to_string() << '\n'; | |||||
| std::cout << dep.name << " " << dep.version_range.to_string() << '\n'; | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| dds::repo_flags::write_lock | dds::repo_flags::create_if_absent, | dds::repo_flags::write_lock | dds::repo_flags::create_if_absent, | ||||
| [&](dds::repository repo) { | [&](dds::repository repo) { | ||||
| for (auto& dep : man.dependencies) { | for (auto& dep : man.dependencies) { | ||||
| auto exists = !!repo.find(dep.name, dep.version); | |||||
| if (!exists) { | |||||
| spdlog::info("Pull remote: {}@{}", dep.name, dep.version.to_string()); | |||||
| auto opt_pkg = catalog.get(dds::package_id{dep.name, dep.version}); | |||||
| if (opt_pkg) { | |||||
| auto tsd = dds::get_package_sdist(*opt_pkg); | |||||
| repo.add_sdist(tsd.sdist, dds::if_exists::ignore); | |||||
| } else { | |||||
| spdlog::error("No remote listing for {}@{}", | |||||
| dep.name, | |||||
| dep.version.to_string()); | |||||
| failed = true; | |||||
| } | |||||
| } else { | |||||
| spdlog::info("Okay: {} {}", dep.name, dep.version.to_string()); | |||||
| } | |||||
| assert(false && "Not ready yet"); | |||||
| // auto exists = !!repo.find(dep.name, dep.version_range); | |||||
| // if (!exists) { | |||||
| // spdlog::info("Pull remote: {}@{}", dep.name, | |||||
| // dep.version_range.to_string()); auto opt_pkg = | |||||
| // catalog.get(dds::package_id{dep.name, dep.version_range}); if | |||||
| // (opt_pkg) { | |||||
| // auto tsd = dds::get_package_sdist(*opt_pkg); | |||||
| // repo.add_sdist(tsd.sdist, dds::if_exists::ignore); | |||||
| // } else { | |||||
| // spdlog::error("No remote listing for {}@{}", | |||||
| // dep.name, | |||||
| // dep.version_range.to_string()); | |||||
| // failed = true; | |||||
| // } | |||||
| // } else { | |||||
| // spdlog::info("Okay: {} {}", dep.name, dep.version_range.to_string()); | |||||
| // } | |||||
| } | } | ||||
| }); | }); | ||||
| if (failed) { | if (failed) { |
| auto name = trim_view(std::string_view(str_begin, str_iter - str_begin)); | auto name = trim_view(std::string_view(str_begin, str_iter - str_begin)); | ||||
| auto version_str = trim_view(std::string_view(str_iter, str_end - str_iter)); | auto version_str = trim_view(std::string_view(str_iter, str_end - str_iter)); | ||||
| semver::version version; | |||||
| try { | try { | ||||
| version = semver::version::parse(version_str); | |||||
| } catch (const semver::invalid_version&) { | |||||
| throw std::runtime_error( | |||||
| fmt::format("Invalid version string '{}' in dependency declaration '{}' (Should be a " | |||||
| "semver string. See https://semver.org/ for info)", | |||||
| version_str, | |||||
| str)); | |||||
| auto rng = semver::range::parse_restricted(version_str); | |||||
| return dependency{std::string(name), rng}; | |||||
| } catch (const semver::invalid_range&) { | |||||
| throw std::runtime_error(fmt::format( | |||||
| "Invalid version range string '{}' in dependency declaration '{}' (Should be a " | |||||
| "semver range string. See https://semver.org/ for info)", | |||||
| version_str, | |||||
| str)); | |||||
| } | } | ||||
| return dependency{std::string(name), version}; | |||||
| } | } | ||||
| std::vector<sdist> dds::find_dependencies(const repository& repo, const dependency& dep) { | std::vector<sdist> dds::find_dependencies(const repository& repo, const dependency& dep) { | ||||
| } | } | ||||
| void detail::do_find_deps(const repository& repo, const dependency& dep, std::vector<sdist>& sd) { | void detail::do_find_deps(const repository& repo, const dependency& dep, std::vector<sdist>& sd) { | ||||
| auto sdist_opt = repo.find(dep.name, dep.version); | |||||
| auto sdist_opt = repo.find(dep.name, dep.version_range.low()); | |||||
| if (!sdist_opt) { | if (!sdist_opt) { | ||||
| throw std::runtime_error( | throw std::runtime_error( | ||||
| fmt::format("Unable to find dependency to satisfy requirement: {} {}", | fmt::format("Unable to find dependency to satisfy requirement: {} {}", | ||||
| dep.name, | dep.name, | ||||
| dep.version.to_string())); | |||||
| dep.version_range.to_string())); | |||||
| } | } | ||||
| const sdist& new_sd = *sdist_opt; | const sdist& new_sd = *sdist_opt; | ||||
| for (const auto& inner_dep : new_sd.manifest.dependencies) { | for (const auto& inner_dep : new_sd.manifest.dependencies) { |
| #include <dds/build/plan/full.hpp> | #include <dds/build/plan/full.hpp> | ||||
| #include <semver/range.hpp> | |||||
| #include <semver/version.hpp> | #include <semver/version.hpp> | ||||
| #include <string_view> | #include <string_view> | ||||
| }; | }; | ||||
| struct dependency { | struct dependency { | ||||
| std::string name; | |||||
| semver::version version; | |||||
| std::string name; | |||||
| semver::range version_range; | |||||
| static dependency parse_depends_string(std::string_view str); | static dependency parse_depends_string(std::string_view str); | ||||
| }; | }; |