aboutsummaryrefslogtreecommitdiff
path: root/bpkg/package.cxx
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 /bpkg/package.cxx
parent86700536f5ca500c4a837d03626f672dcfdbb97d (diff)
Fix build order for test and main packages
Diffstat (limited to 'bpkg/package.cxx')
-rw-r--r--bpkg/package.cxx88
1 files changed, 86 insertions, 2 deletions
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