| } | } | ||||
| package_plan prepare_one(state& st, const sdist_target& sd) { | package_plan prepare_one(state& st, const sdist_target& sd) { | ||||
| package_plan pkg{sd.sd.manifest.pkg_id.name, sd.sd.manifest.namespace_}; | |||||
| package_plan pkg{sd.sd.manifest.id.name, sd.sd.manifest.namespace_}; | |||||
| auto libs = collect_libraries(sd.sd.path); | auto libs = collect_libraries(sd.sd.path); | ||||
| for (const auto& lib : libs) { | for (const auto& lib : libs) { | ||||
| pkg.add_library(prepare_library(st, sd, lib, sd.sd.manifest)); | pkg.add_library(prepare_library(st, sd, lib, sd.sd.manifest)); |
| #pragma once | |||||
| #include <dds/source/dist.hpp> | |||||
| #include <dds/temp.hpp> | |||||
| namespace dds { | |||||
| class pkg_cache; | |||||
| class pkg_db; | |||||
| struct package_info; | |||||
| temporary_sdist get_package_sdist(const package_info&); | |||||
| void get_all(const std::vector<package_id>& pkgs, dds::pkg_cache& repo, const pkg_db& cat); | |||||
| } // namespace dds |
| #include "./build_common.hpp" | #include "./build_common.hpp" | ||||
| #include <dds/catalog/get.hpp> | |||||
| #include <dds/pkg/cache.hpp> | #include <dds/pkg/cache.hpp> | ||||
| #include <dds/pkg/db.hpp> | #include <dds/pkg/db.hpp> | ||||
| #include <dds/pkg/get/get.hpp> | |||||
| using namespace dds; | using namespace dds; | ||||
| // Download dependencies | // Download dependencies | ||||
| auto deps = repo.solve(man.dependencies, cat); | auto deps = repo.solve(man.dependencies, cat); | ||||
| get_all(deps, repo, cat); | get_all(deps, repo, cat); | ||||
| for (const package_id& pk : deps) { | |||||
| for (const pkg_id& pk : deps) { | |||||
| auto sdist_ptr = repo.find(pk); | auto sdist_ptr = repo.find(pk); | ||||
| assert(sdist_ptr); | assert(sdist_ptr); | ||||
| sdist_build_params deps_params; | sdist_build_params deps_params; | ||||
| deps_params.subdir = fs::path("_deps") / sdist_ptr->manifest.pkg_id.to_string(); | |||||
| deps_params.subdir = fs::path("_deps") / sdist_ptr->manifest.id.to_string(); | |||||
| builder.add(*sdist_ptr, deps_params); | builder.add(*sdist_ptr, deps_params); | ||||
| } | } | ||||
| }); | }); |
| #include <dds/build/builder.hpp> | #include <dds/build/builder.hpp> | ||||
| #include <dds/build/params.hpp> | #include <dds/build/params.hpp> | ||||
| #include <dds/catalog/get.hpp> | |||||
| #include <dds/pkg/cache.hpp> | #include <dds/pkg/cache.hpp> | ||||
| #include <dds/pkg/get/get.hpp> | |||||
| #include <range/v3/action/join.hpp> | #include <range/v3/action/join.hpp> | ||||
| #include <range/v3/range/conversion.hpp> | #include <range/v3/range/conversion.hpp> | ||||
| dds_log(info, "Loading {} dependencies", all_deps.size()); | dds_log(info, "Loading {} dependencies", all_deps.size()); | ||||
| auto deps = repo.solve(all_deps, cat); | auto deps = repo.solve(all_deps, cat); | ||||
| dds::get_all(deps, repo, cat); | dds::get_all(deps, repo, cat); | ||||
| for (const dds::package_id& pk : deps) { | |||||
| for (const dds::pkg_id& pk : deps) { | |||||
| auto sdist_ptr = repo.find(pk); | auto sdist_ptr = repo.find(pk); | ||||
| assert(sdist_ptr); | assert(sdist_ptr); | ||||
| dds::sdist_build_params deps_params; | dds::sdist_build_params deps_params; | ||||
| deps_params.subdir = sdist_ptr->manifest.pkg_id.to_string(); | |||||
| dds_log(info, "Dependency: {}", sdist_ptr->manifest.pkg_id.to_string()); | |||||
| deps_params.subdir = sdist_ptr->manifest.id.to_string(); | |||||
| dds_log(info, "Dependency: {}", sdist_ptr->manifest.id.to_string()); | |||||
| bd.add(*sdist_ptr, deps_params); | bd.add(*sdist_ptr, deps_params); | ||||
| } | } | ||||
| }); | }); |
| #include "../options.hpp" | #include "../options.hpp" | ||||
| #include <dds/catalog/get.hpp> | |||||
| #include <dds/dym.hpp> | #include <dds/dym.hpp> | ||||
| #include <dds/error/errors.hpp> | #include <dds/error/errors.hpp> | ||||
| #include <dds/http/session.hpp> | #include <dds/http/session.hpp> | ||||
| #include <dds/pkg/db.hpp> | #include <dds/pkg/db.hpp> | ||||
| #include <dds/pkg/get/get.hpp> | |||||
| #include <dds/util/result.hpp> | #include <dds/util/result.hpp> | ||||
| #include <boost/leaf/handle_exception.hpp> | #include <boost/leaf/handle_exception.hpp> | ||||
| static int _pkg_get(const options& opts) { | static int _pkg_get(const options& opts) { | ||||
| auto cat = opts.open_catalog(); | auto cat = opts.open_catalog(); | ||||
| for (const auto& item : opts.pkg.get.pkgs) { | for (const auto& item : opts.pkg.get.pkgs) { | ||||
| auto id = package_id::parse(item); | |||||
| auto id = pkg_id::parse(item); | |||||
| dds::dym_target dym; | dds::dym_target dym; | ||||
| auto info = cat.get(id); | auto info = cat.get(id); | ||||
| if (!info) { | if (!info) { |
| static int _pkg_ls(const options& opts) { | static int _pkg_ls(const options& opts) { | ||||
| auto list_contents = [&](pkg_cache repo) { | auto list_contents = [&](pkg_cache repo) { | ||||
| auto same_name | auto same_name | ||||
| = [](auto&& a, auto&& b) { return a.manifest.pkg_id.name == b.manifest.pkg_id.name; }; | |||||
| = [](auto&& a, auto&& b) { return a.manifest.id.name == b.manifest.id.name; }; | |||||
| auto all = repo.iter_sdists(); | auto all = repo.iter_sdists(); | ||||
| auto grp_by_name = all // | auto grp_by_name = all // | ||||
| | ranges::views::transform(ranges::to_vector) // | | ranges::views::transform(ranges::to_vector) // | ||||
| | ranges::views::transform([](auto&& grp) { | | ranges::views::transform([](auto&& grp) { | ||||
| assert(grp.size() > 0); | assert(grp.size() > 0); | ||||
| return std::pair(grp[0].manifest.pkg_id.name, grp); | |||||
| return std::pair(grp[0].manifest.id.name, grp); | |||||
| }); | }); | ||||
| for (const auto& [name, grp] : grp_by_name) { | for (const auto& [name, grp] : grp_by_name) { | ||||
| dds_log(info, "{}:", name); | dds_log(info, "{}:", name); | ||||
| for (const dds::sdist& sd : grp) { | for (const dds::sdist& sd : grp) { | ||||
| dds_log(info, " - {}", sd.manifest.pkg_id.version.to_string()); | |||||
| dds_log(info, " - {}", sd.manifest.id.version.to_string()); | |||||
| } | } | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| }; | }; | ||||
| return dds::pkg_cache::with_cache(opts.pkg_cache_dir.value_or( | |||||
| pkg_cache::default_local_path()), | |||||
| dds::pkg_cache_flags::read, | |||||
| list_contents); | |||||
| return dds::pkg_cache::with_cache(opts.pkg_cache_dir.value_or(pkg_cache::default_local_path()), | |||||
| dds::pkg_cache_flags::read, | |||||
| list_contents); | |||||
| } | } | ||||
| int pkg_ls(const options& opts) { | int pkg_ls(const options& opts) { |
| [](dds::e_sqlite3_error_exc, | [](dds::e_sqlite3_error_exc, | ||||
| boost::leaf::match<neo::sqlite3::errc, neo::sqlite3::errc::constraint_unique>, | boost::leaf::match<neo::sqlite3::errc, neo::sqlite3::errc::constraint_unique>, | ||||
| dds::e_repo_import_targz tgz, | dds::e_repo_import_targz tgz, | ||||
| dds::package_id pkg_id) { | |||||
| dds::pkg_id pkid) { | |||||
| dds_log(error, | dds_log(error, | ||||
| "Package {} (from {}) is already present in the repository", | "Package {} (from {}) is already present in the repository", | ||||
| pkg_id.to_string(), | |||||
| pkid.to_string(), | |||||
| tgz.path); | tgz.path); | ||||
| return 1; | return 1; | ||||
| }, | }, |
| static int _repoman_ls(const options& opts) { | static int _repoman_ls(const options& opts) { | ||||
| auto repo = repo_manager::open(opts.repoman.repo_dir); | auto repo = repo_manager::open(opts.repoman.repo_dir); | ||||
| for (auto pkg_id : repo.all_packages()) { | |||||
| std::cout << pkg_id.to_string() << '\n'; | |||||
| for (auto id : repo.all_packages()) { | |||||
| std::cout << id.to_string() << '\n'; | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } |
| static int _repoman_remove(const options& opts) { | static int _repoman_remove(const options& opts) { | ||||
| auto repo = repo_manager::open(opts.repoman.repo_dir); | auto repo = repo_manager::open(opts.repoman.repo_dir); | ||||
| for (auto& str : opts.repoman.remove.pkgs) { | for (auto& str : opts.repoman.remove.pkgs) { | ||||
| auto pkg_id = dds::package_id::parse(str); | |||||
| repo.delete_package(pkg_id); | |||||
| auto id = dds::pkg_id::parse(str); | |||||
| repo.delete_package(id); | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| [](dds::e_sqlite3_error_exc, | [](dds::e_sqlite3_error_exc, | ||||
| boost::leaf::match<neo::sqlite3::errc, neo::sqlite3::errc::constraint_unique>, | boost::leaf::match<neo::sqlite3::errc, neo::sqlite3::errc::constraint_unique>, | ||||
| dds::e_repo_import_targz tgz, | dds::e_repo_import_targz tgz, | ||||
| dds::package_id pkg_id) { | |||||
| dds::pkg_id pkid) { | |||||
| dds_log(error, | dds_log(error, | ||||
| "Package {} (from {}) is already present in the repository", | "Package {} (from {}) is already present in the repository", | ||||
| pkg_id.to_string(), | |||||
| pkid.to_string(), | |||||
| tgz.path); | tgz.path); | ||||
| return 1; | return 1; | ||||
| }, | }, | ||||
| [](dds::e_system_error_exc e, dds::e_repo_delete_path tgz, dds::package_id pkg_id) { | |||||
| [](dds::e_system_error_exc e, dds::e_repo_delete_path tgz, dds::pkg_id pkid) { | |||||
| dds_log(error, | dds_log(error, | ||||
| "Cannot delete requested package '{}' from repository (Path {}): {}", | "Cannot delete requested package '{}' from repository (Path {}): {}", | ||||
| pkg_id.to_string(), | |||||
| pkid.to_string(), | |||||
| tgz.path, | tgz.path, | ||||
| e.message); | e.message); | ||||
| return 1; | return 1; |
| .include_tests = true, | .include_tests = true, | ||||
| }; | }; | ||||
| auto pkg_man = package_manifest::load_from_directory(params.project_dir); | auto pkg_man = package_manifest::load_from_directory(params.project_dir); | ||||
| auto default_filename = fmt::format("{}.tar.gz", pkg_man->pkg_id.to_string()); | |||||
| auto default_filename = fmt::format("{}.tar.gz", pkg_man->id.to_string()); | |||||
| auto filepath = opts.out_path.value_or(fs::current_path() / default_filename); | auto filepath = opts.out_path.value_or(fs::current_path() / default_filename); | ||||
| create_sdist_targz(filepath, params); | create_sdist_targz(filepath, params); | ||||
| return 0; | return 0; |
| required_key{"name", | required_key{"name", | ||||
| "A string 'name' is required", | "A string 'name' is required", | ||||
| require_str{"'name' must be a string"}, | require_str{"'name' must be a string"}, | ||||
| put_into{ret.pkg_id.name}}, | |||||
| put_into{ret.id.name}}, | |||||
| required_key{"namespace", | required_key{"namespace", | ||||
| "A string 'namespace' is a required ", | "A string 'namespace' is a required ", | ||||
| require_str{"'namespace' must be a string"}, | require_str{"'namespace' must be a string"}, | ||||
| required_key{"version", | required_key{"version", | ||||
| "A 'version' string is requried", | "A 'version' string is requried", | ||||
| require_str{"'version' must be a string"}, | require_str{"'version' must be a string"}, | ||||
| put_into{ret.pkg_id.version, | |||||
| put_into{ret.id.version, | |||||
| [](std::string s) { return semver::version::parse(s); }}}, | [](std::string s) { return semver::version::parse(s); }}}, | ||||
| if_key{"depends", | if_key{"depends", | ||||
| [&](auto&& dat) { | [&](auto&& dat) { |
| #pragma once | #pragma once | ||||
| #include <dds/deps.hpp> | #include <dds/deps.hpp> | ||||
| #include <dds/package/id.hpp> | |||||
| #include <dds/pkg/id.hpp> | |||||
| #include <dds/util/fs.hpp> | #include <dds/util/fs.hpp> | ||||
| #include <optional> | #include <optional> | ||||
| */ | */ | ||||
| struct package_manifest { | struct package_manifest { | ||||
| /// The package ID, as determined by `Name` and `Version` together | /// The package ID, as determined by `Name` and `Version` together | ||||
| package_id pkg_id; | |||||
| dds::pkg_id id; | |||||
| /// The declared `Namespace` of the package. This directly corresponds with the libman Namespace | /// The declared `Namespace` of the package. This directly corresponds with the libman Namespace | ||||
| std::string namespace_; | std::string namespace_; | ||||
| /// The `test_driver` that this package declares, or `nullopt` if absent. | /// The `test_driver` that this package declares, or `nullopt` if absent. |
| } | } | ||||
| void pkg_cache::add_sdist(const sdist& sd, if_exists ife_action) { | void pkg_cache::add_sdist(const sdist& sd, if_exists ife_action) { | ||||
| neo_assertion_breadcrumbs("Importing sdist archive", sd.manifest.pkg_id.to_string()); | |||||
| neo_assertion_breadcrumbs("Importing sdist archive", sd.manifest.id.to_string()); | |||||
| if (!_write_enabled) { | if (!_write_enabled) { | ||||
| dds_log(critical, | dds_log(critical, | ||||
| "DDS attempted to write into a cache that wasn't opened with a write-lock. This " | "DDS attempted to write into a cache that wasn't opened with a write-lock. This " | ||||
| "cache, we'll hard-exit immediately."); | "cache, we'll hard-exit immediately."); | ||||
| std::terminate(); | std::terminate(); | ||||
| } | } | ||||
| auto sd_dest = _root / sd.manifest.pkg_id.to_string(); | |||||
| auto sd_dest = _root / sd.manifest.id.to_string(); | |||||
| if (fs::exists(sd_dest)) { | if (fs::exists(sd_dest)) { | ||||
| auto msg = fmt:: | auto msg = fmt:: | ||||
| format("Package '{}' (Importing from [{}]) is already available in the local cache", | format("Package '{}' (Importing from [{}]) is already available in the local cache", | ||||
| sd.manifest.pkg_id.to_string(), | |||||
| sd.manifest.id.to_string(), | |||||
| sd.path.string()); | sd.path.string()); | ||||
| if (ife_action == if_exists::throw_exc) { | if (ife_action == if_exists::throw_exc) { | ||||
| throw_user_error<errc::sdist_exists>(msg); | throw_user_error<errc::sdist_exists>(msg); | ||||
| } | } | ||||
| fs::rename(tmp_copy, sd_dest); | fs::rename(tmp_copy, sd_dest); | ||||
| _sdists.insert(sdist::from_directory(sd_dest)); | _sdists.insert(sdist::from_directory(sd_dest)); | ||||
| dds_log(info, "Source distribution '{}' successfully exported", sd.manifest.pkg_id.to_string()); | |||||
| dds_log(info, "Source distribution '{}' successfully exported", sd.manifest.id.to_string()); | |||||
| } | } | ||||
| const sdist* pkg_cache::find(const package_id& pkg) const noexcept { | |||||
| const sdist* pkg_cache::find(const pkg_id& pkg) const noexcept { | |||||
| auto found = _sdists.find(pkg); | auto found = _sdists.find(pkg); | ||||
| if (found == _sdists.end()) { | if (found == _sdists.end()) { | ||||
| return nullptr; | return nullptr; | ||||
| return &*found; | return &*found; | ||||
| } | } | ||||
| std::vector<package_id> pkg_cache::solve(const std::vector<dependency>& deps, | |||||
| const pkg_db& ctlg) const { | |||||
| std::vector<pkg_id> pkg_cache::solve(const std::vector<dependency>& deps, | |||||
| const pkg_db& ctlg) const { | |||||
| return dds::solve( | return dds::solve( | ||||
| deps, | deps, | ||||
| [&](std::string_view name) -> std::vector<package_id> { | |||||
| [&](std::string_view name) -> std::vector<pkg_id> { | |||||
| auto mine = ranges::views::all(_sdists) // | auto mine = ranges::views::all(_sdists) // | ||||
| | ranges::views::filter( | | ranges::views::filter( | ||||
| [&](const sdist& sd) { return sd.manifest.pkg_id.name == name; }) | |||||
| | ranges::views::transform([](const sdist& sd) { return sd.manifest.pkg_id; }); | |||||
| [&](const sdist& sd) { return sd.manifest.id.name == name; }) | |||||
| | ranges::views::transform([](const sdist& sd) { return sd.manifest.id; }); | |||||
| auto avail = ctlg.by_name(name); | auto avail = ctlg.by_name(name); | ||||
| auto all = ranges::views::concat(mine, avail) | ranges::to_vector; | auto all = ranges::views::concat(mine, avail) | ranges::to_vector; | ||||
| ranges::sort(all, std::less{}); | ranges::sort(all, std::less{}); | ||||
| ranges::unique(all, std::less{}); | ranges::unique(all, std::less{}); | ||||
| return all; | return all; | ||||
| }, | }, | ||||
| [&](const package_id& pkg_id) { | |||||
| [&](const pkg_id& pkg_id) { | |||||
| auto found = find(pkg_id); | auto found = find(pkg_id); | ||||
| if (found) { | if (found) { | ||||
| return found->manifest.dependencies; | return found->manifest.dependencies; |
| void add_sdist(const sdist&, if_exists = if_exists::throw_exc); | void add_sdist(const sdist&, if_exists = if_exists::throw_exc); | ||||
| const sdist* find(const package_id& pk) const noexcept; | |||||
| const sdist* find(const pkg_id& pk) const noexcept; | |||||
| auto iter_sdists() const noexcept { | auto iter_sdists() const noexcept { | ||||
| class ret { | class ret { | ||||
| return r; | return r; | ||||
| } | } | ||||
| std::vector<package_id> solve(const std::vector<dependency>& deps, const pkg_db&) const; | |||||
| std::vector<pkg_id> solve(const std::vector<dependency>& deps, const pkg_db&) const; | |||||
| }; | }; | ||||
| } // namespace dds | } // namespace dds |
| )"); | )"); | ||||
| } | } | ||||
| void store_with_remote(const neo::sqlite3::statement_cache&, | |||||
| const package_info& pkg, | |||||
| std::monostate) { | |||||
| void store_with_remote(const neo::sqlite3::statement_cache&, const pkg_info& pkg, std::monostate) { | |||||
| neo_assert_always( | neo_assert_always( | ||||
| invariant, | invariant, | ||||
| false, | false, | ||||
| } | } | ||||
| void store_with_remote(neo::sqlite3::statement_cache& stmts, | void store_with_remote(neo::sqlite3::statement_cache& stmts, | ||||
| const package_info& pkg, | |||||
| const pkg_info& pkg, | |||||
| const http_remote_listing& http) { | const http_remote_listing& http) { | ||||
| nsql::exec( // | nsql::exec( // | ||||
| stmts(R"( | stmts(R"( | ||||
| } | } | ||||
| void store_with_remote(neo::sqlite3::statement_cache& stmts, | void store_with_remote(neo::sqlite3::statement_cache& stmts, | ||||
| const package_info& pkg, | |||||
| const pkg_info& pkg, | |||||
| const git_remote_listing& git) { | const git_remote_listing& git) { | ||||
| std::string url = git.url; | std::string url = git.url; | ||||
| if (url.starts_with("https://") || url.starts_with("http://")) { | if (url.starts_with("https://") || url.starts_with("http://")) { | ||||
| void do_store_pkg(neo::sqlite3::database& db, | void do_store_pkg(neo::sqlite3::database& db, | ||||
| neo::sqlite3::statement_cache& st_cache, | neo::sqlite3::statement_cache& st_cache, | ||||
| const package_info& pkg) { | |||||
| const pkg_info& pkg) { | |||||
| dds_log(debug, "Recording package {}@{}", pkg.ident.name, pkg.ident.version.to_string()); | dds_log(debug, "Recording package {}@{}", pkg.ident.name, pkg.ident.version.to_string()); | ||||
| std::visit([&](auto&& remote) { store_with_remote(st_cache, pkg, remote); }, pkg.remote); | std::visit([&](auto&& remote) { store_with_remote(st_cache, pkg, remote); }, pkg.remote); | ||||
| auto db_pkg_id = db.last_insert_rowid(); | auto db_pkg_id = db.last_insert_rowid(); | ||||
| pkg_db::pkg_db(nsql::database db) | pkg_db::pkg_db(nsql::database db) | ||||
| : _db(std::move(db)) {} | : _db(std::move(db)) {} | ||||
| void pkg_db::store(const package_info& pkg) { | |||||
| void pkg_db::store(const pkg_info& pkg) { | |||||
| nsql::transaction_guard tr{_db}; | nsql::transaction_guard tr{_db}; | ||||
| do_store_pkg(_db, _stmt_cache, pkg); | do_store_pkg(_db, _stmt_cache, pkg); | ||||
| } | } | ||||
| std::optional<package_info> pkg_db::get(const package_id& pk_id) const noexcept { | |||||
| std::optional<pkg_info> pkg_db::get(const pkg_id& pk_id) const noexcept { | |||||
| auto ver_str = pk_id.version.to_string(); | auto ver_str = pk_id.version.to_string(); | ||||
| dds_log(trace, "Lookup package {}@{}", pk_id.name, ver_str); | dds_log(trace, "Lookup package {}@{}", pk_id.name, ver_str); | ||||
| auto& st = _stmt_cache(R"( | auto& st = _stmt_cache(R"( | ||||
| auto deps = dependencies_of(pk_id); | auto deps = dependencies_of(pk_id); | ||||
| auto info = package_info{ | |||||
| auto info = pkg_info{ | |||||
| pk_id, | pk_id, | ||||
| std::move(deps), | std::move(deps), | ||||
| std::move(description), | std::move(description), | ||||
| auto pair_to_pkg_id = [](auto&& pair) { | auto pair_to_pkg_id = [](auto&& pair) { | ||||
| const auto& [name, ver] = pair; | const auto& [name, ver] = pair; | ||||
| return package_id{name, semver::version::parse(ver)}; | |||||
| return pkg_id{name, semver::version::parse(ver)}; | |||||
| }; | }; | ||||
| std::vector<package_id> pkg_db::all() const noexcept { | |||||
| std::vector<pkg_id> pkg_db::all() const noexcept { | |||||
| return nsql::exec_tuples<std::string, std::string>( | return nsql::exec_tuples<std::string, std::string>( | ||||
| _stmt_cache("SELECT name, version FROM dds_cat_pkgs"_sql)) | _stmt_cache("SELECT name, version FROM dds_cat_pkgs"_sql)) | ||||
| | neo::lref // | | neo::lref // | ||||
| | ranges::to_vector; | | ranges::to_vector; | ||||
| } | } | ||||
| std::vector<package_id> pkg_db::by_name(std::string_view sv) const noexcept { | |||||
| std::vector<pkg_id> pkg_db::by_name(std::string_view sv) const noexcept { | |||||
| return nsql::exec_tuples<std::string, std::string>( // | return nsql::exec_tuples<std::string, std::string>( // | ||||
| _stmt_cache( | _stmt_cache( | ||||
| R"( | R"( | ||||
| | ranges::to_vector; | | ranges::to_vector; | ||||
| } | } | ||||
| std::vector<dependency> pkg_db::dependencies_of(const package_id& pkg) const noexcept { | |||||
| std::vector<dependency> pkg_db::dependencies_of(const pkg_id& pkg) const noexcept { | |||||
| dds_log(trace, "Lookup dependencies of {}@{}", pkg.name, pkg.version.to_string()); | dds_log(trace, "Lookup dependencies of {}@{}", pkg.name, pkg.version.to_string()); | ||||
| return nsql::exec_tuples<std::string, | return nsql::exec_tuples<std::string, | ||||
| std::string, | std::string, |
| #pragma once | #pragma once | ||||
| #include "./info.hpp" | |||||
| #include <dds/deps.hpp> | #include <dds/deps.hpp> | ||||
| #include <dds/package/id.hpp> | |||||
| #include <dds/pkg/id.hpp> | |||||
| #include <dds/util/fs.hpp> | #include <dds/util/fs.hpp> | ||||
| #include <dds/util/glob.hpp> | #include <dds/util/glob.hpp> | ||||
| #include <dds/catalog/package_info.hpp> | |||||
| #include <neo/sqlite3/database.hpp> | #include <neo/sqlite3/database.hpp> | ||||
| #include <neo/sqlite3/statement.hpp> | #include <neo/sqlite3/statement.hpp> | ||||
| #include <neo/sqlite3/statement_cache.hpp> | #include <neo/sqlite3/statement_cache.hpp> | ||||
| static fs::path default_path() noexcept; | static fs::path default_path() noexcept; | ||||
| void store(const package_info& info); | |||||
| std::optional<package_info> get(const package_id& id) const noexcept; | |||||
| void store(const pkg_info& info); | |||||
| std::optional<pkg_info> get(const pkg_id& id) const noexcept; | |||||
| std::vector<package_id> all() const noexcept; | |||||
| std::vector<package_id> by_name(std::string_view sv) const noexcept; | |||||
| std::vector<dependency> dependencies_of(const package_id& pkg) const noexcept; | |||||
| std::vector<pkg_id> all() const noexcept; | |||||
| std::vector<pkg_id> by_name(std::string_view sv) const noexcept; | |||||
| std::vector<dependency> dependencies_of(const pkg_id& pkg) const noexcept; | |||||
| auto& database() noexcept { return _db; } | auto& database() noexcept { return _db; } | ||||
| auto& database() const noexcept { return _db; } | auto& database() const noexcept { return _db; } |
| }; | }; | ||||
| TEST_CASE_METHOD(catalog_test_case, "Store a simple package") { | TEST_CASE_METHOD(catalog_test_case, "Store a simple package") { | ||||
| db.store(dds::package_info{ | |||||
| dds::package_id("foo", semver::version::parse("1.2.3")), | |||||
| db.store(dds::pkg_info{ | |||||
| dds::pkg_id("foo", semver::version::parse("1.2.3")), | |||||
| {}, | {}, | ||||
| "example", | "example", | ||||
| dds::git_remote_listing{std::nullopt, "git+http://example.com", "master"}, | dds::git_remote_listing{std::nullopt, "git+http://example.com", "master"}, | ||||
| CHECK(std::get<dds::git_remote_listing>(info->remote).ref == "master"); | CHECK(std::get<dds::git_remote_listing>(info->remote).ref == "master"); | ||||
| // Update the entry with a new git remote ref | // Update the entry with a new git remote ref | ||||
| CHECK_NOTHROW(db.store(dds::package_info{ | |||||
| dds::package_id("foo", semver::version::parse("1.2.3")), | |||||
| CHECK_NOTHROW(db.store(dds::pkg_info{ | |||||
| dds::pkg_id("foo", semver::version::parse("1.2.3")), | |||||
| {}, | {}, | ||||
| "example", | "example", | ||||
| dds::git_remote_listing{std::nullopt, "git+http://example.com", "develop"}, | dds::git_remote_listing{std::nullopt, "git+http://example.com", "develop"}, | ||||
| } | } | ||||
| TEST_CASE_METHOD(catalog_test_case, "Package requirements") { | TEST_CASE_METHOD(catalog_test_case, "Package requirements") { | ||||
| db.store(dds::package_info{ | |||||
| dds::package_id{"foo", semver::version::parse("1.2.3")}, | |||||
| db.store(dds::pkg_info{ | |||||
| dds::pkg_id{"foo", semver::version::parse("1.2.3")}, | |||||
| { | { | ||||
| {"bar", {semver::version::parse("1.2.3"), semver::version::parse("1.4.0")}}, | {"bar", {semver::version::parse("1.2.3"), semver::version::parse("1.4.0")}}, | ||||
| {"baz", {semver::version::parse("5.3.0"), semver::version::parse("6.0.0")}}, | {"baz", {semver::version::parse("5.3.0"), semver::version::parse("6.0.0")}}, |
| #include "./base.hpp" | #include "./base.hpp" | ||||
| #include <dds/package/id.hpp> | |||||
| #include <dds/pkg/id.hpp> | |||||
| #include <dds/util/log.hpp> | #include <dds/util/log.hpp> | ||||
| #include <nlohmann/json.hpp> | #include <nlohmann/json.hpp> | ||||
| using namespace dds; | using namespace dds; | ||||
| void remote_listing_base::generate_auto_lib_files(const package_id& pid, path_ref root) const { | |||||
| void remote_listing_base::generate_auto_lib_files(const pkg_id& pid, path_ref root) const { | |||||
| if (auto_lib.has_value()) { | if (auto_lib.has_value()) { | ||||
| dds_log(info, "Generating library data automatically"); | dds_log(info, "Generating library data automatically"); | ||||
| namespace dds { | namespace dds { | ||||
| struct package_id; | |||||
| struct pkg_id; | |||||
| struct remote_listing_base { | struct remote_listing_base { | ||||
| std::optional<lm::usage> auto_lib{}; | std::optional<lm::usage> auto_lib{}; | ||||
| void generate_auto_lib_files(const package_id& pid, path_ref root) const; | |||||
| void generate_auto_lib_files(const pkg_id& pid, path_ref root) const; | |||||
| }; | }; | ||||
| template <typename T> | template <typename T> |
| namespace { | namespace { | ||||
| temporary_sdist do_pull_sdist(const package_info& listing, std::monostate) { | |||||
| temporary_sdist do_pull_sdist(const pkg_info& listing, std::monostate) { | |||||
| neo_assert_always( | neo_assert_always( | ||||
| invariant, | invariant, | ||||
| false, | false, | ||||
| } | } | ||||
| template <remote_listing R> | template <remote_listing R> | ||||
| temporary_sdist do_pull_sdist(const package_info& listing, const R& remote) { | |||||
| temporary_sdist do_pull_sdist(const pkg_info& listing, const R& remote) { | |||||
| auto tmpdir = dds::temporary_dir::create(); | auto tmpdir = dds::temporary_dir::create(); | ||||
| remote.pull_source(tmpdir.path()); | remote.pull_source(tmpdir.path()); | ||||
| } // namespace | } // namespace | ||||
| temporary_sdist dds::get_package_sdist(const package_info& pkg) { | |||||
| temporary_sdist dds::get_package_sdist(const pkg_info& pkg) { | |||||
| auto tsd = std::visit([&](auto&& remote) { return do_pull_sdist(pkg, remote); }, pkg.remote); | auto tsd = std::visit([&](auto&& remote) { return do_pull_sdist(pkg, remote); }, pkg.remote); | ||||
| if (!(tsd.sdist.manifest.pkg_id == pkg.ident)) { | |||||
| if (!(tsd.sdist.manifest.id == pkg.ident)) { | |||||
| throw_external_error<errc::sdist_ident_mismatch>( | throw_external_error<errc::sdist_ident_mismatch>( | ||||
| "The package name@version in the generated source distribution does not match the name " | "The package name@version in the generated source distribution does not match the name " | ||||
| "listed in the remote listing file (expected '{}', but got '{}')", | "listed in the remote listing file (expected '{}', but got '{}')", | ||||
| pkg.ident.to_string(), | pkg.ident.to_string(), | ||||
| tsd.sdist.manifest.pkg_id.to_string()); | |||||
| tsd.sdist.manifest.id.to_string()); | |||||
| } | } | ||||
| return tsd; | return tsd; | ||||
| } | } | ||||
| void dds::get_all(const std::vector<package_id>& pkgs, pkg_cache& repo, const pkg_db& cat) { | |||||
| void dds::get_all(const std::vector<pkg_id>& pkgs, pkg_cache& repo, const pkg_db& cat) { | |||||
| std::mutex repo_mut; | std::mutex repo_mut; | ||||
| auto absent_pkg_infos = pkgs // | auto absent_pkg_infos = pkgs // | ||||
| return *info; | return *info; | ||||
| }); | }); | ||||
| auto okay = parallel_run(absent_pkg_infos, 8, [&](package_info inf) { | |||||
| auto okay = parallel_run(absent_pkg_infos, 8, [&](pkg_info inf) { | |||||
| dds_log(info, "Download package: {}", inf.ident.to_string()); | dds_log(info, "Download package: {}", inf.ident.to_string()); | ||||
| auto tsd = get_package_sdist(inf); | auto tsd = get_package_sdist(inf); | ||||
| std::scoped_lock lk{repo_mut}; | std::scoped_lock lk{repo_mut}; |
| #pragma once | |||||
| #include <dds/source/dist.hpp> | |||||
| #include <dds/temp.hpp> | |||||
| namespace dds { | |||||
| class pkg_cache; | |||||
| class pkg_db; | |||||
| struct pkg_info; | |||||
| temporary_sdist get_package_sdist(const pkg_info&); | |||||
| void get_all(const std::vector<pkg_id>& pkgs, dds::pkg_cache& repo, const pkg_db& cat); | |||||
| } // namespace dds |
| #include <dds/catalog/remote/http.hpp> | |||||
| #include "./http.hpp" | |||||
| #include <dds/error/errors.hpp> | #include <dds/error/errors.hpp> | ||||
| #include <dds/source/dist.hpp> | #include <dds/source/dist.hpp> |
| #include <dds/package/id.hpp> | |||||
| #include <dds/pkg/id.hpp> | |||||
| #include <dds/error/errors.hpp> | #include <dds/error/errors.hpp> | ||||
| using namespace dds; | using namespace dds; | ||||
| package_id package_id::parse(std::string_view s) { | |||||
| pkg_id pkg_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_user_error<errc::invalid_pkg_id>("Invalid package ID '{}'", s); | throw_user_error<errc::invalid_pkg_id>("Invalid package ID '{}'", s); | ||||
| return {std::string(name), semver::version::parse(ver_str)}; | return {std::string(name), semver::version::parse(ver_str)}; | ||||
| } | } | ||||
| package_id::package_id(std::string_view n, semver::version v) | |||||
| pkg_id::pkg_id(std::string_view n, semver::version v) | |||||
| : name(n) | : name(n) | ||||
| , version(std::move(v)) { | , version(std::move(v)) { | ||||
| if (name.find('@') != name.npos) { | if (name.find('@') != name.npos) { | ||||
| } | } | ||||
| } | } | ||||
| std::string package_id::to_string() const noexcept { return name + "@" + version.to_string(); } | |||||
| std::string pkg_id::to_string() const noexcept { return name + "@" + version.to_string(); } |
| * `to_string` method convert between this textual representation, and supports | * `to_string` method convert between this textual representation, and supports | ||||
| * full round-trips. | * full round-trips. | ||||
| */ | */ | ||||
| struct package_id { | |||||
| struct pkg_id { | |||||
| /// The name of the package | /// The name of the package | ||||
| std::string name; | std::string name; | ||||
| /// The version of the package | /// The version of the package | ||||
| semver::version version; | semver::version version; | ||||
| /// Default-initialize a package_id with a blank name and a default version | |||||
| package_id() = default; | |||||
| /// Default-initialize a pkg_id with a blank name and a default version | |||||
| pkg_id() = default; | |||||
| /// Construct a package ID from a name-version pair | /// Construct a package ID from a name-version pair | ||||
| package_id(std::string_view s, semver::version v); | |||||
| pkg_id(std::string_view s, semver::version v); | |||||
| /** | /** | ||||
| * Parse the given string into a package_id object. | |||||
| * Parse the given string into a pkg_id object. | |||||
| */ | */ | ||||
| static package_id parse(std::string_view); | |||||
| static pkg_id parse(std::string_view); | |||||
| /** | |||||
| * Convert this package_id into its corresponding textual representation. | |||||
| /**d | |||||
| * Convert this pkg_id into its corresponding textual representation. | |||||
| * The returned string can be passed back to `parse()` for a round-trip | * The returned string can be passed back to `parse()` for a round-trip | ||||
| */ | */ | ||||
| std::string to_string() const noexcept; | std::string to_string() const noexcept; | ||||
| friend bool operator<(const package_id& lhs, const package_id& rhs) noexcept { | |||||
| friend bool operator<(const pkg_id& lhs, const pkg_id& rhs) noexcept { | |||||
| return std::tie(lhs.name, lhs.version) < std::tie(rhs.name, rhs.version); | return std::tie(lhs.name, lhs.version) < std::tie(rhs.name, rhs.version); | ||||
| } | } | ||||
| friend bool operator==(const package_id& lhs, const package_id& rhs) noexcept { | |||||
| friend bool operator==(const pkg_id& lhs, const pkg_id& rhs) noexcept { | |||||
| return std::tie(lhs.name, lhs.version) == std::tie(rhs.name, rhs.version); | return std::tie(lhs.name, lhs.version) == std::tie(rhs.name, rhs.version); | ||||
| } | } | ||||
| }; | }; |
| #include <dds/package/id.hpp> | |||||
| #include <dds/pkg/id.hpp> | |||||
| #include <catch2/catch.hpp> | #include <catch2/catch.hpp> | ||||
| {"foo@1.2.3-alpha", "foo", "1.2.3-alpha"}, | {"foo@1.2.3-alpha", "foo", "1.2.3-alpha"}, | ||||
| })); | })); | ||||
| auto pk_id = dds::package_id::parse(id_str); | |||||
| auto pk_id = dds::pkg_id::parse(id_str); | |||||
| CHECK(pk_id.to_string() == id_str); | CHECK(pk_id.to_string() == id_str); | ||||
| CHECK(pk_id.name == exp_name); | CHECK(pk_id.name == exp_name); | ||||
| CHECK(pk_id.version.to_string() == exp_ver); | CHECK(pk_id.version.to_string() == exp_ver); | ||||
| {"foo@0.1.2-alpha", less_than, "foo@1.0.0"}, | {"foo@0.1.2-alpha", less_than, "foo@1.0.0"}, | ||||
| })); | })); | ||||
| auto lhs = dds::package_id::parse(lhs_str); | |||||
| auto rhs = dds::package_id::parse(rhs_str); | |||||
| auto lhs = dds::pkg_id::parse(lhs_str); | |||||
| auto rhs = dds::pkg_id::parse(rhs_str); | |||||
| if (ord == less_than) { | if (ord == less_than) { | ||||
| CHECK(lhs < rhs); | CHECK(lhs < rhs); |
| #include "./package_info.hpp" | |||||
| #include "./info.hpp" | |||||
| #include <dds/error/errors.hpp> | #include <dds/error/errors.hpp> | ||||
| #include <dds/util/string.hpp> | #include <dds/util/string.hpp> |
| #pragma once | #pragma once | ||||
| #include "./remote/git.hpp" | |||||
| #include "./remote/http.hpp" | |||||
| #include "./get/git.hpp" | |||||
| #include "./get/http.hpp" | |||||
| #include <dds/deps.hpp> | #include <dds/deps.hpp> | ||||
| #include <dds/package/id.hpp> | |||||
| #include <dds/pkg/id.hpp> | |||||
| #include <dds/util/glob.hpp> | #include <dds/util/glob.hpp> | ||||
| #include <optional> | #include <optional> | ||||
| remote_listing_var parse_remote_url(std::string_view url); | remote_listing_var parse_remote_url(std::string_view url); | ||||
| struct package_info { | |||||
| package_id ident; | |||||
| struct pkg_info { | |||||
| pkg_id ident; | |||||
| std::vector<dependency> deps; | std::vector<dependency> deps; | ||||
| std::string description; | std::string description; | ||||
| throw std::runtime_error("Invalid package archive"); | throw std::runtime_error("Invalid package archive"); | ||||
| } | } | ||||
| DDS_E_SCOPE(man->pkg_id); | |||||
| DDS_E_SCOPE(man->id); | |||||
| neo::sqlite3::transaction_guard tr{_db}; | neo::sqlite3::transaction_guard tr{_db}; | ||||
| dds_log(debug, "Recording package {}@{}", man->pkg_id.name, man->pkg_id.version.to_string()); | |||||
| dds_log(debug, "Recording package {}@{}", man->id.name, man->id.version.to_string()); | |||||
| nsql::exec( // | nsql::exec( // | ||||
| _stmts(R"( | _stmts(R"( | ||||
| INSERT INTO dds_repo_packages (name, version, description, url) | INSERT INTO dds_repo_packages (name, version, description, url) | ||||
| printf('dds:%s@%s', ?1, ?2) | printf('dds:%s@%s', ?1, ?2) | ||||
| ) | ) | ||||
| )"_sql), | )"_sql), | ||||
| man->pkg_id.name, | |||||
| man->pkg_id.version.to_string()); | |||||
| man->id.name, | |||||
| man->id.version.to_string()); | |||||
| auto package_id = _db.last_insert_rowid(); | auto package_id = _db.last_insert_rowid(); | ||||
| } | } | ||||
| auto dest_path | auto dest_path | ||||
| = pkg_dir() / man->pkg_id.name / man->pkg_id.version.to_string() / "sdist.tar.gz"; | |||||
| = pkg_dir() / man->id.name / man->id.version.to_string() / "sdist.tar.gz"; | |||||
| fs::create_directories(dest_path.parent_path()); | fs::create_directories(dest_path.parent_path()); | ||||
| fs::copy(tgz_file, dest_path); | fs::copy(tgz_file, dest_path); | ||||
| tr.commit(); | tr.commit(); | ||||
| } | } | ||||
| void repo_manager::delete_package(package_id pkg_id) { | |||||
| void repo_manager::delete_package(pkg_id pkg_id) { | |||||
| neo::sqlite3::transaction_guard tr{_db}; | neo::sqlite3::transaction_guard tr{_db}; | ||||
| DDS_E_SCOPE(pkg_id); | DDS_E_SCOPE(pkg_id); |
| #pragma once | #pragma once | ||||
| #include <dds/package/id.hpp> | |||||
| #include <dds/pkg/id.hpp> | |||||
| #include <dds/util/fs.hpp> | #include <dds/util/fs.hpp> | ||||
| #include <neo/sqlite3/database.hpp> | #include <neo/sqlite3/database.hpp> | ||||
| std::string name() const noexcept; | std::string name() const noexcept; | ||||
| void import_targz(path_ref tgz_path); | void import_targz(path_ref tgz_path); | ||||
| void delete_package(package_id id); | |||||
| void delete_package(pkg_id id); | |||||
| auto all_packages() const noexcept { | auto all_packages() const noexcept { | ||||
| using namespace neo::sqlite3::literals; | using namespace neo::sqlite3::literals; | ||||
| auto tups = neo::sqlite3::iter_tuples<std::string, std::string>(st); | auto tups = neo::sqlite3::iter_tuples<std::string, std::string>(st); | ||||
| return tups | ranges::views::transform([](auto&& pair) { | return tups | ranges::views::transform([](auto&& pair) { | ||||
| auto [name, version] = pair; | auto [name, version] = pair; | ||||
| return package_id{name, semver::version::parse(version)}; | |||||
| return pkg_id{name, semver::version::parse(version)}; | |||||
| }); | }); | ||||
| } | } | ||||
| }; | }; |
| CHECK(dds::fs::is_directory(repo.pkg_dir() / "neo-url/")); | CHECK(dds::fs::is_directory(repo.pkg_dir() / "neo-url/")); | ||||
| CHECK(dds::fs::is_regular_file(repo.pkg_dir() / "neo-url/0.2.1/sdist.tar.gz")); | CHECK(dds::fs::is_regular_file(repo.pkg_dir() / "neo-url/0.2.1/sdist.tar.gz")); | ||||
| CHECK_THROWS_AS(repo.import_targz(neo_url_tgz), neo::sqlite3::constraint_unique_error); | CHECK_THROWS_AS(repo.import_targz(neo_url_tgz), neo::sqlite3::constraint_unique_error); | ||||
| repo.delete_package(dds::package_id::parse("neo-url@0.2.1")); | |||||
| repo.delete_package(dds::pkg_id::parse("neo-url@0.2.1")); | |||||
| CHECK_FALSE(dds::fs::is_regular_file(repo.pkg_dir() / "neo-url/0.2.1/sdist.tar.gz")); | CHECK_FALSE(dds::fs::is_regular_file(repo.pkg_dir() / "neo-url/0.2.1/sdist.tar.gz")); | ||||
| CHECK_FALSE(dds::fs::is_directory(repo.pkg_dir() / "neo-url")); | CHECK_FALSE(dds::fs::is_directory(repo.pkg_dir() / "neo-url")); | ||||
| CHECK_THROWS_AS(repo.delete_package(dds::package_id::parse("neo-url@0.2.1")), | |||||
| std::system_error); | |||||
| CHECK_THROWS_AS(repo.delete_package(dds::pkg_id::parse("neo-url@0.2.1")), std::system_error); | |||||
| CHECK_NOTHROW(repo.import_targz(neo_url_tgz)); | CHECK_NOTHROW(repo.import_targz(neo_url_tgz)); | ||||
| } | } |
| auto as_pkg_id(const req_type& req) { | auto as_pkg_id(const req_type& req) { | ||||
| const version_range_set& versions = req.dep.versions; | const version_range_set& versions = req.dep.versions; | ||||
| assert(versions.num_intervals() == 1); | assert(versions.num_intervals() == 1); | ||||
| return package_id{req.dep.name, (*versions.iter_intervals().begin()).low}; | |||||
| return pkg_id{req.dep.name, (*versions.iter_intervals().begin()).low}; | |||||
| } | } | ||||
| struct solver_provider { | struct solver_provider { | ||||
| pkg_id_provider_fn& pkgs_for_name; | pkg_id_provider_fn& pkgs_for_name; | ||||
| deps_provider_fn& deps_for_pkg; | deps_provider_fn& deps_for_pkg; | ||||
| mutable std::map<std::string, std::vector<package_id>> pkgs_by_name = {}; | |||||
| mutable std::map<std::string, std::vector<pkg_id>> pkgs_by_name = {}; | |||||
| std::optional<req_type> best_candidate(const req_type& req) const { | std::optional<req_type> best_candidate(const req_type& req) const { | ||||
| dds_log(debug, "Find best candidate of {}", req.dep.to_string()); | dds_log(debug, "Find best candidate of {}", req.dep.to_string()); | ||||
| } | } | ||||
| // Find the first package with the version contained by the ranges in the requirement | // Find the first package with the version contained by the ranges in the requirement | ||||
| auto& for_name = found->second; | auto& for_name = found->second; | ||||
| auto cand = std::find_if(for_name.cbegin(), for_name.cend(), [&](const package_id& pk) { | |||||
| auto cand = std::find_if(for_name.cbegin(), for_name.cend(), [&](const pkg_id& pk) { | |||||
| return req.dep.versions.contains(pk.version); | return req.dep.versions.contains(pk.version); | ||||
| }); | }); | ||||
| if (cand == for_name.cend()) { | if (cand == for_name.cend()) { | ||||
| } // namespace | } // namespace | ||||
| std::vector<package_id> dds::solve(const std::vector<dependency>& deps, | |||||
| pkg_id_provider_fn pkgs_prov, | |||||
| deps_provider_fn deps_prov) { | |||||
| std::vector<pkg_id> dds::solve(const std::vector<dependency>& deps, | |||||
| pkg_id_provider_fn pkgs_prov, | |||||
| deps_provider_fn deps_prov) { | |||||
| auto wrap_req | auto wrap_req | ||||
| = deps | ranges::views::transform([](const dependency& dep) { return req_type{dep}; }); | = deps | ranges::views::transform([](const dependency& dep) { return req_type{dep}; }); | ||||
| #pragma once | #pragma once | ||||
| #include <dds/deps.hpp> | #include <dds/deps.hpp> | ||||
| #include <dds/package/id.hpp> | |||||
| #include <dds/pkg/id.hpp> | |||||
| #include <functional> | #include <functional> | ||||
| namespace dds { | namespace dds { | ||||
| using pkg_id_provider_fn = std::function<std::vector<package_id>(std::string_view)>; | |||||
| using deps_provider_fn = std::function<std::vector<dependency>(const package_id& pk)>; | |||||
| using pkg_id_provider_fn = std::function<std::vector<pkg_id>(std::string_view)>; | |||||
| using deps_provider_fn = std::function<std::vector<dependency>(const pkg_id& pk)>; | |||||
| std::vector<package_id> | |||||
| std::vector<pkg_id> | |||||
| solve(const std::vector<dependency>& deps, pkg_id_provider_fn, deps_provider_fn); | solve(const std::vector<dependency>& deps, pkg_id_provider_fn, deps_provider_fn); | ||||
| } // namespace dds | } // namespace dds |
| #include "./dist.hpp" | #include "./dist.hpp" | ||||
| #include <dds/catalog/remote/http.hpp> | |||||
| #include <dds/error/errors.hpp> | #include <dds/error/errors.hpp> | ||||
| #include <dds/library/root.hpp> | #include <dds/library/root.hpp> | ||||
| #include <dds/pkg/get/http.hpp> | |||||
| #include <dds/temp.hpp> | #include <dds/temp.hpp> | ||||
| #include <dds/util/fs.hpp> | #include <dds/util/fs.hpp> | ||||
| #include <dds/util/log.hpp> | #include <dds/util/log.hpp> | ||||
| auto pkg_man = package_manifest::load_from_file(*man_path); | auto pkg_man = package_manifest::load_from_file(*man_path); | ||||
| sdist_export_file(out, params.project_dir, *man_path); | sdist_export_file(out, params.project_dir, *man_path); | ||||
| dds_log(info, "Generated export as {}", pkg_man.pkg_id.to_string()); | |||||
| dds_log(info, "Generated export as {}", pkg_man.id.to_string()); | |||||
| return sdist::from_directory(out); | return sdist::from_directory(out); | ||||
| } | } | ||||
| inline constexpr struct sdist_compare_t { | inline constexpr struct sdist_compare_t { | ||||
| bool operator()(const sdist& lhs, const sdist& rhs) const { | bool operator()(const sdist& lhs, const sdist& rhs) const { | ||||
| return lhs.manifest.pkg_id < rhs.manifest.pkg_id; | |||||
| } | |||||
| bool operator()(const sdist& lhs, const package_id& rhs) const { | |||||
| return lhs.manifest.pkg_id < rhs; | |||||
| } | |||||
| bool operator()(const package_id& lhs, const sdist& rhs) const { | |||||
| return lhs < rhs.manifest.pkg_id; | |||||
| return lhs.manifest.id < rhs.manifest.id; | |||||
| } | } | ||||
| bool operator()(const sdist& lhs, const pkg_id& rhs) const { return lhs.manifest.id < rhs; } | |||||
| bool operator()(const pkg_id& lhs, const sdist& rhs) const { return lhs < rhs.manifest.id; } | |||||
| using is_transparent = int; | using is_transparent = int; | ||||
| } sdist_compare; | } sdist_compare; | ||||