From 11dfd8bc4022b6596c2158594f18544a1f7ffa3e Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sat, 17 Feb 2018 16:04:58 +0300 Subject: Use root repository as a default complement for git repository --- bpkg/package.cxx | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'bpkg/package.cxx') diff --git a/bpkg/package.cxx b/bpkg/package.cxx index 1c98f42..c7c40a1 100644 --- a/bpkg/package.cxx +++ b/bpkg/package.cxx @@ -24,16 +24,35 @@ namespace bpkg // available_package // - // Check if the package is available from the specified repository, - // its prerequisite repositories, or one of their complements, - // recursively. Return the first repository that contains the - // package or NULL if none are. + // Check if the package is available from the specified repository, its + // prerequisite repositories, or one of their complements, recursively. + // Return the first repository that contains the package or NULL if none + // are. // + // Note that we can end up with a repository dependency cycle since the + // root repository can be the default complement for git repositories (see + // rep_fetch() implementation for details). Thus we need to make sure that + // the repository is not in the dependency chain yet. + // + using repositories = vector>>; + static shared_ptr find (const shared_ptr& r, const shared_ptr& ap, - bool prereq = true) + repositories& chain) { + auto pr = [&r] (const shared_ptr& i) -> bool {return i == r;}; + auto i (find_if (chain.begin (), chain.end (), pr)); + + if (i != chain.end ()) + return nullptr; + + bool prereq (chain.empty ()); // Check prerequisites in top-level only. + chain.emplace_back (r); + + unique_ptr deleter ( + &chain, [] (repositories* r) {r->pop_back ();}); + const auto& ps (r->prerequisites); const auto& cs (r->complements); @@ -60,7 +79,7 @@ namespace bpkg // Should we consider prerequisites of our complements as our // prerequisites? I'd say not. // - if (shared_ptr r = find (cr.load (), ap, false)) + if (shared_ptr r = find (cr.load (), ap, chain)) return r; } @@ -68,7 +87,7 @@ namespace bpkg { for (const lazy_weak_ptr& pr: ps) { - if (shared_ptr r = find (pr.load (), ap, false)) + if (shared_ptr r = find (pr.load (), ap, chain)) return r; } } @@ -77,6 +96,14 @@ namespace bpkg return nullptr; } + static inline shared_ptr + find (const shared_ptr& r, + const shared_ptr& ap) + { + repositories chain; + return find (r, ap, chain); + } + vector> filter (const shared_ptr& r, result&& apr) { -- cgit v1.1