diff options
-rw-r--r-- | bpkg/package.cxx | 41 | ||||
-rw-r--r-- | bpkg/rep-fetch.cxx | 14 | ||||
-rw-r--r-- | tests/common/git/state0/libbar.tar | bin | 71680 -> 71680 bytes | |||
-rw-r--r-- | tests/common/git/state0/libfoo.tar | bin | 296960 -> 296960 bytes | |||
-rw-r--r-- | tests/common/git/state0/style-basic.tar | bin | 71680 -> 71680 bytes | |||
-rw-r--r-- | tests/common/git/state0/style.tar | bin | 133120 -> 133120 bytes | |||
-rw-r--r-- | tests/common/git/state1/libbaz.tar | bin | 61440 -> 61440 bytes | |||
-rw-r--r-- | tests/common/git/state1/libfoo.tar | bin | 378880 -> 378880 bytes | |||
-rw-r--r-- | tests/common/git/state1/style-basic.tar | bin | 71680 -> 71680 bytes | |||
-rw-r--r-- | tests/common/git/state1/style.tar | bin | 133120 -> 133120 bytes | |||
-rw-r--r-- | tests/pkg-status.test | 51 | ||||
l--------- | tests/pkg-status/git/libbar.tar | 1 | ||||
l--------- | tests/pkg-status/git/style-basic.tar | 1 | ||||
l--------- | tests/pkg-status/git/style.tar | 1 |
14 files changed, 98 insertions, 11 deletions
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<reference_wrapper<const shared_ptr<repository>>>; + static shared_ptr<repository> find (const shared_ptr<repository>& r, const shared_ptr<available_package>& ap, - bool prereq = true) + repositories& chain) { + auto pr = [&r] (const shared_ptr<repository>& 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<repositories, void (*)(repositories*)> 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<repository> r = find (cr.load (), ap, false)) + if (shared_ptr<repository> r = find (cr.load (), ap, chain)) return r; } @@ -68,7 +87,7 @@ namespace bpkg { for (const lazy_weak_ptr<repository>& pr: ps) { - if (shared_ptr<repository> r = find (pr.load (), ap, false)) + if (shared_ptr<repository> r = find (pr.load (), ap, chain)) return r; } } @@ -77,6 +96,14 @@ namespace bpkg return nullptr; } + static inline shared_ptr<repository> + find (const shared_ptr<repository>& r, + const shared_ptr<available_package>& ap) + { + repositories chain; + return find (r, ap, chain); + } + vector<shared_ptr<available_package>> filter (const shared_ptr<repository>& r, result<available_package>&& apr) { diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx index 029db1d..e78ae064 100644 --- a/bpkg/rep-fetch.cxx +++ b/bpkg/rep-fetch.cxx @@ -367,6 +367,7 @@ namespace bpkg case repository_type::git: return rep_fetch_git (co, conf, rl, iu); } + assert (false); // Can't be here. return rep_fetch_data (); } @@ -500,6 +501,19 @@ namespace bpkg } } + // For git repositories that have neither prerequisites nor complements + // we use the root repository as the default complement. + // + // This supports the common use case where the user has a single-package + // git repository and doesn't want to bother with the repositories file. + // This way their package will still pick up its dependencies from the + // configuration, without regards from which repositories they came from. + // + if (rl.type () == repository_type::git && + r->complements.empty () && + r->prerequisites.empty ()) + r->complements.insert (lazy_shared_ptr<repository> (db, root)); + // "Suspend" session while persisting packages to reduce memory // consumption. // diff --git a/tests/common/git/state0/libbar.tar b/tests/common/git/state0/libbar.tar Binary files differindex e78ae06e..1046f4b 100644 --- a/tests/common/git/state0/libbar.tar +++ b/tests/common/git/state0/libbar.tar diff --git a/tests/common/git/state0/libfoo.tar b/tests/common/git/state0/libfoo.tar Binary files differindex 141a341..d917a68 100644 --- a/tests/common/git/state0/libfoo.tar +++ b/tests/common/git/state0/libfoo.tar diff --git a/tests/common/git/state0/style-basic.tar b/tests/common/git/state0/style-basic.tar Binary files differindex 217ee7c..a16e009 100644 --- a/tests/common/git/state0/style-basic.tar +++ b/tests/common/git/state0/style-basic.tar diff --git a/tests/common/git/state0/style.tar b/tests/common/git/state0/style.tar Binary files differindex fc3faa0..0d40071 100644 --- a/tests/common/git/state0/style.tar +++ b/tests/common/git/state0/style.tar diff --git a/tests/common/git/state1/libbaz.tar b/tests/common/git/state1/libbaz.tar Binary files differindex 373863e..74661aa 100644 --- a/tests/common/git/state1/libbaz.tar +++ b/tests/common/git/state1/libbaz.tar diff --git a/tests/common/git/state1/libfoo.tar b/tests/common/git/state1/libfoo.tar Binary files differindex 23275c8..276e6ba 100644 --- a/tests/common/git/state1/libfoo.tar +++ b/tests/common/git/state1/libfoo.tar diff --git a/tests/common/git/state1/style-basic.tar b/tests/common/git/state1/style-basic.tar Binary files differindex e4e14e9..ad067f4 100644 --- a/tests/common/git/state1/style-basic.tar +++ b/tests/common/git/state1/style-basic.tar diff --git a/tests/common/git/state1/style.tar b/tests/common/git/state1/style.tar Binary files differindex 52389c3..67bcb87 100644 --- a/tests/common/git/state1/style.tar +++ b/tests/common/git/state1/style.tar diff --git a/tests/pkg-status.test b/tests/pkg-status.test index 3c00e97..3e27294 100644 --- a/tests/pkg-status.test +++ b/tests/pkg-status.test @@ -2,7 +2,7 @@ # copyright : Copyright (c) 2014-2017 Code Synthesis Ltd # license : MIT; see accompanying LICENSE file -.include common.test config.test remote.test +.include common.test config.test remote.test remote-git.test # Source repository: # @@ -10,17 +10,25 @@ # |-- extra -> stable (prerequisite) # | |-- libbar-1.1.0+1.tar.gz # | `-- repositories +# | # |-- stable # | |-- libbar-1.0.0.tar.gz # | |-- libfoo-1.0.0.tar.gz # | `-- repositories +# | # |-- testing -> stable (complement), extra (prerequisite) # | |-- libbar-1.0.0+1.tar.gz # | |-- libbar-1.1.0.tar.gz # | `-- repositories -# `-- unstable -> testing (complement) -# |-- libbar-2.0.0.tar.gz -# `-- repositories +# | +# |-- unstable -> testing (complement) +# | |-- libbar-2.0.0.tar.gz +# | `-- repositories +# | +# `-- git +# |-- libbar.git -> style-basic.git (prerequisite) +# |-- style-basic.git +# `-- style.git # Prepare repositories used by tests if running in the local mode. # @@ -31,6 +39,12 @@ cp -r $src/stable $out/stable && $c $out/stable &$out/stable/packages cp -r $src/testing $out/testing && $c $out/testing &$out/testing/packages cp -r $src/unstable $out/unstable && $c $out/unstable &$out/unstable/packages + + # Create git repositories. + # + $git_extract $src/git/style.tar + $git_extract $src/git/libbar.tar + $git_extract $src/git/style-basic.tar &$out_git/state0/*** end pkg_fetch += 2>! @@ -158,3 +172,32 @@ rep_fetch += -d cfg --auth all --trust-yes 2>! $* -d ../fetched2 libbar >'fetched 2.0.0; available sys:?' } } + +: git-repos +: +if ($git_supported != true) +{ + # Skip git repository tests. + # +} +else +{ + rep = "$rep_git/state0" + rep_add += -d cfg 2>! + test.cleanups += &cfg/.bpkg/repositories/*/*** + + : complement-cycle + : + : Make sure that we properly handle the root<->style repository dependency + : cycle while searching for the style-basic package, that is an available + : package but not from the user-added repository (or its complement), and so + : is not visible for the status command. Note that the root repository is the + : default complement for git repositories (see rep_fetch() implementation for + : the reasoning). + : + $clone_root_cfg; + $rep_add "$rep/libbar.git#master" && $rep_add "$rep/style.git#master"; + $rep_fetch; + + $* style-basic >'unknown' +} diff --git a/tests/pkg-status/git/libbar.tar b/tests/pkg-status/git/libbar.tar new file mode 120000 index 0000000..67ccdb1 --- /dev/null +++ b/tests/pkg-status/git/libbar.tar @@ -0,0 +1 @@ +../../common/git/state0/libbar.tar
\ No newline at end of file diff --git a/tests/pkg-status/git/style-basic.tar b/tests/pkg-status/git/style-basic.tar new file mode 120000 index 0000000..2833f83 --- /dev/null +++ b/tests/pkg-status/git/style-basic.tar @@ -0,0 +1 @@ +../../common/git/state0/style-basic.tar
\ No newline at end of file diff --git a/tests/pkg-status/git/style.tar b/tests/pkg-status/git/style.tar new file mode 120000 index 0000000..948d152 --- /dev/null +++ b/tests/pkg-status/git/style.tar @@ -0,0 +1 @@ +../../common/git/state0/style.tar
\ No newline at end of file |