diff options
-rw-r--r-- | bpkg/package-query.cxx | 90 | ||||
-rw-r--r-- | bpkg/package-query.hxx | 19 |
2 files changed, 99 insertions, 10 deletions
diff --git a/bpkg/package-query.cxx b/bpkg/package-query.cxx index 8d7b652..66cb7f0 100644 --- a/bpkg/package-query.cxx +++ b/bpkg/package-query.cxx @@ -311,11 +311,13 @@ namespace bpkg } // Sort the available package fragments in the package version descending - // order and suppress duplicate packages. + // order and suppress duplicate packages and, optionally, older package + // revisions. // static void sort_dedup (vector<pair<shared_ptr<available_package>, - lazy_shared_ptr<repository_fragment>>>& pfs) + lazy_shared_ptr<repository_fragment>>>& pfs, + bool suppress_older_revisions = false) { sort (pfs.begin (), pfs.end (), [] (const auto& x, const auto& y) @@ -323,12 +325,14 @@ namespace bpkg return x.first->version > y.first->version; }); - pfs.erase (unique (pfs.begin(), pfs.end(), - [] (const auto& x, const auto& y) - { - return x.first->version == y.first->version; - }), - pfs.end ()); + pfs.erase ( + unique (pfs.begin(), pfs.end(), + [suppress_older_revisions] (const auto& x, const auto& y) + { + return x.first->version.compare (y.first->version, + suppress_older_revisions) == 0; + }), + pfs.end ()); } vector<pair<shared_ptr<available_package>, @@ -546,6 +550,76 @@ namespace bpkg return make_pair (find_available (options, db, sp), nullptr); } + vector<pair<shared_ptr<available_package>, + lazy_shared_ptr<repository_fragment>>> + find_available_all (const linked_databases& dbs, + const package_name& name, + bool suppress_older_revisions) + { + // Collect all the databases linked explicitly and implicitly to the + // specified databases, recursively. + // + // Note that this is a superset of the database cluster, since we descend + // into the database links regardless of their types (see + // cluster_configs() for details). + // + linked_databases all_dbs; + all_dbs.reserve (dbs.size ()); + + auto add = [&all_dbs] (database& db, const auto& add) + { + if (find (all_dbs.begin (), all_dbs.end (), db) != all_dbs.end ()) + return; + + all_dbs.push_back (db); + + { + const linked_configs& cs (db.explicit_links ()); + for (auto i (cs.begin_linked ()); i != cs.end (); ++i) + add (i->db, add); + } + + { + const linked_databases& cs (db.implicit_links ()); + for (auto i (cs.begin_linked ()); i != cs.end (); ++i) + add (*i, add); + } + }; + + for (database& db: dbs) + add (db, add); + + // Collect all the available packages from all the collected databases. + // + vector<pair<shared_ptr<available_package>, + lazy_shared_ptr<repository_fragment>>> r; + + for (database& db: all_dbs) + { + for (shared_ptr<available_package> ap: + pointer_result ( + query_available (db, name, nullopt /* version_constraint */))) + { + // An available package should come from at least one fetched + // repository fragment. + // + assert (!ap->locations.empty ()); + + // All repository fragments the package comes from are equally good, so + // we pick the first one. + // + r.emplace_back (move (ap), ap->locations[0].repository_fragment); + } + } + + // Sort the result in the package version descending order and suppress + // duplicates and, if requested, older package revisions. + // + sort_dedup (r, suppress_older_revisions); + + return r; + } + pair<shared_ptr<available_package>, lazy_shared_ptr<repository_fragment>> make_available_fragment (const common_options& options, diff --git a/bpkg/package-query.hxx b/bpkg/package-query.hxx index ebe92ac..1919058 100644 --- a/bpkg/package-query.hxx +++ b/bpkg/package-query.hxx @@ -75,8 +75,8 @@ namespace bpkg // Try to find packages that optionally satisfy the specified version // constraint in multiple databases, suppressing duplicates. Return the list // of packages and repository fragments in which each was found in the - // package version descending or empty list if none were found. Note that a - // stub satisfies any constraint. + // package version descending order or empty list if none were found. Note + // that a stub satisfies any constraint. // // Note that we return (loaded) lazy_shared_ptr in order to also convey // the database to which it belongs. @@ -173,6 +173,21 @@ namespace bpkg database&, const shared_ptr<selected_package>&); + // Try to find packages in multiple databases, traversing the explicitly and + // implicitly linked databases recursively and suppressing duplicates and, + // optionally, older package revisions. Return the list of packages and + // repository fragments in which each was found in the package version + // descending order or empty list if none were found. + // + // Note that we return (loaded) lazy_shared_ptr in order to also convey + // the database to which it belongs. + // + vector<pair<shared_ptr<available_package>, + lazy_shared_ptr<repository_fragment>>> + find_available_all (const linked_databases&, + const package_name&, + bool suppress_older_revisions = true); + // Create a transient (or fake, if you prefer) available_package object // corresponding to the specified selected object. Note that the package // locations list is left empty and that the returned repository fragment |