aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2020-06-24 22:12:01 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2020-06-26 15:29:44 +0300
commit58357d79110a925dcb3cdc734d812f17b6465c17 (patch)
tree2b5f4714e038f1b0cefcca64b427e6ae9772833f
parent86700536f5ca500c4a837d03626f672dcfdbb97d (diff)
Fix build order for test and main packages
-rw-r--r--bpkg/checksum.cxx4
-rw-r--r--bpkg/fetch-git.cxx1
-rw-r--r--bpkg/package.cxx88
-rw-r--r--bpkg/package.hxx132
-rw-r--r--bpkg/package.xml60
-rw-r--r--bpkg/pkg-build.cxx113
-rw-r--r--bpkg/pkg-checkout.cxx5
-rw-r--r--bpkg/pkg-command.cxx2
-rw-r--r--bpkg/pkg-configure.cxx10
-rw-r--r--bpkg/pkg-unpack.cxx4
-rw-r--r--bpkg/rep-create.cxx1
-rw-r--r--bpkg/rep-fetch.cxx69
-rw-r--r--bpkg/rep-info.cxx3
-rw-r--r--bpkg/rep-remove.cxx1
-rw-r--r--bpkg/utility.hxx13
15 files changed, 376 insertions, 130 deletions
diff --git a/bpkg/checksum.cxx b/bpkg/checksum.cxx
index efc86dd..9c52da0 100644
--- a/bpkg/checksum.cxx
+++ b/bpkg/checksum.cxx
@@ -3,10 +3,6 @@
#include <bpkg/checksum.hxx>
-#ifdef _WIN32
-# include <algorithm> // replace()
-#endif
-
#include <bpkg/diagnostics.hxx>
using namespace std;
diff --git a/bpkg/fetch-git.cxx b/bpkg/fetch-git.cxx
index df59dde..2bdd2d5 100644
--- a/bpkg/fetch-git.cxx
+++ b/bpkg/fetch-git.cxx
@@ -4,7 +4,6 @@
#include <bpkg/fetch.hxx>
#include <map>
-#include <algorithm> // find_if(), replace(), sort()
#include <libbutl/git.mxx>
#include <libbutl/utility.mxx> // digit(), xdigit()
diff --git a/bpkg/package.cxx b/bpkg/package.cxx
index 8c3fd19..3532f3d 100644
--- a/bpkg/package.cxx
+++ b/bpkg/package.cxx
@@ -4,8 +4,6 @@
#include <bpkg/package.hxx>
#include <bpkg/package-odb.hxx>
-#include <algorithm> // find_if()
-
#include <bpkg/database.hxx>
#include <bpkg/checksum.hxx>
#include <bpkg/diagnostics.hxx>
@@ -28,6 +26,92 @@ namespace bpkg
// available_package
//
+ odb::result<available_package>
+ query_available (database& db,
+ const package_name& name,
+ const optional<version_constraint>& c,
+ bool order)
+ {
+ using query = query<available_package>;
+
+ query q (query::id.name == name);
+ const auto& vm (query::id.version);
+
+ // If there is a constraint, then translate it to the query. Otherwise,
+ // get the latest version or stub versions if present.
+ //
+ if (c)
+ {
+ assert (c->complete ());
+
+ // If the revision is not explicitly specified, then compare ignoring the
+ // revision. The idea is that when the user runs 'bpkg build libfoo/1'
+ // and there is 1+1 available, it should just work. The user shouldn't
+ // have to spell the revision explicitly. Similarly, when we have
+ // 'depends: libfoo == 1', then it would be strange if 1+1 did not
+ // satisfy this constraint. The same for libfoo <= 1 -- 1+1 should
+ // satisfy.
+ //
+ // Note that we always compare ignoring the iteration, as it can not be
+ // specified in the manifest/command line. This way the latest iteration
+ // will always be picked up.
+ //
+ query qs (compare_version_eq (vm,
+ canonical_version (wildcard_version),
+ false /* revision */,
+ false /* iteration */));
+
+ if (c->min_version &&
+ c->max_version &&
+ *c->min_version == *c->max_version)
+ {
+ const version& v (*c->min_version);
+
+ q = q &&
+ (compare_version_eq (vm,
+ canonical_version (v),
+ v.revision.has_value (),
+ false /* iteration */) ||
+ qs);
+ }
+ else
+ {
+ query qr (true);
+
+ if (c->min_version)
+ {
+ const version& v (*c->min_version);
+ canonical_version cv (v);
+ bool rv (v.revision);
+
+ if (c->min_open)
+ qr = compare_version_gt (vm, cv, rv, false /* iteration */);
+ else
+ qr = compare_version_ge (vm, cv, rv, false /* iteration */);
+ }
+
+ if (c->max_version)
+ {
+ const version& v (*c->max_version);
+ canonical_version cv (v);
+ bool rv (v.revision);
+
+ if (c->max_open)
+ qr = qr && compare_version_lt (vm, cv, rv, false /* iteration */);
+ else
+ qr = qr && compare_version_le (vm, cv, rv, false /* iteration */);
+ }
+
+ q = q && (qr || qs);
+ }
+ }
+
+ if (order)
+ q += order_by_version_desc (vm);
+
+ return db.query<available_package> (q);
+ }
+
// Check if the package is available from the specified repository fragment,
// its prerequisite repositories, or one of their complements, recursively.
// Return the first repository fragment that contains the package or NULL if
diff --git a/bpkg/package.hxx b/bpkg/package.hxx
index 8987069..f10e670 100644
--- a/bpkg/package.hxx
+++ b/bpkg/package.hxx
@@ -27,7 +27,7 @@
//
#define DB_SCHEMA_VERSION_BASE 5
-#pragma db model version(DB_SCHEMA_VERSION_BASE, 6, closed)
+#pragma db model version(DB_SCHEMA_VERSION_BASE, 7, closed)
namespace bpkg
{
@@ -446,7 +446,61 @@ namespace bpkg
#pragma db member(dependency::constraint) column("")
#pragma db value(dependency_alternatives) definition
- using dependencies = vector<dependency_alternatives>;
+ // Extend dependency_alternatives to also represent the special test
+ // dependencies of the test packages to the main packages, produced by
+ // inverting the main packages external test dependencies (specified with
+ // the tests, etc., manifest values).
+ //
+ #pragma db value
+ class dependency_alternatives_ex: public dependency_alternatives
+ {
+ public:
+ optional<test_dependency_type> type;
+
+ dependency_alternatives_ex () = default;
+
+ // Create the regular dependency alternatives object.
+ //
+ dependency_alternatives_ex (dependency_alternatives da)
+ : dependency_alternatives (move (da)) {}
+
+ // Create the special test dependencies object (built incrementally).
+ //
+ dependency_alternatives_ex (test_dependency_type t)
+ : dependency_alternatives (false /* conditional */,
+ false /* buildtime */,
+ "" /* comment */),
+ type (t) {}
+ };
+
+ using dependencies = vector<dependency_alternatives_ex>;
+
+ // Convert the regular dependency alternatives list (normally comes from a
+ // package manifest) to the extended version of it (see above).
+ //
+ inline dependencies
+ convert (vector<dependency_alternatives>&& das)
+ {
+ return dependencies (make_move_iterator (das.begin ()),
+ make_move_iterator (das.end ()));
+ }
+
+ // tests
+ //
+ #pragma db value(test_dependency) definition
+
+ using optional_test_dependency_type = optional<test_dependency_type>;
+
+ #pragma db map type(test_dependency_type) as(string) \
+ to(to_string (?)) \
+ from(bpkg::to_test_dependency_type (?))
+
+ #pragma db map type(optional_test_dependency_type) \
+ as(bpkg::optional_string) \
+ to((?) ? to_string (*(?)) : bpkg::optional_string ()) \
+ from((?) \
+ ? bpkg::to_test_dependency_type (*(?)) \
+ : bpkg::optional_test_dependency_type ())
// Wildcard version. Satisfies any version constraint and is represented as
// 0+0 (which is also the "stub version"; since a real version is always
@@ -498,12 +552,17 @@ namespace bpkg
//
small_vector<package_location, 1> locations;
- // Package manifest data.
+ // Package manifest data and, potentially, the special test dependencies.
+ //
+ // Note that there can be only one special test dependencies entry in the
+ // list and it's always the last one, if present.
//
using dependencies_type = bpkg::dependencies;
dependencies_type dependencies;
+ small_vector<test_dependency, 1> tests;
+
// Present for non-transient objects only (and only for certain repository
// types).
//
@@ -519,7 +578,8 @@ namespace bpkg
available_package (package_manifest&& m)
: id (move (m.name), m.version),
version (move (m.version)),
- dependencies (move (m.dependencies)),
+ dependencies (convert (move (m.dependencies))),
+ tests (move (m.tests)),
sha256sum (move (m.sha256sum)) {}
// Create available stub package.
@@ -596,8 +656,8 @@ namespace bpkg
// dependencies
//
- using _dependency_key = odb::nested_key<dependency_alternatives>;
- using _dependency_alternatives_type =
+ using _dependency_key = odb::nested_key<dependency_alternatives_ex>;
+ using _dependency_alternatives_ex_type =
std::map<_dependency_key, dependency>;
#pragma db value(_dependency_key)
@@ -605,13 +665,18 @@ namespace bpkg
#pragma db member(_dependency_key::inner) column("index")
#pragma db member(dependencies) id_column("") value_column("")
- #pragma db member(dependency_alternatives) \
- virtual(_dependency_alternatives_type) \
+ #pragma db member(dependency_alternatives_ex) \
+ table("available_package_dependency_alternatives") \
+ virtual(_dependency_alternatives_ex_type) \
after(dependencies) \
get(odb::nested_get (this.dependencies)) \
set(odb::nested_set (this.dependencies, std::move (?))) \
id_column("") key_column("") value_column("dep_")
+ // tests
+ //
+ #pragma db member(tests) id_column("") value_column("test_")
+
private:
friend class odb::access;
available_package () = default;
@@ -626,6 +691,57 @@ namespace bpkg
operator size_t () const {return result;}
};
+ // Return the list of available test packages, that is, that are referred to
+ // as external tests by some main package(s).
+ //
+ // Note that there can be only one test dependency row per package, so the
+ // DISTINCT clause is not required.
+ //
+ #pragma db view object(available_package = package) \
+ table("available_package_dependencies" = "pd" inner: \
+ "pd.type IN ('tests', 'examples', 'benchmarks') AND " \
+ "pd.name = " + package::id.name + "AND" + \
+ "pd.version_epoch = " + package::id.version.epoch + "AND" + \
+ "pd.version_canonical_upstream = " + \
+ package::id.version.canonical_upstream + "AND" + \
+ "pd.version_canonical_release = " + \
+ package::id.version.canonical_release + "AND" + \
+ "pd.version_revision = " + package::id.version.revision + "AND" + \
+ "pd.version_iteration = " + package::id.version.iteration)
+ struct available_test
+ {
+ shared_ptr<available_package> package;
+ };
+
+ // Return the list of available main packages, that is, that refer to some
+ // external test packages.
+ //
+ #pragma db view object(available_package = package) \
+ table("available_package_tests" = "pt" inner: \
+ "pt.name = " + package::id.name + "AND" + \
+ "pt.version_epoch = " + package::id.version.epoch + "AND" + \
+ "pt.version_canonical_upstream = " + \
+ package::id.version.canonical_upstream + "AND" + \
+ "pt.version_canonical_release = " + \
+ package::id.version.canonical_release + "AND" + \
+ "pt.version_revision = " + package::id.version.revision + "AND" + \
+ "pt.version_iteration = " + package::id.version.iteration) \
+ query(distinct)
+ struct available_main
+ {
+ shared_ptr<available_package> package;
+ };
+
+ // Query the available packages that optionally satisfy the specified
+ // version constraint and return them in the version descending order, by
+ // default. Note that a stub satisfies any constraint.
+ //
+ odb::result<available_package>
+ query_available (database&,
+ const package_name&,
+ const optional<version_constraint>&,
+ bool order = true);
+
// Only return packages that are in the specified repository fragments, their
// complements or prerequisites (if prereq is true), recursively. While you
// could maybe come up with a (barely comprehensible) view/query to achieve
diff --git a/bpkg/package.xml b/bpkg/package.xml
index 2856be1..ed5dd64 100644
--- a/bpkg/package.xml
+++ b/bpkg/package.xml
@@ -1,4 +1,64 @@
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="sqlite" version="1">
+ <changeset version="7">
+ <alter-table name="available_package_dependencies">
+ <add-column name="type" type="TEXT" null="true"/>
+ </alter-table>
+ <add-table name="available_package_tests" kind="container">
+ <column name="name" type="TEXT" null="true" options="COLLATE NOCASE"/>
+ <column name="version_epoch" type="INTEGER" null="true"/>
+ <column name="version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="version_canonical_release" type="TEXT" null="true" options="COLLATE BINARY"/>
+ <column name="version_revision" type="INTEGER" null="true"/>
+ <column name="version_iteration" type="INTEGER" null="true"/>
+ <column name="index" type="INTEGER" null="true"/>
+ <column name="test_name" type="TEXT" null="true" options="COLLATE NOCASE"/>
+ <column name="test_min_version_epoch" type="INTEGER" null="true"/>
+ <column name="test_min_version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="test_min_version_canonical_release" type="TEXT" null="true"/>
+ <column name="test_min_version_revision" type="INTEGER" null="true"/>
+ <column name="test_min_version_iteration" type="INTEGER" null="true"/>
+ <column name="test_min_version_upstream" type="TEXT" null="true"/>
+ <column name="test_min_version_release" type="TEXT" null="true"/>
+ <column name="test_max_version_epoch" type="INTEGER" null="true"/>
+ <column name="test_max_version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="test_max_version_canonical_release" type="TEXT" null="true"/>
+ <column name="test_max_version_revision" type="INTEGER" null="true"/>
+ <column name="test_max_version_iteration" type="INTEGER" null="true"/>
+ <column name="test_max_version_upstream" type="TEXT" null="true"/>
+ <column name="test_max_version_release" type="TEXT" null="true"/>
+ <column name="test_min_open" type="INTEGER" null="true"/>
+ <column name="test_max_open" type="INTEGER" null="true"/>
+ <column name="test_type" type="TEXT" null="true"/>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <column name="version_iteration"/>
+ <references table="available_package">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <column name="version_iteration"/>
+ </references>
+ </foreign-key>
+ <index name="available_package_tests_object_id_i">
+ <column name="name"/>
+ <column name="version_epoch"/>
+ <column name="version_canonical_upstream"/>
+ <column name="version_canonical_release"/>
+ <column name="version_revision"/>
+ <column name="version_iteration"/>
+ </index>
+ <index name="available_package_tests_index_i">
+ <column name="index"/>
+ </index>
+ </add-table>
+ </changeset>
+
<changeset version="6"/>
<model version="5">
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index 106666a..3ef513a 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -8,7 +8,6 @@
#include <list>
#include <cstring> // strlen()
#include <iostream> // cout
-#include <algorithm> // find_if()
#include <libbutl/standard-version.mxx>
@@ -42,95 +41,6 @@ namespace bpkg
// - Configuration vars (both passed and preserved)
//
- // Query the available packages that optionally satisfy the specified
- // version constraint and return them in the version descending order. Note
- // that a stub satisfies any constraint. Note also that this function does
- // not return the extra stubs from the imaginary system repository (use one
- // of the find_available*() overloads instead).
- //
- static odb::result<available_package>
- query_available (database& db,
- const package_name& name,
- const optional<version_constraint>& c)
- {
- using query = query<available_package>;
-
- query q (query::id.name == name);
- const auto& vm (query::id.version);
-
- // If there is a constraint, then translate it to the query. Otherwise,
- // get the latest version or stub versions if present.
- //
- if (c)
- {
- assert (c->complete ());
-
- // If the revision is not explicitly specified, then compare ignoring the
- // revision. The idea is that when the user runs 'bpkg build libfoo/1'
- // and there is 1+1 available, it should just work. The user shouldn't
- // have to spell the revision explicitly. Similarly, when we have
- // 'depends: libfoo == 1', then it would be strange if 1+1 did not
- // satisfy this constraint. The same for libfoo <= 1 -- 1+1 should
- // satisfy.
- //
- // Note that we always compare ignoring the iteration, as it can not be
- // specified in the manifest/command line. This way the latest iteration
- // will always be picked up.
- //
- query qs (compare_version_eq (vm,
- canonical_version (wildcard_version),
- false /* revision */,
- false /* iteration */));
-
- if (c->min_version &&
- c->max_version &&
- *c->min_version == *c->max_version)
- {
- const version& v (*c->min_version);
-
- q = q &&
- (compare_version_eq (vm,
- canonical_version (v),
- v.revision.has_value (),
- false /* iteration */) ||
- qs);
- }
- else
- {
- query qr (true);
-
- if (c->min_version)
- {
- const version& v (*c->min_version);
- canonical_version cv (v);
- bool rv (v.revision);
-
- if (c->min_open)
- qr = compare_version_gt (vm, cv, rv, false /* iteration */);
- else
- qr = compare_version_ge (vm, cv, rv, false /* iteration */);
- }
-
- if (c->max_version)
- {
- const version& v (*c->max_version);
- canonical_version cv (v);
- bool rv (v.revision);
-
- if (c->max_open)
- qr = qr && compare_version_lt (vm, cv, rv, false /* iteration */);
- else
- qr = qr && compare_version_le (vm, cv, rv, false /* iteration */);
- }
-
- q = q && (qr || qs);
- }
- }
-
- q += order_by_version_desc (vm);
- return db.query<available_package> (q);
- }
-
// Try to find an available stub package in the imaginary system repository.
// Such a repository contains stubs corresponding to the system packages
// specified by the user on the command line with version information
@@ -841,7 +751,7 @@ namespace bpkg
const shared_ptr<repository_fragment>& af (pkg.repository_fragment);
const package_name& name (ap->id.name);
- for (const dependency_alternatives& da: ap->dependencies)
+ for (const dependency_alternatives_ex& da: ap->dependencies)
{
if (da.conditional) // @@ TODO
fail << "conditional dependencies are not yet supported";
@@ -1018,6 +928,17 @@ namespace bpkg
// the conservative choice and the user can always override it by
// explicitly building libhello.
//
+ // Note though, that if this is a test package, then its special
+ // test dependencies (main packages that refer to it) should be
+ // searched upstream through the complement repositories
+ // recursively, since the test packages may only belong to the main
+ // package's repository and its complements.
+ //
+ // @@ Currently we don't implement the reverse direction search for
+ // the test dependencies, effectively only supporting the common
+ // case where the main and test packages belong to the same
+ // repository. Will need to fix this eventually.
+ //
// Note that this logic (naturally) does not apply if the package is
// already selected by the user (see above).
//
@@ -1709,7 +1630,7 @@ namespace bpkg
// be built in the order that is as close to the manifest as
// possible.
//
- for (const dependency_alternatives& da:
+ for (const dependency_alternatives_ex& da:
reverse_iterate (ap->dependencies))
{
assert (!da.conditional && da.size () == 1); // @@ TODO
@@ -4901,7 +4822,13 @@ namespace bpkg
true /* ignore_unknown */,
[&sp] (version& v) {v = sp->version;}));
- pkg_configure (c, o, t, sp, m.dependencies, p.config_vars, simulate);
+ pkg_configure (c,
+ o,
+ t,
+ sp,
+ convert (move (m.dependencies)),
+ p.config_vars,
+ simulate);
}
assert (sp->state == package_state::configured);
diff --git a/bpkg/pkg-checkout.cxx b/bpkg/pkg-checkout.cxx
index 60a30ae..05875a4 100644
--- a/bpkg/pkg-checkout.cxx
+++ b/bpkg/pkg-checkout.cxx
@@ -226,7 +226,10 @@ namespace bpkg
true /* ignore_unknown */,
[&ap] (version& v) {v = ap->version;}));
- pkg_configure_prerequisites (o, t, m.dependencies, m.name);
+ pkg_configure_prerequisites (o,
+ t,
+ convert (move (m.dependencies)),
+ m.name);
// Form the buildspec.
//
diff --git a/bpkg/pkg-command.cxx b/bpkg/pkg-command.cxx
index 6f330a6..0828118 100644
--- a/bpkg/pkg-command.cxx
+++ b/bpkg/pkg-command.cxx
@@ -3,8 +3,6 @@
#include <bpkg/pkg-command.hxx>
-#include <algorithm> // find_if()
-
#include <bpkg/package.hxx>
#include <bpkg/package-odb.hxx>
#include <bpkg/database.hxx>
diff --git a/bpkg/pkg-configure.cxx b/bpkg/pkg-configure.cxx
index 225291b..cd55575 100644
--- a/bpkg/pkg-configure.cxx
+++ b/bpkg/pkg-configure.cxx
@@ -28,7 +28,7 @@ namespace bpkg
database& db (t.database ());
- for (const dependency_alternatives& da: deps)
+ for (const dependency_alternatives_ex& da: deps)
{
assert (!da.conditional); //@@ TODO
@@ -319,7 +319,13 @@ namespace bpkg
true /* ignore_unknown */,
[&p] (version& v) {v = p->version;}));
- pkg_configure (c, o, t, p, m.dependencies, vars, false /* simulate */);
+ pkg_configure (c,
+ o,
+ t,
+ p,
+ convert (move (m.dependencies)),
+ vars,
+ false /* simulate */);
}
if (verb && !o.no_result ())
diff --git a/bpkg/pkg-unpack.cxx b/bpkg/pkg-unpack.cxx
index 10f8920..b8ac08e 100644
--- a/bpkg/pkg-unpack.cxx
+++ b/bpkg/pkg-unpack.cxx
@@ -3,10 +3,6 @@
#include <bpkg/pkg-unpack.hxx>
-#ifdef _WIN32
-# include <algorithm> // replace()
-#endif
-
#include <libbpkg/manifest.hxx>
#include <bpkg/archive.hxx>
diff --git a/bpkg/rep-create.cxx b/bpkg/rep-create.cxx
index 0ca2e5f..f47bc09 100644
--- a/bpkg/rep-create.cxx
+++ b/bpkg/rep-create.cxx
@@ -4,7 +4,6 @@
#include <bpkg/rep-create.hxx>
#include <map>
-#include <algorithm> // count_if()
#include <libbutl/filesystem.mxx> // dir_iterator
#include <libbutl/manifest-serializer.mxx>
diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx
index 1b8e00a..b58ef2c 100644
--- a/bpkg/rep-fetch.cxx
+++ b/bpkg/rep-fetch.cxx
@@ -5,7 +5,6 @@
#include <map>
#include <set>
-#include <algorithm> // equal()
#include <libbutl/manifest-parser.mxx>
@@ -1273,8 +1272,8 @@ namespace bpkg
}
}
- // Finally, make sure that the external packages are available from a
- // single directory-based repository.
+ // Make sure that the external packages are available from a single
+ // directory-based repository.
//
// Sort the packages by name and version. This way the external packages
// with the same upstream version and revision will be adjacent. Note
@@ -1324,6 +1323,70 @@ namespace bpkg
ap = id;
rf = f;
}
+
+ // Finally, invert the main packages external test dependencies into the
+ // the test packages special test dependencies.
+ //
+ // But first, remove the existing (and possibly outdated) special test
+ // dependencies from the test packages, unless all the available
+ // packages are (re)created from scratch.
+ //
+ if (!full_fetch)
+ {
+ for (const auto& at: db.query<available_test> ())
+ {
+ dependencies& ds (at.package->dependencies);
+
+ // Note that the special test dependencies entry is always the last
+ // one, if present.
+ //
+ assert (!ds.empty () && ds.back ().type);
+
+ ds.pop_back ();
+
+ db.update (at.package);
+ }
+ }
+
+ // Go through the available packages that have external tests and add
+ // them as the special test dependencies to these test packages.
+ //
+ for (const auto& am: db.query<available_main> ())
+ {
+ const shared_ptr<available_package>& p (am.package);
+
+ vector<shared_ptr<repository_fragment>> rfs;
+
+ for (const package_location& pl: p->locations)
+ rfs.push_back (pl.repository_fragment.load ());
+
+ for (const test_dependency& td: p->tests)
+ {
+ vector<pair<shared_ptr<available_package>,
+ shared_ptr<repository_fragment>>> tps (
+ filter (rfs,
+ query_available (db,
+ td.name,
+ td.constraint,
+ false /* order */),
+ false /* prereq */));
+
+ for (const auto& t: tps)
+ {
+ const shared_ptr<available_package>& tp (t.first);
+
+ dependencies& ds (tp->dependencies);
+
+ if (ds.empty () || !ds.back ().type)
+ ds.push_back (dependency_alternatives_ex (td.type));
+
+ ds.back ().push_back (
+ dependency {p->id.name, version_constraint (p->version)});
+
+ db.update (tp);
+ }
+ }
+ }
}
catch (const failed&)
{
diff --git a/bpkg/rep-info.cxx b/bpkg/rep-info.cxx
index 6c0c7d5..1a23528 100644
--- a/bpkg/rep-info.cxx
+++ b/bpkg/rep-info.cxx
@@ -3,8 +3,7 @@
#include <bpkg/rep-info.hxx>
-#include <iostream> // cout
-#include <algorithm> // find_if()
+#include <iostream> // cout
#include <libbutl/sha256.mxx> // sha256_to_fingerprint()
#include <libbutl/manifest-serializer.mxx>
diff --git a/bpkg/rep-remove.cxx b/bpkg/rep-remove.cxx
index c0b67b6..c377fc5 100644
--- a/bpkg/rep-remove.cxx
+++ b/bpkg/rep-remove.cxx
@@ -4,7 +4,6 @@
#include <bpkg/rep-remove.hxx>
#include <set>
-#include <algorithm> // find()
#include <libbutl/filesystem.mxx> // dir_iterator
diff --git a/bpkg/utility.hxx b/bpkg/utility.hxx
index e891f21..4360118 100644
--- a/bpkg/utility.hxx
+++ b/bpkg/utility.hxx
@@ -4,12 +4,13 @@
#ifndef BPKG_UTILITY_HXX
#define BPKG_UTILITY_HXX
-#include <memory> // make_shared()
-#include <string> // to_string()
-#include <cstring> // strcmp(), strchr()
-#include <utility> // move(), forward(), declval(), make_pair()
-#include <cassert> // assert()
-#include <iterator> // make_move_iterator()
+#include <memory> // make_shared()
+#include <string> // to_string()
+#include <cstring> // strcmp(), strchr()
+#include <utility> // move(), forward(), declval(), make_pair()
+#include <cassert> // assert()
+#include <iterator> // make_move_iterator()
+#include <algorithm> // *
#include <libbutl/ft/lang.hxx>