aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/package.cxx41
-rw-r--r--bpkg/rep-fetch.cxx14
-rw-r--r--tests/common/git/state0/libbar.tarbin71680 -> 71680 bytes
-rw-r--r--tests/common/git/state0/libfoo.tarbin296960 -> 296960 bytes
-rw-r--r--tests/common/git/state0/style-basic.tarbin71680 -> 71680 bytes
-rw-r--r--tests/common/git/state0/style.tarbin133120 -> 133120 bytes
-rw-r--r--tests/common/git/state1/libbaz.tarbin61440 -> 61440 bytes
-rw-r--r--tests/common/git/state1/libfoo.tarbin378880 -> 378880 bytes
-rw-r--r--tests/common/git/state1/style-basic.tarbin71680 -> 71680 bytes
-rw-r--r--tests/common/git/state1/style.tarbin133120 -> 133120 bytes
-rw-r--r--tests/pkg-status.test51
l---------tests/pkg-status/git/libbar.tar1
l---------tests/pkg-status/git/style-basic.tar1
l---------tests/pkg-status/git/style.tar1
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
index e78ae06e..1046f4b 100644
--- a/tests/common/git/state0/libbar.tar
+++ b/tests/common/git/state0/libbar.tar
Binary files differ
diff --git a/tests/common/git/state0/libfoo.tar b/tests/common/git/state0/libfoo.tar
index 141a341..d917a68 100644
--- a/tests/common/git/state0/libfoo.tar
+++ b/tests/common/git/state0/libfoo.tar
Binary files differ
diff --git a/tests/common/git/state0/style-basic.tar b/tests/common/git/state0/style-basic.tar
index 217ee7c..a16e009 100644
--- a/tests/common/git/state0/style-basic.tar
+++ b/tests/common/git/state0/style-basic.tar
Binary files differ
diff --git a/tests/common/git/state0/style.tar b/tests/common/git/state0/style.tar
index fc3faa0..0d40071 100644
--- a/tests/common/git/state0/style.tar
+++ b/tests/common/git/state0/style.tar
Binary files differ
diff --git a/tests/common/git/state1/libbaz.tar b/tests/common/git/state1/libbaz.tar
index 373863e..74661aa 100644
--- a/tests/common/git/state1/libbaz.tar
+++ b/tests/common/git/state1/libbaz.tar
Binary files differ
diff --git a/tests/common/git/state1/libfoo.tar b/tests/common/git/state1/libfoo.tar
index 23275c8..276e6ba 100644
--- a/tests/common/git/state1/libfoo.tar
+++ b/tests/common/git/state1/libfoo.tar
Binary files differ
diff --git a/tests/common/git/state1/style-basic.tar b/tests/common/git/state1/style-basic.tar
index e4e14e9..ad067f4 100644
--- a/tests/common/git/state1/style-basic.tar
+++ b/tests/common/git/state1/style-basic.tar
Binary files differ
diff --git a/tests/common/git/state1/style.tar b/tests/common/git/state1/style.tar
index 52389c3..67bcb87 100644
--- a/tests/common/git/state1/style.tar
+++ b/tests/common/git/state1/style.tar
Binary files differ
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