aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-12-30 20:24:29 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-01-08 16:51:05 +0200
commit4b074f21d097e02a8343a4c1d8ad48e6661d622a (patch)
tree625d0c129276a22e43fb840a36e3bc6af300901d
parent02ca7e6b7bb7c01659adba36944e59262f307b06 (diff)
Support package dependency version range
-rw-r--r--bpkg/fetch.cxx2
-rw-r--r--bpkg/help.cxx12
-rw-r--r--bpkg/package58
-rw-r--r--bpkg/package.xml52
-rw-r--r--bpkg/pkg-build.cxx34
-rw-r--r--bpkg/satisfaction.cxx116
6 files changed, 137 insertions, 137 deletions
diff --git a/bpkg/fetch.cxx b/bpkg/fetch.cxx
index f63a6e3..484d014 100644
--- a/bpkg/fetch.cxx
+++ b/bpkg/fetch.cxx
@@ -590,7 +590,7 @@ namespace bpkg
ifs.exceptions (ofstream::badbit | ofstream::failbit);
ofs.exceptions (ofstream::badbit | ofstream::failbit);
- ofs << ifs.rdbuf();
+ ofs << ifs.rdbuf ();
// In case they throw.
//
diff --git a/bpkg/help.cxx b/bpkg/help.cxx
index 3c44c52..16ef4e8 100644
--- a/bpkg/help.cxx
+++ b/bpkg/help.cxx
@@ -33,7 +33,7 @@ using namespace butl;
namespace bpkg
{
- struct pager: protected std::streambuf
+ struct pager: protected streambuf
{
pager (const common_options& co, const string& name)
{
@@ -142,10 +142,10 @@ namespace bpkg
buf_ = stream ().rdbuf (this);
}
- std::ostream&
+ ostream&
stream ()
{
- return os_.is_open () ? os_ : std::cout;
+ return os_.is_open () ? os_ : cout;
}
bool
@@ -168,8 +168,8 @@ namespace bpkg
// streambuf output interface.
//
protected:
- using int_type = std::streambuf::int_type;
- using traits_type = std::streambuf::traits_type;
+ using int_type = streambuf::int_type;
+ using traits_type = streambuf::traits_type;
virtual int_type
overflow (int_type c)
@@ -198,7 +198,7 @@ namespace bpkg
string indent_;
int_type prev_ = '\n'; // Previous character.
- std::streambuf* buf_ = nullptr;
+ streambuf* buf_ = nullptr;
};
int
diff --git a/bpkg/package b/bpkg/package
index 318f09d..99b7924 100644
--- a/bpkg/package
+++ b/bpkg/package
@@ -18,7 +18,7 @@
#include <bpkg/types>
#include <bpkg/utility>
-#pragma db model version(1, 1, open)
+#pragma db model version(2, 2, open)
namespace bpkg
{
@@ -67,7 +67,7 @@ namespace bpkg
string canonical_release;
uint16_t revision;
string upstream;
- string release;
+ optional<string> release;
};
}
@@ -103,31 +103,29 @@ namespace bpkg
{
uint16_t epoch;
string canonical_upstream;
-
- // By a fluke SQLite 3 uses BINARY collation for UTF-8-encoded TEXT columns
- // by default. So no need to adjust it to make "absent" and specified
- // canonical releases to compare properly. But better to keep an eye on
- // it not to miss a moment if SQLite plug UCA-compliant collation.
- // Note: PostgreSQL uses UCA-compliant one by default for UTF8-encoded
- // TEXT columns.
- //
- // Unicode Collation Algorithm (UCA): http://unicode.org/reports/tr10/
- //
string canonical_release;
-
uint16_t revision;
+
+ // By default SQLite3 uses BINARY collation for TEXT columns. So while this
+ // means we don't need to do anything special to make "absent" (~) and
+ // specified canonical releases compare properly, better make it explicit
+ // in case the Unicode Collation Algorithm (UCA, where '~' < 'a') becomes
+ // the default.
+ //
+ #pragma db member(canonical_release) options("COLLATE BINARY")
};
#pragma db value transient
struct upstream_version: version
{
- #pragma db member(upstream_) virtual(string) \
- get(this.upstream) \
- set(this = bpkg::version (0, std::move (?), "~", 0))
+ #pragma db member(upstream_) virtual(string) \
+ get(this.upstream) \
+ set(this = bpkg::version (0, std::move (?), std::string (), 0))
- #pragma db member(release_) virtual(string) \
- get(this.release) \
- set(this = bpkg::version (0, this.upstream, std::move (?), 0))
+ #pragma db member(release_) virtual(optional_string) \
+ get(this.release) \
+ set(this = bpkg::version ( \
+ 0, std::move (this.upstream), std::move (?), 0))
upstream_version () = default;
upstream_version (version v): version (move (v)) {}
@@ -155,6 +153,24 @@ namespace bpkg
std::move ((?).release), \
(?).revision))
+ using optional_version = optional<version>;
+ using _optional_version = optional<_version>;
+
+ #pragma db map type(optional_version) as(_optional_version) \
+ to((?) \
+ ? bpkg::_version{(?)->epoch, \
+ (?)->canonical_upstream, \
+ (?)->canonical_release, \
+ (?)->revision, \
+ (?)->upstream, \
+ (?)->release} \
+ : bpkg::_optional_version ()) \
+ from((?) \
+ ? bpkg::version ((?)->epoch, \
+ std::move ((?)->upstream), \
+ std::move ((?)->release), \
+ (?)->revision) \
+ : bpkg::optional_version ())
// repository_location
//
@@ -236,10 +252,6 @@ namespace bpkg
// dependencies
//
- #pragma db map type(comparison) as(string) \
- to(to_string (?)) \
- from(bpkg::to_comparison (?))
-
#pragma db value(dependency_constraint) definition
#pragma db value(dependency) definition
#pragma db member(dependency::constraint) column("")
diff --git a/bpkg/package.xml b/bpkg/package.xml
index f2c470c..80a4aa7 100644
--- a/bpkg/package.xml
+++ b/bpkg/package.xml
@@ -1,5 +1,5 @@
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="sqlite" version="1">
- <model version="1">
+ <model version="2">
<table name="repository" kind="object">
<column name="name" type="TEXT" null="true"/>
<column name="location" type="TEXT" null="true"/>
@@ -49,7 +49,7 @@
<column name="name" type="TEXT" null="true"/>
<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"/>
+ <column name="version_canonical_release" type="TEXT" null="true" options="COLLATE BINARY"/>
<column name="version_revision" type="INTEGER" null="true"/>
<column name="version_upstream" type="TEXT" null="true"/>
<column name="version_release" type="TEXT" null="true"/>
@@ -65,7 +65,7 @@
<column name="name" type="TEXT" null="true"/>
<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"/>
+ <column name="version_canonical_release" type="TEXT" null="true" options="COLLATE BINARY"/>
<column name="version_revision" type="INTEGER" null="true"/>
<column name="repository" type="TEXT" null="true"/>
<column name="location" type="TEXT" null="true"/>
@@ -101,7 +101,7 @@
<column name="name" type="TEXT" null="true"/>
<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"/>
+ <column name="version_canonical_release" type="TEXT" null="true" options="COLLATE BINARY"/>
<column name="version_revision" type="INTEGER" null="true"/>
<column name="index" type="INTEGER" null="true"/>
<column name="conditional" type="INTEGER" null="true"/>
@@ -135,18 +135,25 @@
<column name="name" type="TEXT" null="true"/>
<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"/>
+ <column name="version_canonical_release" type="TEXT" null="true" options="COLLATE BINARY"/>
<column name="version_revision" type="INTEGER" null="true"/>
<column name="dependency_index" type="INTEGER" null="true"/>
<column name="index" type="INTEGER" null="true"/>
<column name="dep_name" type="TEXT" null="true"/>
- <column name="dep_operation" type="TEXT" null="true"/>
- <column name="dep_version_epoch" type="INTEGER" null="true"/>
- <column name="dep_version_canonical_upstream" type="TEXT" null="true"/>
- <column name="dep_version_canonical_release" type="TEXT" null="true"/>
- <column name="dep_version_revision" type="INTEGER" null="true"/>
- <column name="dep_version_upstream" type="TEXT" null="true"/>
- <column name="dep_version_release" type="TEXT" null="true"/>
+ <column name="dep_min_version_epoch" type="INTEGER" null="true"/>
+ <column name="dep_min_version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="dep_min_version_canonical_release" type="TEXT" null="true"/>
+ <column name="dep_min_version_revision" type="INTEGER" null="true"/>
+ <column name="dep_min_version_upstream" type="TEXT" null="true"/>
+ <column name="dep_min_version_release" type="TEXT" null="true"/>
+ <column name="dep_max_version_epoch" type="INTEGER" null="true"/>
+ <column name="dep_max_version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="dep_max_version_canonical_release" type="TEXT" null="true"/>
+ <column name="dep_max_version_revision" type="INTEGER" null="true"/>
+ <column name="dep_max_version_upstream" type="TEXT" null="true"/>
+ <column name="dep_max_version_release" type="TEXT" null="true"/>
+ <column name="dep_min_open" type="INTEGER" null="true"/>
+ <column name="dep_max_open" type="INTEGER" null="true"/>
<foreign-key name="object_id_fk" on-delete="CASCADE">
<column name="name"/>
<column name="version_epoch"/>
@@ -193,13 +200,20 @@
<table name="selected_package_prerequisites" kind="container">
<column name="package" type="TEXT" null="true"/>
<column name="prerequisite" type="TEXT" null="true"/>
- <column name="operation" type="TEXT" null="true"/>
- <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"/>
- <column name="version_revision" type="INTEGER" null="true"/>
- <column name="version_upstream" type="TEXT" null="true"/>
- <column name="version_release" type="TEXT" null="true"/>
+ <column name="min_version_epoch" type="INTEGER" null="true"/>
+ <column name="min_version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="min_version_canonical_release" type="TEXT" null="true"/>
+ <column name="min_version_revision" type="INTEGER" null="true"/>
+ <column name="min_version_upstream" type="TEXT" null="true"/>
+ <column name="min_version_release" type="TEXT" null="true"/>
+ <column name="max_version_epoch" type="INTEGER" null="true"/>
+ <column name="max_version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="max_version_canonical_release" type="TEXT" null="true"/>
+ <column name="max_version_revision" type="INTEGER" null="true"/>
+ <column name="max_version_upstream" type="TEXT" null="true"/>
+ <column name="max_version_release" type="TEXT" null="true"/>
+ <column name="min_open" type="INTEGER" null="true"/>
+ <column name="max_open" type="INTEGER" null="true"/>
<foreign-key name="package_fk" on-delete="CASCADE">
<column name="package"/>
<references table="selected_package">
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index d896b40..40f67b5 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -50,7 +50,7 @@ namespace bpkg
// Return the package and the repository in which it was found or
// NULL for both if not found.
//
- std::pair<shared_ptr<available_package>, shared_ptr<repository>>
+ pair<shared_ptr<available_package>, shared_ptr<repository>>
find_available (database& db,
const string& name,
const shared_ptr<repository>& r,
@@ -64,25 +64,26 @@ namespace bpkg
// If there is a constraint, then translate it to the query. Otherwise,
// get the latest version.
//
- bool order (true);
if (c)
{
- const version& v (c->version);
+ if (c->min_version)
+ {
+ if (c->min_open)
+ q = q && vm > *c->min_version;
+ else
+ q = q && vm >= *c->min_version;
+ }
- // Note that the constraint's version is always rhs (libfoo >= 1.2.3).
- //
- switch (c->operation)
+ if (c->max_version)
{
- case comparison::eq: q = q && vm == v; order = false; break;
- case comparison::lt: q = q && vm < v; break;
- case comparison::gt: q = q && vm > v; break;
- case comparison::le: q = q && vm <= v; break;
- case comparison::ge: q = q && vm >= v; break;
+ if (c->max_open)
+ q = q && vm < *c->max_version;
+ else
+ q = q && vm <= *c->max_version;
}
}
- if (order)
- q += order_by_version_desc (vm);
+ q += order_by_version_desc (vm);
// Filter the result based on the repository to which each version
// belongs.
@@ -95,7 +96,7 @@ namespace bpkg
// that the package locations list is left empty and that the
// returned repository could be NULL if the package is an orphan.
//
- std::pair<shared_ptr<available_package>, shared_ptr<repository>>
+ pair<shared_ptr<available_package>, shared_ptr<repository>>
make_available (const common_options& options,
const dir_path& cd,
database& db,
@@ -844,8 +845,7 @@ namespace bpkg
auto rp (
v.empty ()
? find_available (db, n, root, nullopt)
- : find_available (db, n, root,
- dependency_constraint {comparison::eq, v}));
+ : find_available (db, n, root, dependency_constraint (v)));
ap = rp.first;
ar = rp.second;
@@ -960,7 +960,7 @@ namespace bpkg
if (!v.empty ())
p.constraints.emplace_back (
"command line",
- dependency_constraint {comparison::eq, v});
+ dependency_constraint (v));
pkgs.collect (o, c, db, move (p));
names.push_back (n);
diff --git a/bpkg/satisfaction.cxx b/bpkg/satisfaction.cxx
index af531f4..8198283 100644
--- a/bpkg/satisfaction.cxx
+++ b/bpkg/satisfaction.cxx
@@ -15,94 +15,68 @@ namespace bpkg
bool
satisfies (const version& v, const dependency_constraint& c)
{
- using op = comparison;
+ assert (!c.empty ());
- // Note that the constraint's version is always rhs (libfoo >= 1.2.3).
- //
- switch (c.operation)
- {
- case op::eq: return v == c.version;
- case op::lt: return v < c.version;
- case op::gt: return v > c.version;
- case op::le: return v <= c.version;
- case op::ge: return v >= c.version;
- }
+ bool s (true);
+
+ if (c.min_version)
+ s = c.min_open ? v > *c.min_version : v >= *c.min_version;
- assert (false);
- return false;
+ if (s && c.max_version)
+ s = c.max_open ? v < *c.max_version : v <= *c.max_version;
+
+ return s;
}
bool
satisfies (const dependency_constraint& l, const dependency_constraint& r)
{
- using op = comparison;
-
- op lo (l.operation);
- op ro (r.operation);
+ assert (!l.empty () && !r.empty ());
- const version& lv (l.version);
- const version& rv (r.version);
+ bool s (false);
- switch (lo)
+ if (l.min_version)
{
- case op::eq: // ==
- {
- switch (ro)
- {
- case op::eq: return lv == rv;
- case op::lt: return lv < rv;
- case op::le: return lv <= rv;
- case op::gt: return lv > rv;
- case op::ge: return lv >= rv;
- }
- }
- case op::lt: // <
- {
- switch (ro)
- {
- case op::lt: return lv <= rv;
- case op::le: return lv < rv;
- case op::eq:
- case op::gt:
- case op::ge: return false;
- }
- }
- case op::le: // <=
+ if (r.min_version)
{
- switch (ro)
- {
- case op::lt: return lv < rv;
- case op::le: return lv <= rv;
- case op::eq:
- case op::gt:
- case op::ge: return false;
- }
+ if (l.min_open)
+ // Doesn't matter if r is min_open or not.
+ //
+ s = *l.min_version >= *r.min_version;
+ else
+ s = r.min_open
+ ? *l.min_version > *r.min_version
+ : *l.min_version >= *r.min_version;
}
- case op::gt: // >
- {
- switch (ro)
- {
- case op::gt: return lv >= rv;
- case op::ge: return lv > rv;
- case op::eq:
- case op::lt:
- case op::le: return false;
- }
- }
- case op::ge: // >=
+ else
+ s = true; // Doesn't matter what l.min_version is.
+ }
+ else
+ s = !r.min_version;
+
+ if (s)
+ {
+ if (l.max_version)
{
- switch (ro)
+ if (r.max_version)
{
- case op::gt: return lv > rv;
- case op::ge: return lv >= rv;
- case op::eq:
- case op::lt:
- case op::le: return false;
+ if (l.max_open)
+ // Doesn't matter if r is max_open or not.
+ //
+ s = *l.max_version <= *r.max_version;
+ else
+ s = r.max_open
+ ? *l.max_version < *r.max_version
+ : *l.max_version <= *r.max_version;
}
+ else
+ // Doesn't matter what l.max_version is, so leave s to be true.
+ ;
}
+ else
+ s = !r.max_version;
}
- assert (false);
- return false;
+ return s;
}
}