From 1ad6dad8da0d51e9522f9d27cf48531fa23b24ba Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 30 Aug 2019 20:56:26 +0300 Subject: Adapt to optional package revision --- bpkg/database.cxx | 28 ++++++++- bpkg/manifest-utility.cxx | 6 +- bpkg/manifest-utility.hxx | 12 +++- bpkg/package.cxx | 12 +++- bpkg/package.hxx | 83 ++++++++++++++++--------- bpkg/package.ixx | 6 +- bpkg/package.xml | 2 + bpkg/pkg-build.cxx | 72 ++++++++++++++------- bpkg/pkg-status.cxx | 18 +++--- bpkg/rep-fetch.cxx | 5 +- bpkg/satisfaction.cxx | 43 ++++++++++--- bpkg/satisfaction.test.cxx | 58 +++++++++++++++++ tests/common/satisfy/libbar-1.1.1.tar.gz | Bin 0 -> 367 bytes tests/common/satisfy/libfoo-1.1.0+1.tar.gz | Bin 0 -> 353 bytes tests/common/satisfy/t4e/libbar-1.1.0.tar.gz | 1 + tests/common/satisfy/t4e/libbar-1.1.1.tar.gz | 1 + tests/common/satisfy/t4e/libfoo-1.1.0+1.tar.gz | 1 + tests/common/satisfy/t4e/repositories.manifest | 4 ++ tests/pkg-build.testscript | 64 ++++++++++++++++++- tests/pkg-build/t4e | 1 + tests/pkg-status.testscript | 30 ++++++++- 21 files changed, 360 insertions(+), 87 deletions(-) create mode 100644 bpkg/satisfaction.test.cxx create mode 100644 tests/common/satisfy/libbar-1.1.1.tar.gz create mode 100644 tests/common/satisfy/libfoo-1.1.0+1.tar.gz create mode 120000 tests/common/satisfy/t4e/libbar-1.1.0.tar.gz create mode 120000 tests/common/satisfy/t4e/libbar-1.1.1.tar.gz create mode 120000 tests/common/satisfy/t4e/libfoo-1.1.0+1.tar.gz create mode 100644 tests/common/satisfy/t4e/repositories.manifest create mode 120000 tests/pkg-build/t4e diff --git a/bpkg/database.cxx b/bpkg/database.cxx index a66b3a3..68a2a34 100644 --- a/bpkg/database.cxx +++ b/bpkg/database.cxx @@ -42,15 +42,39 @@ namespace bpkg // Register the data migration functions. // -#if 0 template using migration_entry = odb::data_migration_entry; static const migration_entry<6> migrate_v6 ([] (odb::database& db) { + // Set the zero version revision to NULL. + // + auto migrate_rev = [&db] (const char* table, const char* column) + { + db.execute (string ("UPDATE ") + table + " SET " + column + " = NULL " + + "WHERE " + column + " = 0"); + }; + + // The version package manifest value. Note: is not part of a primary key. + // + migrate_rev ("selected_package", "version_revision"); + + // The depends package manifest value endpoint versions. + // + // Note that previously the zero and absent revisions had the same + // semantics. Now the semantics differs and the zero revision is preserved + // (see libbpkg/manifest.hxx for details). + // + migrate_rev ("selected_package_prerequisites", "min_version_revision"); + migrate_rev ("selected_package_prerequisites", "max_version_revision"); + + migrate_rev ("available_package_dependency_alternatives", + "dep_min_version_revision"); + + migrate_rev ("available_package_dependency_alternatives", + "dep_max_version_revision"); }); -#endif database open (const dir_path& d, tracer& tr, bool create) diff --git a/bpkg/manifest-utility.cxx b/bpkg/manifest-utility.cxx index 74daf6b..bf4956b 100644 --- a/bpkg/manifest-utility.cxx +++ b/bpkg/manifest-utility.cxx @@ -68,7 +68,9 @@ namespace bpkg } version - parse_package_version (const char* s, bool allow_wildcard) + parse_package_version (const char* s, + bool allow_wildcard, + bool fold_zero_revision) { using traits = string::traits_type; @@ -82,7 +84,7 @@ namespace bpkg try { - version r (p); + version r (p, fold_zero_revision); if (r.release && r.release->empty ()) throw invalid_argument ("earliest version"); diff --git a/bpkg/manifest-utility.hxx b/bpkg/manifest-utility.hxx index 6c88f1f..9f690b4 100644 --- a/bpkg/manifest-utility.hxx +++ b/bpkg/manifest-utility.hxx @@ -47,12 +47,18 @@ namespace bpkg // Return empty version if none is specified. // version - parse_package_version (const char*, bool allow_wildcard = false); + parse_package_version (const char*, + bool allow_wildcard = false, + bool fold_zero_revision = true); inline version - parse_package_version (const string& s, bool allow_wildcard = false) + parse_package_version (const string& s, + bool allow_wildcard = false, + bool fold_zero_revision = true) { - return parse_package_version (s.c_str (), allow_wildcard); + return parse_package_version (s.c_str (), + allow_wildcard, + fold_zero_revision); } // If the passed location is a relative local path, then assume this is a diff --git a/bpkg/package.cxx b/bpkg/package.cxx index 0ac2577..563fc93 100644 --- a/bpkg/package.cxx +++ b/bpkg/package.cxx @@ -16,7 +16,7 @@ using namespace std; namespace bpkg { - const version wildcard_version (0, "0", nullopt, 0, 0); + const version wildcard_version (0, "0", nullopt, nullopt, 0); // available_package_id // @@ -290,7 +290,10 @@ namespace bpkg query q ( query::package::id.name == n && - compare_version_eq (query::package::id.version, v, true, false)); + compare_version_eq (query::package::id.version, + canonical_version (v), + true /* revision */, + false /* iteration */)); for (const auto& prf: db.query (q)) { @@ -306,7 +309,10 @@ namespace bpkg shared_ptr p (db.find (n)); if (p == nullptr || !p->src_root || - compare_version_ne (v, p->version, true, false)) + compare_version_ne (v, + p->version, + true /* revision */, + false /* iteration */)) return nullopt; string mc (sha256 (o, d / manifest_file)); diff --git a/bpkg/package.hxx b/bpkg/package.hxx index 74021c7..4f40939 100644 --- a/bpkg/package.hxx +++ b/bpkg/package.hxx @@ -28,7 +28,7 @@ // #define DB_SCHEMA_VERSION_BASE 5 -#pragma db model version(DB_SCHEMA_VERSION_BASE, 5, closed) +#pragma db model version(DB_SCHEMA_VERSION_BASE, 6, closed) namespace bpkg { @@ -102,7 +102,7 @@ namespace bpkg uint16_t epoch; string canonical_upstream; string canonical_release; - uint16_t revision; + optional revision; uint32_t iteration; string upstream; optional release; @@ -112,10 +112,12 @@ namespace bpkg _version () = default; _version (uint16_t e, string cu, string cr, - uint16_t rv, uint32_t i, string u, optional rl) + optional rv, uint32_t i, + string u, optional rl) : epoch (e), - canonical_upstream (cu), canonical_release (cr), - revision (rv), iteration (i), upstream (u), release (rl) {} + canonical_upstream (move (cu)), canonical_release (move (cr)), + revision (rv), iteration (i), + upstream (move (u)), release (move (rl)) {} }; } @@ -147,6 +149,11 @@ namespace bpkg // strange contraption is for. See available_package for an example // on how everything fits together. // + // Note that the object id cannot contain an optional member which is why we + // make the revision type uint16_t and represent nullopt as zero. This + // should be ok for package object ids referencing the package manifest + // version values because an absent revision and zero revision mean the + // same thing. // #pragma db value struct canonical_version @@ -157,6 +164,16 @@ namespace bpkg uint16_t revision; uint32_t iteration; + canonical_version () = default; + + explicit + canonical_version (const version& v) + : epoch (v.epoch), + canonical_upstream (v.canonical_upstream), + canonical_release (v.canonical_release), + revision (v.effective_revision ()), + iteration (v.iteration) {} + // 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 @@ -169,14 +186,15 @@ namespace bpkg #pragma db value transient struct upstream_version: version { - #pragma db member(upstream_) virtual(string) \ - get(this.upstream) \ - set(this = bpkg::version (0, std::move (?), std::string (), 0, 0)) + #pragma db member(upstream_) virtual(string) \ + get(this.upstream) \ + set(this = bpkg::version ( \ + 0, std::move (?), std::string (), bpkg::nullopt, 0)) - #pragma db member(release_) virtual(optional_string) \ - get(this.release) \ - set(this = bpkg::version ( \ - 0, std::move (this.upstream), std::move (?), 0, 0)) + #pragma db member(release_) virtual(optional_string) \ + get(this.release) \ + set(this = bpkg::version ( \ + 0, std::move (this.upstream), std::move (?), bpkg::nullopt, 0)) upstream_version () = default; upstream_version (version v): version (move (v)) {} @@ -186,10 +204,14 @@ namespace bpkg void init (const canonical_version& cv, const upstream_version& uv) { + // Note: revert the zero revision mapping (see above). + // *this = version (cv.epoch, uv.upstream, uv.release, - cv.revision, + (cv.revision != 0 + ? optional (cv.revision) + : nullopt), cv.iteration); assert (cv.canonical_upstream == canonical_upstream && @@ -1147,17 +1169,20 @@ namespace bpkg // // They allow comparing objects that have epoch, canonical_upstream, // canonical_release, revision, and iteration data members. The idea is that - // this works for both query members of types version and canonical_version - // as well as for comparing canonical_version to version. + // this works for both query members of types version and canonical_version. + // Note, though, that the object revisions should be comparable (both + // optional, numeric, etc), so to compare version to query member or + // canonical_version you may need to explicitly convert the version object + // to canonical_version. // - // Note that if the comparison operation ignores the revision, then it also - // unconditionally ignores the iteration (that semantically extends the + // Also note that if the comparison operation ignores the revision, then it + // also unconditionally ignores the iteration (that semantically extends the // revision). // template inline auto compare_version_eq (const T1& x, const T2& y, bool revision, bool iteration) - -> decltype (x.epoch == y.epoch) + -> decltype (x.revision == y.revision) { assert (revision || !iteration); // !revision && iteration is meaningless. @@ -1181,7 +1206,7 @@ namespace bpkg template inline auto - operator== (const T1& x, const T2& y) -> decltype (x.epoch == y.epoch) + operator== (const T1& x, const T2& y) -> decltype (x.revision == y.revision) { return compare_version_eq (x, y, true); } @@ -1190,7 +1215,7 @@ namespace bpkg template inline auto compare_version_ne (const T1& x, const T2& y, bool revision, bool iteration) - -> decltype (x.epoch == y.epoch) + -> decltype (x.revision == y.revision) { assert (revision || !iteration); // !revision && iteration is meaningless. @@ -1207,7 +1232,7 @@ namespace bpkg template inline auto - operator!= (const T1& x, const T2& y) -> decltype (x.epoch != y.epoch) + operator!= (const T1& x, const T2& y) -> decltype (x.revision != y.revision) { return compare_version_ne (x, y, true, true); } @@ -1215,7 +1240,7 @@ namespace bpkg template inline auto compare_version_lt (const T1& x, const T2& y, bool revision, bool iteration) - -> decltype (x.epoch == y.epoch) + -> decltype (x.revision == y.revision) { assert (revision || !iteration); // !revision && iteration is meaningless. @@ -1245,7 +1270,7 @@ namespace bpkg template inline auto - operator< (const T1& x, const T2& y) -> decltype (x.epoch < y.epoch) + operator< (const T1& x, const T2& y) -> decltype (x.revision < y.revision) { return compare_version_lt (x, y, true, true); } @@ -1253,7 +1278,7 @@ namespace bpkg template inline auto compare_version_le (const T1& x, const T2& y, bool revision, bool iteration) - -> decltype (x.epoch == y.epoch) + -> decltype (x.revision == y.revision) { assert (revision || !iteration); // !revision && iteration is meaningless. @@ -1301,7 +1326,7 @@ namespace bpkg template inline auto - operator<= (const T1& x, const T2& y) -> decltype (x.epoch <= y.epoch) + operator<= (const T1& x, const T2& y) -> decltype (x.revision <= y.revision) { return compare_version_le (x, y, true); } @@ -1310,7 +1335,7 @@ namespace bpkg template inline auto compare_version_gt (const T1& x, const T2& y, bool revision, bool iteration) - -> decltype (x.epoch == y.epoch) + -> decltype (x.revision == y.revision) { assert (revision || !iteration); // !revision && iteration is meaningless. @@ -1340,7 +1365,7 @@ namespace bpkg template inline auto - operator> (const T1& x, const T2& y) -> decltype (x.epoch > y.epoch) + operator> (const T1& x, const T2& y) -> decltype (x.revision > y.revision) { return compare_version_gt (x, y, true, true); } @@ -1348,7 +1373,7 @@ namespace bpkg template inline auto compare_version_ge (const T1& x, const T2& y, bool revision, bool iteration) - -> decltype (x.epoch == y.epoch) + -> decltype (x.revision == y.revision) { assert (revision || !iteration); // !revision && iteration is meaningless. @@ -1393,7 +1418,7 @@ namespace bpkg template inline auto - operator>= (const T1& x, const T2& y) -> decltype (x.epoch >= y.epoch) + operator>= (const T1& x, const T2& y) -> decltype (x.revision >= y.revision) { return compare_version_ge (x, y, true, true); } diff --git a/bpkg/package.ixx b/bpkg/package.ixx index 9359294..f6aa6c4 100644 --- a/bpkg/package.ixx +++ b/bpkg/package.ixx @@ -9,11 +9,7 @@ namespace bpkg inline available_package_id:: available_package_id (package_name n, const bpkg::version& v) : name (move (n)), - version {v.epoch, - v.canonical_upstream, - v.canonical_release, - v.revision, - v.iteration} + version (v) { } } diff --git a/bpkg/package.xml b/bpkg/package.xml index 6c17f11..2856be1 100644 --- a/bpkg/package.xml +++ b/bpkg/package.xml @@ -1,4 +1,6 @@ + + diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index 0844ae9..5a5eaa1 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -75,18 +75,14 @@ namespace bpkg // satisfy this constraint. The same for libfoo <= 1 -- 1+1 should // satisfy. // - // Note that strictly speaking 0 doesn't mean unspecified. Which means - // with this implementation there is no way to say "I really mean - // revision 0" since 1 == 1+0. One can, in the current model, say libfoo - // == 1+1, though. This is probably ok since one would assume any - // subsequent revision of a package version are just as (un)satisfactory - // as the first one. + // 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. // - // Also 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, wildcard_version, false, false)); + query qs (compare_version_eq (vm, + canonical_version (wildcard_version), + false /* revision */, + false /* iteration */)); if (c->min_version && c->max_version && @@ -94,7 +90,12 @@ namespace bpkg { const version& v (*c->min_version); - q = q && (compare_version_eq (vm, v, v.revision != 0, false) || qs); + q = q && + (compare_version_eq (vm, + canonical_version (v), + v.revision.has_value (), + false /* iteration */) || + qs); } else { @@ -103,21 +104,25 @@ namespace bpkg 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, v, v.revision != 0, false); + qr = compare_version_gt (vm, cv, rv, false /* iteration */); else - qr = compare_version_ge (vm, v, v.revision != 0, false); + 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, v, v.revision != 0, false); + qr = qr && compare_version_lt (vm, cv, rv, false /* iteration */); else - qr = qr && compare_version_le (vm, v, v.revision != 0, false); + qr = qr && compare_version_le (vm, cv, rv, false /* iteration */); } q = q && (qr || qs); @@ -2818,6 +2823,20 @@ namespace bpkg transaction t (db); + // Don't fold the zero revision if building the package from source so + // that we build the exact X+0 package revision if it is specified. + // + auto fold_zero_rev = [] (package_scheme sc) + { + bool r (false); + switch (sc) + { + case package_scheme::none: r = false; break; + case package_scheme::sys: r = true; break; + } + return r; + }; + for (pkg_spec& ps: specs) { if (ps.location.empty ()) @@ -2826,14 +2845,14 @@ namespace bpkg // otherwise add unparsed. // const char* s (ps.packages.c_str ()); - package_scheme h (parse_package_scheme (s)); + package_scheme sc (parse_package_scheme (s)); - if (h != package_scheme::none) // Add parsed. + if (sc != package_scheme::none) // Add parsed. { - bool sys (h == package_scheme::sys); + bool sys (sc == package_scheme::sys); package_name n (parse_package_name (s)); - version v (parse_package_version (s, sys)); + version v (parse_package_version (s, sys, fold_zero_rev (sc))); // For system packages not associated with a specific repository // location add the stub package to the imaginary system @@ -2842,7 +2861,7 @@ namespace bpkg if (sys && !v.empty ()) stubs.push_back (make_shared (n)); - pkg_args.push_back (arg_package (h, + pkg_args.push_back (arg_package (sc, move (n), move (v), move (ps.options), @@ -2974,7 +2993,7 @@ namespace bpkg bool sys (sc == package_scheme::sys); package_name n (parse_package_name (s)); - version v (parse_package_version (s, sys)); + version v (parse_package_version (s, sys, fold_zero_rev (sc))); // Check if the package is present in the repository and its // complements, recursively. If the version is not specified then @@ -3311,7 +3330,14 @@ namespace bpkg // prior to saving them into the package arg. // package_name n (parse_package_name (package)); - version v (parse_package_version (package)); + + // Don't fold the zero revision so that we build the exact X+0 + // package revision, if it is specified. + // + version v ( + parse_package_version (package, + false /* allow_wildcard */, + false /* fold_zero_revision */)); pa = arg_package (package_scheme::none, move (n), diff --git a/bpkg/pkg-status.cxx b/bpkg/pkg-status.cxx index aaaedaf..bfba21f 100644 --- a/bpkg/pkg-status.cxx +++ b/bpkg/pkg-status.cxx @@ -86,9 +86,9 @@ namespace bpkg // if (!p.version.empty ()) q = q && compare_version_eq (query::id.version, - p.version, - p.version.revision != 0, - false); + canonical_version (p.version), + p.version.revision.has_value (), + false /* iteration */); // And if we found an existing package, then only look for versions // greater than to what already exists unless we were asked to show @@ -98,7 +98,7 @@ namespace bpkg // available versions (since it is 0). // if (s != nullptr && !o.old_available ()) - q = q && query::id.version > s->version; + q = q && query::id.version > canonical_version (s->version); q += order_by_version_desc (query::id.version); @@ -281,7 +281,9 @@ namespace bpkg { const char* arg (args.next ()); package p {parse_package_name (arg), - parse_package_version (arg), + parse_package_version (arg, + false /* allow_wildcard */, + false /* fold_zero_revision */), nullptr /* selected */, nullopt /* constraint */}; @@ -292,9 +294,9 @@ namespace bpkg if (!p.version.empty ()) q = q && compare_version_eq (query::version, - p.version, - p.version.revision != 0, - false); + canonical_version (p.version), + p.version.revision.has_value (), + false /* iteration */); p.selected = db.query_one (q); } diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx index 413358a..cafa0c1 100644 --- a/bpkg/rep-fetch.cxx +++ b/bpkg/rep-fetch.cxx @@ -1307,7 +1307,10 @@ namespace bpkg const available_package_id& id (prf.package_id); if (id.name == ap.name && - compare_version_eq (id.version, ap.version, true, false)) + compare_version_eq (id.version, + ap.version, + true /* revision */, + false /* iteration */)) { shared_ptr p (db.load (id)); const version& v (p->version); diff --git a/bpkg/satisfaction.cxx b/bpkg/satisfaction.cxx index faebce0..53fd3b8 100644 --- a/bpkg/satisfaction.cxx +++ b/bpkg/satisfaction.cxx @@ -24,18 +24,27 @@ namespace bpkg bool s (true); - // See notes in pkg-build:find_available() on ignoring revision in + // Here an absent revision means zero revision and version X must satisfy + // the [X+0 ...) dependency constraint. Note that technically X < X+0. + // + version ev (v.epoch, + v.upstream, + v.release, + v.effective_revision (), + v.iteration); + + // See notes in pkg-build:query_available() on ignoring revision in // comparison. // if (c.min_version) { - int i (v.compare (*c.min_version, c.min_version->revision == 0)); + int i (ev.compare (*c.min_version, !c.min_version->revision)); s = c.min_open ? i > 0 : i >= 0; } if (s && c.max_version) { - int i (v.compare (*c.max_version, c.max_version->revision == 0)); + int i (ev.compare (*c.max_version, !c.max_version->revision)); s = c.max_open ? i < 0 : i <= 0; } @@ -47,16 +56,33 @@ namespace bpkg { assert (!l.empty () && l.complete () && !r.empty () && r.complete ()); - // Note: the revision ignoring logic is still unclear/unimplemented. It - // seems it will be specific to each case below. + // Note that a revision should not be ignored if we compare the endpoint + // versions. However, an absent revision translates into the effective + // revision differently, depending on the range endpoint side and openness + // (see libbpkg/manifest.hxx for details). That's why we normalize + // endpoint versions prior to comparison. // + auto norm = [] (const version& v, bool min, bool open) -> version + { + return version (v.epoch, + v.upstream, + v.release, + v.revision ? v.revision : + (min && !open) || (!min && open) ? 0 : + uint16_t (~0), + v.iteration); + }; + bool s (false); if (l.min_version) { if (r.min_version) { - int i (l.min_version->compare (*r.min_version, false)); + version lv (norm (*l.min_version, true /* min */, l.min_open)); + version rv (norm (*r.min_version, true /* min */, r.min_open)); + + int i (lv.compare (rv, false /* ignore_revision */)); if (l.min_open) // Doesn't matter if r is min_open or not. // @@ -76,7 +102,10 @@ namespace bpkg { if (r.max_version) { - int i (l.max_version->compare (*r.max_version, false)); + version lv (norm (*l.max_version, false /* min */, l.max_open)); + version rv (norm (*r.max_version, false /* min */, r.max_open)); + + int i (lv.compare (rv, false /* ignore_revision */)); if (l.max_open) // Doesn't matter if r is max_open or not. // diff --git a/bpkg/satisfaction.test.cxx b/bpkg/satisfaction.test.cxx new file mode 100644 index 0000000..fef30e1 --- /dev/null +++ b/bpkg/satisfaction.test.cxx @@ -0,0 +1,58 @@ +// file : bpkg/satisfaction.test.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +namespace bpkg +{ + static int + main (int, char*[]) + { + using dc = dependency_constraint; + + assert ( satisfies (dc ("[1.0 2.0]"), dc ("[1.0+0 2.0]"))); + assert (!satisfies (dc ("[1.0 2.0]"), dc ("[1.0+1 2.0]"))); + assert ( satisfies (dc ("[1.0+0 2.0]"), dc ("[1.0 2.0]"))); + assert ( satisfies (dc ("[1.0+1 2.0]"), dc ("[1.0 2.0]"))); + + assert (!satisfies (dc ("[1.0+0 2.0]"), dc ("(1.0 2.0]"))); + assert (!satisfies (dc ("[1.0+1 2.0]"), dc ("(1.0 2.0]"))); + assert (!satisfies (dc ("(1.0+0 2.0]"), dc ("(1.0 2.0]"))); + assert (!satisfies (dc ("(1.0+1 2.0]"), dc ("(1.0 2.0]"))); + assert ( satisfies (dc ("(1.0+0 2.0]"), dc ("[1.0 2.0]"))); + assert ( satisfies (dc ("(1.0+1 2.0]"), dc ("[1.0 2.0]"))); + + assert (!satisfies (dc ("[1.0 2.0+0]"), dc ("[1.0 2.0)"))); + assert (!satisfies (dc ("[1.0 2.0+1]"), dc ("[1.0 2.0)"))); + assert ( satisfies (dc ("[1.0 2.0+0)"), dc ("[1.0 2.0)"))); + assert (!satisfies (dc ("[1.0 2.0+1)"), dc ("[1.0 2.0)"))); + + // Swap the above constraints. + // + assert (!satisfies (dc ("[1.0 2.0]"), dc ("[1.0 2.0+0]"))); + assert (!satisfies (dc ("[1.0 2.0]"), dc ("[1.0 2.0+1]"))); + assert ( satisfies (dc ("[1.0 2.0+0]"), dc ("[1.0 2.0]"))); + assert ( satisfies (dc ("[1.0 2.0+1]"), dc ("[1.0 2.0]"))); + + assert ( satisfies (dc ("(1.0 2.0]"), dc ("[1.0+0 2.0]"))); + assert ( satisfies (dc ("(1.0 2.0]"), dc ("[1.0+1 2.0]"))); + assert ( satisfies (dc ("(1.0 2.0]"), dc ("(1.0+0 2.0]"))); + assert ( satisfies (dc ("(1.0 2.0]"), dc ("(1.0+1 2.0]"))); + assert (!satisfies (dc ("[1.0 2.0]"), dc ("(1.0+0 2.0]"))); + assert (!satisfies (dc ("[1.0 2.0]"), dc ("(1.0+1 2.0]"))); + + assert ( satisfies (dc ("[1.0 2.0)"), dc ("[1.0 2.0+0)"))); + assert ( satisfies (dc ("[1.0 2.0)"), dc ("[1.0 2.0+1)"))); + assert (!satisfies (dc ("[1.0 2.0]"), dc ("[1.0 2.0+0)"))); + assert (!satisfies (dc ("[1.0 2.0]"), dc ("[1.0 2.0+1)"))); + + return 0; + } +} + +int +main (int argc, char* argv[]) +{ + return bpkg::main (argc, argv); +} diff --git a/tests/common/satisfy/libbar-1.1.1.tar.gz b/tests/common/satisfy/libbar-1.1.1.tar.gz new file mode 100644 index 0000000..b4b0bb7 Binary files /dev/null and b/tests/common/satisfy/libbar-1.1.1.tar.gz differ diff --git a/tests/common/satisfy/libfoo-1.1.0+1.tar.gz b/tests/common/satisfy/libfoo-1.1.0+1.tar.gz new file mode 100644 index 0000000..8cc49aa Binary files /dev/null and b/tests/common/satisfy/libfoo-1.1.0+1.tar.gz differ diff --git a/tests/common/satisfy/t4e/libbar-1.1.0.tar.gz b/tests/common/satisfy/t4e/libbar-1.1.0.tar.gz new file mode 120000 index 0000000..b9a2de5 --- /dev/null +++ b/tests/common/satisfy/t4e/libbar-1.1.0.tar.gz @@ -0,0 +1 @@ +../libbar-1.1.0.tar.gz \ No newline at end of file diff --git a/tests/common/satisfy/t4e/libbar-1.1.1.tar.gz b/tests/common/satisfy/t4e/libbar-1.1.1.tar.gz new file mode 120000 index 0000000..0784aba --- /dev/null +++ b/tests/common/satisfy/t4e/libbar-1.1.1.tar.gz @@ -0,0 +1 @@ +../libbar-1.1.1.tar.gz \ No newline at end of file diff --git a/tests/common/satisfy/t4e/libfoo-1.1.0+1.tar.gz b/tests/common/satisfy/t4e/libfoo-1.1.0+1.tar.gz new file mode 120000 index 0000000..ca9c01a --- /dev/null +++ b/tests/common/satisfy/t4e/libfoo-1.1.0+1.tar.gz @@ -0,0 +1 @@ +../libfoo-1.1.0+1.tar.gz \ No newline at end of file diff --git a/tests/common/satisfy/t4e/repositories.manifest b/tests/common/satisfy/t4e/repositories.manifest new file mode 100644 index 0000000..4cc7c0a --- /dev/null +++ b/tests/common/satisfy/t4e/repositories.manifest @@ -0,0 +1,4 @@ +: 1 +: +location: ../t4a +role: complement diff --git a/tests/pkg-build.testscript b/tests/pkg-build.testscript index 4465081..6ce1689 100644 --- a/tests/pkg-build.testscript +++ b/tests/pkg-build.testscript @@ -10,8 +10,8 @@ # Source repository: # # pkg-build -# |-- libbar-1.0.0.tar.gz -# |-- libbaz-1.1.0.tar.gz +# |-- libbar-1.0.0.tar.gz -> libfoo +# |-- libbaz-1.1.0.tar.gz -> libfoo, libbar # |-- libfix-0.0.1.tar.gz # |-- libfoo-0.0.1.tar.gz -> libfix # |-- libfoo-1.0.0.tar.gz @@ -95,6 +95,10 @@ # | |-- libfox-1.0.0.tar.gz # | `-- repositories.manifest # | +# |-- t4e +# | |-- libfoo-1.1.0+1.tar.gz +# | `-- repositories.manifest +# | # |-- t5 # | |-- libbar-1.2.0.tar.gz # | `-- repositories.manifest @@ -131,6 +135,7 @@ cp -r $src/t4b $out/t4b && $rep_create $out/t4b &$out/t4b/packages.manifest cp -r $src/t4c $out/t4c && $rep_create $out/t4c &$out/t4c/packages.manifest cp -r $src/t4d $out/t4d && $rep_create $out/t4d &$out/t4d/packages.manifest + cp -r $src/t4e $out/t4e && $rep_create $out/t4e &$out/t4e/packages.manifest cp -r $src/t5 $out/t5 && $rep_create $out/t5 &$out/t5/packages.manifest cp -r $src/t6 $out/t6 && $rep_create $out/t6 &$out/t6/packages.manifest @@ -315,6 +320,33 @@ test.options += --no-progress EOE } } + + : revision + : + { + +$clone_root_cfg + +$rep_add $rep/t4e && $rep_fetch + + : latest + : + { + $clone_cfg; + + $* libfoo/1.1.0 >>EOO + new libfoo/1.1.0+1 + EOO + } + + : zero + : + { + $clone_cfg; + + $* libfoo/1.1.0+0 >>EOO + new libfoo/1.1.0 + EOO + } + } } : libbar-libfoo @@ -420,6 +452,34 @@ test.options += --no-progress $pkg_purge libfoo 2>'purged libfoo/1.1.0' } } + + : dependency-revision + : + { + +$clone_root_cfg && $rep_add $rep/t4e && $rep_fetch + + : latest + : + { + $clone_cfg; + + $* libbar/1.1.0 >>EOO + new libfoo/1.1.0+1 (required by libbar) + new libbar/1.1.0 + EOO + } + + : zero + : + { + $clone_cfg; + + $* libbar/1.1.1 >>EOO + new libfoo/1.1.0 (required by libbar) + new libbar/1.1.1 + EOO + } + } } : libbaz-libbar diff --git a/tests/pkg-build/t4e b/tests/pkg-build/t4e new file mode 120000 index 0000000..9cd01c8 --- /dev/null +++ b/tests/pkg-build/t4e @@ -0,0 +1 @@ +../common/satisfy/t4e \ No newline at end of file diff --git a/tests/pkg-status.testscript b/tests/pkg-status.testscript index 39ea85a..1ac3a97 100644 --- a/tests/pkg-status.testscript +++ b/tests/pkg-status.testscript @@ -94,6 +94,11 @@ rep_fetch += -d cfg --auth all --trust-yes 2>! $clone_cfg; $* libfoo/1.0.0 >'libfoo available 1.0.0' + : libfoo-1.0.0+0 + : + $clone_cfg; + $* libfoo/1.0.0+0 >'libfoo available 1.0.0' + : libfoo : $clone_cfg; @@ -147,9 +152,30 @@ rep_fetch += -d cfg --auth all --trust-yes 2>! : testing : { - $clone_cfg ./ && $rep_add $rep/testing && $rep_fetch; + +$clone_cfg ./ && $rep_add $rep/testing && $rep_fetch + + clone_cfg = cp -r ../cfg ./ + + : no-version + : + { + $clone_cfg; + $* libbar >'libbar available [1.1.0+1] 1.1.0 1.0.0+1 1.0.0' + } - $* libbar >'libbar available [1.1.0+1] 1.1.0 1.0.0+1 1.0.0' + : no-revision + : + { + $clone_cfg; + $* libbar/1.0.0 >'libbar available 1.0.0+1 1.0.0' + } + + : zero-revision + : + { + $clone_cfg; + $* libbar/1.0.0+0 >'libbar available 1.0.0' + } } : unstable -- cgit v1.1