aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-09-29 11:29:50 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-09-29 11:29:50 +0200
commitf5adc6c0ee7965abcad4cc73d0f36d1ed3cba3cc (patch)
tree209d8b593efc5cf525ae96f6bf69b356cdba9766
parentbbc1acd6e9e086c5bcfccac971c8ca4edd192765 (diff)
Complete pkg-status, rework object model
-rw-r--r--bpkg/common-options.cli3
-rw-r--r--bpkg/database10
-rw-r--r--bpkg/diagnostics2
-rw-r--r--bpkg/package232
-rw-r--r--bpkg/package.cxx48
-rw-r--r--bpkg/package.ixx10
-rw-r--r--bpkg/package.xml18
-rw-r--r--bpkg/pkg-fetch.cxx4
-rw-r--r--bpkg/pkg-status.cxx124
-rw-r--r--bpkg/rep-fetch.cxx20
-rwxr-xr-xbpkg/test.sh61
-rw-r--r--bpkg/types5
-rw-r--r--tests/repository/1/status/extra/libbar-1.1.0-1.tar.gzbin0 -> 242 bytes
-rw-r--r--tests/repository/1/status/extra/repositories3
-rw-r--r--tests/repository/1/status/stable/libbar-1.0.0.tar.gzbin0 -> 241 bytes
-rw-r--r--tests/repository/1/status/stable/libfoo-1.0.0.tar.gzbin0 -> 240 bytes
-rw-r--r--tests/repository/1/status/stable/repositories1
-rw-r--r--tests/repository/1/status/testing/libbar-1.0.0-1.tar.gzbin0 -> 244 bytes
-rw-r--r--tests/repository/1/status/testing/libbar-1.1.0.tar.gzbin0 -> 242 bytes
-rw-r--r--tests/repository/1/status/testing/repositories6
-rw-r--r--tests/repository/1/status/unstable/libbar-2.0.0.tar.gzbin0 -> 245 bytes
-rw-r--r--tests/repository/1/status/unstable/repositories4
22 files changed, 366 insertions, 185 deletions
diff --git a/bpkg/common-options.cli b/bpkg/common-options.cli
index afeec77..d564a1c 100644
--- a/bpkg/common-options.cli
+++ b/bpkg/common-options.cli
@@ -3,7 +3,6 @@
// license : MIT; see accompanying LICENSE file
include <vector>;
-include <cstdint>;
include <bpkg/types>;
namespace bpkg
@@ -22,7 +21,7 @@ namespace bpkg
to \cb{--verbose 0}."
};
- std::uint16_t --verbose = 1
+ uint16_t --verbose = 1
{
"<level>",
"Set the diagnostics verbosity to <level> between 0 (disabled) and
diff --git a/bpkg/database b/bpkg/database
index f7de4d5..7ff3129 100644
--- a/bpkg/database
+++ b/bpkg/database
@@ -5,9 +5,13 @@
#ifndef BPKG_DATABASE
#define BPKG_DATABASE
-#include <utility> // forward()
+#include <utility> // forward()
+#include <type_traits> // remove_reference
+#include <odb/result.hxx>
#include <odb/session.hxx>
+
+#include <odb/sqlite/query.hxx>
#include <odb/sqlite/database.hxx>
#include <bpkg/types>
@@ -15,8 +19,10 @@
namespace bpkg
{
+ using odb::result;
using odb::session;
+ using odb::sqlite::query;
using odb::sqlite::database;
using odb::sqlite::transaction;
@@ -47,7 +53,7 @@ namespace bpkg
public:
pointer_result_range (R&& r): r_ (std::forward<R> (r)) {}
- using base_iterator = typename R::iterator;
+ using base_iterator = typename std::remove_reference<R>::type::iterator;
struct iterator: base_iterator
{
diff --git a/bpkg/diagnostics b/bpkg/diagnostics
index 565a9e5..68aac63 100644
--- a/bpkg/diagnostics
+++ b/bpkg/diagnostics
@@ -66,7 +66,7 @@ namespace bpkg
//
// While uint8 is more than enough, use uint16 for the ease of printing.
//
- extern std::uint16_t verb;
+ extern uint16_t verb;
template <typename F> inline void level1 (const F& f) {if (verb >= 1) f ();}
template <typename F> inline void level2 (const F& f) {if (verb >= 2) f ();}
diff --git a/bpkg/package b/bpkg/package
index 2601b7b..a75d18e 100644
--- a/bpkg/package
+++ b/bpkg/package
@@ -12,6 +12,8 @@
#include <odb/core.hxx>
+#include <bpkg/manifest>
+
#include <bpkg/types>
#include <bpkg/utility>
@@ -19,23 +21,6 @@
namespace bpkg
{
- // Use an image type to map version to the database since there
- // is no way to modify individual components directly.
- //
- #pragma db value
- struct _version
- {
- std::uint16_t epoch;
- string upstream;
- std::uint16_t revision;
- string canonical_upstream;
- };
-}
-
-#include <bpkg/manifest>
-
-namespace bpkg
-{
// compare_lazy_ptr
//
// Compare two lazy pointers via the pointed-to object ids.
@@ -50,6 +35,7 @@ namespace bpkg
}
};
+
// path
//
using optional_string = optional<string>;
@@ -70,15 +56,74 @@ namespace bpkg
to((?) ? (?)->string () : bpkg::optional_string ()) \
from((?) ? bpkg::dir_path (*(?)) : bpkg::optional_dir_path ())
+
// version
//
+ // Sometimes we need to split the version into two parts: the part
+ // that goes into the object id (epoch, canonical upstream, revision)
+ // and the original upstream. This is what the canonical_version and
+ // upstream_version value types are for. Note that upstream_version
+ // derives from version and uses it as storage. The idea here is this:
+ // when we split the version, we often still want to have the "whole"
+ // version object readily accessible and that's exactly what this
+ // strange contraption is for. See available_package for an example
+ // on how everything fits together.
+ //
+ //
+ #pragma db value
+ struct canonical_version
+ {
+ uint16_t epoch;
+ string canonical_upstream;
+ uint16_t revision;
+ };
+
+ #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))
+
+ upstream_version () = default;
+ upstream_version (version v): version (move (v)) {}
+ upstream_version&
+ operator= (version v) {version& b (*this); b = v; return *this;}
+
+ void
+ init (const canonical_version& cv, const upstream_version& uv)
+ {
+ *this = version (cv.epoch, uv.upstream (), cv.revision);
+ assert (cv.canonical_upstream == canonical_upstream ());
+ }
+ };
+
+ // Use an image type to map version to the database since there
+ // is no way to modify individual components directly.
+ //
+ #pragma db value
+ struct _version
+ {
+ uint16_t epoch;
+ string canonical_upstream;
+ uint16_t revision;
+ string upstream;
+ };
+
#pragma db map type(version) as(_version) \
to(bpkg::_version{(?).epoch (), \
- (?).upstream (), \
+ (?).canonical_upstream (), \
(?).revision (), \
- (?).canonical_upstream ()}) \
+ (?).upstream ()}) \
from(bpkg::version ((?).epoch, std::move ((?).upstream), (?).revision))
+
+ // repository_location
+ //
+ #pragma db map type(repository_location) as(string) \
+ to((?).string ()) from(bpkg::repository_location (?))
+
+
// repository
//
#pragma db object pointer(std::shared_ptr) session
@@ -86,20 +131,18 @@ namespace bpkg
{
public:
// We use a weak pointer for prerequisite repositories because we
- // might have cycles.
+ // could have cycles. No cycles in complements, thought.
//
using complements_type =
std::set<lazy_shared_ptr<repository>, compare_lazy_ptr>;
using prerequisites_type =
std::set<lazy_weak_ptr<repository>, compare_lazy_ptr>;
+ string name; // Object id (canonical name).
repository_location location;
complements_type complements;
prerequisites_type prerequisites;
- const string&
- name () const {return location.canonical_name ();}
-
// Used to detect recursive fecthing. Will probably be replaced
// by the 'repositories' file timestamp or hashsum later.
//
@@ -108,27 +151,18 @@ namespace bpkg
public:
explicit
- repository (repository_location l): location (move (l)) {}
+ repository (repository_location l): location (move (l))
+ {
+ name = location.canonical_name ();
+ }
// Database mapping.
//
- #pragma db value
- struct _id_type
- {
- string name; // Canonical name.
- string location;
- };
-
- _id_type
- _id () const;
-
- void
- _id (_id_type&&);
-
- #pragma db member(location) transient
+ #pragma db member(name) id
- #pragma db member(id) virtual(_id_type) before id(name) \
- get(_id) set(_id (std::move (?))) column("")
+ #pragma db member(location) \
+ set(this.location = std::move (?); \
+ assert (this.name == this.location.canonical_name ()))
#pragma db member(complements) id_column("repository") \
value_column("complement") value_not_null
@@ -141,35 +175,15 @@ namespace bpkg
repository () = default;
};
- #pragma db view object(repository) query(repository::id.name != "" && (?))
+ #pragma db view object(repository) query(repository::name != "" && (?))
struct repository_count
{
- #pragma db column("count(" + repository::id.name + ")")
+ #pragma db column("count(*)")
size_t result;
operator size_t () const {return result;}
};
- // package_version_id
- //
- #pragma db value
- struct package_version_id
- {
- string name;
- std::uint16_t epoch;
- string upstream; // Canonical upstream.
- std::uint16_t revision;
-
- package_version_id () = default;
- package_version_id (string, const version&);
-
- #pragma db member(epoch) column("version_epoch")
- #pragma db member(upstream) column("version_upstream")
- #pragma db member(revision) column("version_revision")
- };
-
- bool
- operator< (const package_version_id&, const package_version_id&);
// package_location
//
@@ -182,50 +196,44 @@ namespace bpkg
path location; // Relative to the repository.
};
+
// available_package
//
+ #pragma db value
+ struct available_package_id
+ {
+ string name;
+ canonical_version version;
+
+ available_package_id () = default;
+ available_package_id (string, const bpkg::version&);
+ };
+
+ bool
+ operator< (const available_package_id&, const available_package_id&);
+
#pragma db object pointer(shared_ptr) session
class available_package
{
public:
- using version_type = bpkg::version;
-
- string name;
- version_type version;
+ available_package_id id;
+ upstream_version version;
// List of repositories to which this package version belongs (yes,
// in our world, it can be in multiple, unrelated repositories).
//
std::vector<package_location> locations;
- // Database mapping.
- //
+ public:
+ available_package (string name, bpkg::version v)
+ : id (move (name), v), version (move (v)) {}
- // id
+ // Database mapping.
//
- #pragma db value
- struct _id_type
- {
- package_version_id data;
- string version_original_upstream;
-
- #pragma db member(data) column("")
- };
-
- _id_type
- _id () const;
-
- void
- _id (_id_type&&);
-
- #pragma db member(name) transient
- #pragma db member(version) transient
+ #pragma db member(id) id column("")
- #pragma db member(id) virtual(_id_type) before id(data) \
- get(_id) set(_id (std::move (?))) column("")
+ #pragma db member(version) set(this.version.init (this.id.version, (?)))
- // repositories
- //
#pragma db member(locations) id_column("") value_column("") \
unordered value_not_null
@@ -237,12 +245,13 @@ namespace bpkg
#pragma db view object(available_package)
struct available_package_count
{
- #pragma db column("count(" + available_package::id.data.name + ")")
+ #pragma db column("count(*)")
size_t result;
operator size_t () const {return result;}
};
+
// state
//
enum class state
@@ -266,6 +275,7 @@ namespace bpkg
to(to_string (?)) \
from(bpkg::from_string (?))
+
// package
//
#pragma db object pointer(shared_ptr) session
@@ -275,7 +285,7 @@ namespace bpkg
using version_type = bpkg::version;
using state_type = bpkg::state;
- string name;
+ string name; // Object id.
version_type version;
state_type state;
@@ -314,6 +324,44 @@ namespace bpkg
friend class odb::access;
package () = default;
};
+
+ // Version comparison operators.
+ //
+ // @@ Still not sure if this is conceptually the right way to do
+ // it (should we document it as an advanced technique?). Also
+ // the return type (query_base) ugliness.
+ //
+ template <typename T>
+ inline auto
+ operator== (const T& x, const version& y) -> decltype (x.epoch == 0)
+ {
+ return x.epoch == y.epoch () &&
+ x.canonical_upstream == y.canonical_upstream () &&
+ x.revision == y.revision ();
+ }
+
+ template <typename T>
+ inline auto
+ operator> (const T& x, const version& y) -> decltype (x.epoch > 0)
+ {
+ return x.epoch > y.epoch () ||
+ (x.epoch == y.epoch () &&
+ x.canonical_upstream > y.canonical_upstream ()) ||
+ (x.epoch == y.epoch () &&
+ x.canonical_upstream == y.canonical_upstream () &&
+ x.revision > y.revision ());
+ }
+
+ template <typename T>
+ inline auto
+ order_by_version_desc (const T& x) -> //decltype ("ORDER BY" + x.epoch)
+ decltype (x.epoch == 0)
+ {
+ return "ORDER BY"
+ + x.epoch + "DESC,"
+ + x.canonical_upstream + "DESC,"
+ + x.revision + "DESC";
+ }
}
#include <bpkg/package.ixx>
diff --git a/bpkg/package.cxx b/bpkg/package.cxx
index 1862fe4..ad54e51 100644
--- a/bpkg/package.cxx
+++ b/bpkg/package.cxx
@@ -10,58 +10,28 @@ using namespace std;
namespace bpkg
{
- // repository
- //
- repository::_id_type repository::
- _id () const
- {
- return _id_type {location.canonical_name (), location.string ()};
- }
-
- void repository::
- _id (_id_type&& l)
- {
- location = repository_location (move (l.location));
- assert (location.canonical_name () == l.name);
- }
-
- // package_version_id
+ // available_package_id
//
bool
- operator< (const package_version_id& x, const package_version_id& y)
+ operator< (const available_package_id& x, const available_package_id& y)
{
int r (x.name.compare (y.name));
if (r != 0)
return r < 0;
- if (x.epoch != y.epoch)
- return x.epoch < y.epoch;
+ const auto& xv (x.version);
+ const auto& yv (y.version);
+
+ if (xv.epoch != yv.epoch)
+ return xv.epoch < yv.epoch;
- r = x.upstream.compare (y.upstream);
+ r = xv.canonical_upstream.compare (yv.canonical_upstream);
if (r != 0)
return r < 0;
- return x.revision < y.revision;
- }
-
- // available_package
- //
- available_package::_id_type available_package::
- _id () const
- {
- return _id_type {package_version_id (name, version), version.upstream ()};
- }
-
- void available_package::
- _id (_id_type&& v)
- {
- name = move (v.data.name);
- version = version_type (v.data.epoch,
- move (v.version_original_upstream),
- v.data.revision);
- assert (version.canonical_upstream () == v.data.upstream);
+ return xv.revision < yv.revision;
}
// state
diff --git a/bpkg/package.ixx b/bpkg/package.ixx
index 79cb0b1..571f866 100644
--- a/bpkg/package.ixx
+++ b/bpkg/package.ixx
@@ -4,14 +4,12 @@
namespace bpkg
{
- // package_version_id
+ // available_package_id
//
- inline package_version_id::
- package_version_id (string n, const version& v)
+ inline available_package_id::
+ available_package_id (string n, const bpkg::version& v)
: name (move (n)),
- epoch (v.epoch ()),
- upstream (v.canonical_upstream ()),
- revision (v.revision ())
+ version {v.epoch (), v.canonical_upstream (), v.revision ()}
{
}
}
diff --git a/bpkg/package.xml b/bpkg/package.xml
index 1508d61..8bb959d 100644
--- a/bpkg/package.xml
+++ b/bpkg/package.xml
@@ -48,39 +48,39 @@
<table name="available_package" kind="object">
<column name="name" type="TEXT" null="true"/>
<column name="version_epoch" type="INTEGER" null="true"/>
- <column name="version_upstream" type="TEXT" null="true"/>
+ <column name="version_canonical_upstream" type="TEXT" null="true"/>
<column name="version_revision" type="INTEGER" null="true"/>
- <column name="version_original_upstream" type="TEXT" null="true"/>
+ <column name="version_upstream" type="TEXT" null="true"/>
<primary-key>
<column name="name"/>
<column name="version_epoch"/>
- <column name="version_upstream"/>
+ <column name="version_canonical_upstream"/>
<column name="version_revision"/>
</primary-key>
</table>
<table name="available_package_locations" kind="container">
<column name="name" type="TEXT" null="true"/>
<column name="version_epoch" type="INTEGER" null="true"/>
- <column name="version_upstream" type="TEXT" null="true"/>
+ <column name="version_canonical_upstream" type="TEXT" null="true"/>
<column name="version_revision" type="INTEGER" null="true"/>
<column name="repository" type="TEXT" null="true"/>
<column name="location" type="TEXT" null="true"/>
<foreign-key name="object_id_fk" on-delete="CASCADE">
<column name="name"/>
<column name="version_epoch"/>
- <column name="version_upstream"/>
+ <column name="version_canonical_upstream"/>
<column name="version_revision"/>
<references table="available_package">
<column name="name"/>
<column name="version_epoch"/>
- <column name="version_upstream"/>
+ <column name="version_canonical_upstream"/>
<column name="version_revision"/>
</references>
</foreign-key>
<index name="available_package_locations_object_id_i">
<column name="name"/>
<column name="version_epoch"/>
- <column name="version_upstream"/>
+ <column name="version_canonical_upstream"/>
<column name="version_revision"/>
</index>
<foreign-key name="repository_fk" deferrable="DEFERRED">
@@ -93,9 +93,9 @@
<table name="package" kind="object">
<column name="name" type="TEXT" null="true"/>
<column name="version_epoch" type="INTEGER" null="true"/>
- <column name="version_upstream" type="TEXT" null="true"/>
- <column name="version_revision" type="INTEGER" null="true"/>
<column name="version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="version_revision" type="INTEGER" null="true"/>
+ <column name="version_upstream" type="TEXT" null="true"/>
<column name="state" type="TEXT" null="true"/>
<column name="archive" type="TEXT" null="true"/>
<column name="purge_archive" type="INTEGER" null="true"/>
diff --git a/bpkg/pkg-fetch.cxx b/bpkg/pkg-fetch.cxx
index 1406d8d..36b80a7 100644
--- a/bpkg/pkg-fetch.cxx
+++ b/bpkg/pkg-fetch.cxx
@@ -73,7 +73,7 @@ namespace bpkg
info << "use 'bpkg rep-fetch' to fetch available packages list";
shared_ptr<available_package> p (
- db.find<available_package> (package_version_id (n, v)));
+ db.find<available_package> (available_package_id (n, v)));
if (p == nullptr)
fail << "package " << n << " " << v << " is not available";
@@ -93,7 +93,7 @@ namespace bpkg
if (verb > 1)
text << "fetching " << pl->location.leaf () << " "
- << "from " << pl->repository->name ();
+ << "from " << pl->repository->name;
a = fetch_archive (o, pl->repository->location, pl->location, c);
purge = true;
diff --git a/bpkg/pkg-status.cxx b/bpkg/pkg-status.cxx
index c75019e..dbd2bd0 100644
--- a/bpkg/pkg-status.cxx
+++ b/bpkg/pkg-status.cxx
@@ -4,7 +4,8 @@
#include <bpkg/pkg-status>
-#include <iostream> // cout
+#include <iostream> // cout
+#include <functional> // function
#include <bpkg/types>
#include <bpkg/package>
@@ -39,39 +40,126 @@ namespace bpkg
database db (open (c, trace));
transaction t (db.begin ());
+ session s;
- using query = odb::query<package>;
- query q (query::name == n);
+ level4 ([&]{trace << "package " << n << "; version " << v;});
- if (!v.empty ())
+ // First search in the packages that already exist in this configuration.
+ //
+ shared_ptr<package> p;
{
- q = q && (query::version.epoch == v.epoch () &&
- query::version.revision == v.revision () &&
- query::version.canonical_upstream == v.canonical_upstream ());
- }
+ using query = query<package>;
+ query q (query::name == n);
- shared_ptr<package> p (db.query_one<package> (q));
- t.commit ();
+ if (!v.empty ())
+ q = q && query::version == v;
+
+ p = db.query_one<package> (q);
+ }
- if (p == nullptr)
+ // Now look for available packages. If the user specified the version
+ // explicitly and we found the corresponding existing package, then
+ // no need to look for it in available packages.
+ //
+ vector<shared_ptr<available_package>> aps;
+ if (p == nullptr || v.empty ())
{
- // @@ TODO: This is where we search the packages available in
- // the repositories and if found, print its status as 'available'
- // plus a list of versions.
+ using query = query<available_package>;
+
+ query q (query::id.name == n);
+
+ // If we found an existing package, then only look for versions
+ // greater than what already exists.
//
- cout << "unknown";
+ if (p != nullptr)
+ q = q && query::id.version > p->version;
+ else if (!v.empty ())
+ //
+ // Otherwise, if the user specified the version, then only look for
+ // that specific version.
+ //
+ q = q && query::id.version == v;
+
+ q += order_by_version_desc (query::id.version);
+
+ // Only consider packages that are in repositories that were
+ // explicitly added to the configuration and their complements,
+ // transitively. While we could maybe come up with a (barely
+ // comprehensible) view/query to achieve this, doing it on the
+ // "client side" is definitely more straightforward.
+ //
+ shared_ptr<repository> root (db.load<repository> (""));
+
+ for (shared_ptr<available_package> ap:
+ pointer_result (db.query<available_package> (q)))
+ {
+ function<bool (const shared_ptr<repository>&)> find =
+ [&ap, &find](const shared_ptr<repository>& r) -> bool
+ {
+ const auto& cs (r->complements);
+
+ for (const package_location& pl: ap->locations)
+ {
+ // First check all the complements without loading them.
+ //
+ if (cs.find (pl.repository) != cs.end ())
+ return true;
+
+ // If not found, then load the complements and check them
+ // recursively.
+ //
+ for (lazy_shared_ptr<repository> cr: cs)
+ {
+ if (find (cr.load ()))
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+ level4 ([&]{trace << "available " << ap->version;});
+
+ if (find (root))
+ aps.push_back (ap);
+ }
}
- else
+
+ t.commit ();
+
+ bool found (false);
+
+ if (p != nullptr)
{
cout << p->state;
- // Also print the version of the package unless the user
- // specified it.
+ // Also print the version of the package unless the user specified it.
//
if (v.empty ())
cout << " " << p->version;
+
+ found = true;
}
+ if (!aps.empty ())
+ {
+ cout << (found ? "; " : "") << "available";
+
+ // If the user specified the version, then there will be only one
+ // entry.
+ //
+ if (v.empty ())
+ {
+ for (shared_ptr<available_package> ap: aps)
+ cout << ' ' << ap->version;
+ }
+
+ found = true;
+ }
+
+ if (!found)
+ cout << "unknown";
+
cout << endl;
}
}
diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx
index 04e09f8..1823909 100644
--- a/bpkg/rep-fetch.cxx
+++ b/bpkg/rep-fetch.cxx
@@ -33,14 +33,14 @@ namespace bpkg
tracer_guard tg (db, trace);
const repository_location& rl (r->location);
- level4 ([&]{trace << r->name () << " " << rl;});
+ level4 ([&]{trace << r->name << " " << rl;});
assert (rl.absolute () || rl.remote ());
// The fetch_*() functions below will be quiet at level 1, which
// can be quite confusing if the download hangs.
//
if (verb >= (rl.remote () ? 1 : 2))
- text << "fetching " << r->name ();
+ text << "fetching " << r->name;
r->fetched = true; // Mark as being fetched.
@@ -108,15 +108,13 @@ namespace bpkg
{
case repository_role::complement:
{
- level4 ([&]{trace << pr->name () << " complement of "
- << r->name ();});
+ level4 ([&]{trace << pr->name << " complement of " << r->name;});
r->complements.insert (lazy_shared_ptr<repository> (db, pr));
break;
}
case repository_role::prerequisite:
{
- level4 ([&]{trace << pr->name () << " prerequisite of "
- << r->name ();});
+ level4 ([&]{trace << pr->name << " prerequisite of " << r->name;});
r->prerequisites.insert (lazy_weak_ptr<repository> (db, pr));
break;
}
@@ -146,13 +144,11 @@ namespace bpkg
shared_ptr<available_package> p (
db.find<available_package> (
- package_version_id (pm.name, pm.version)));
+ available_package_id (pm.name, pm.version)));
if (p == nullptr)
{
- p.reset (new available_package {move (pm.name),
- move (pm.version),
- {}});
+ p.reset (new available_package (move (pm.name), move (pm.version)));
persist = true;
}
@@ -210,7 +206,7 @@ namespace bpkg
}
else if (ua.find (lazy_shared_ptr<repository> (db, r)) != ua.end ())
{
- level4 ([&]{trace << "cleaning " << r->name ();});
+ level4 ([&]{trace << "cleaning " << r->name;});
r->complements.clear ();
r->prerequisites.clear ();
@@ -219,7 +215,7 @@ namespace bpkg
}
else
{
- level4 ([&]{trace << "erasing " << r->name ();});
+ level4 ([&]{trace << "erasing " << r->name;});
db.erase (r);
}
}
diff --git a/bpkg/test.sh b/bpkg/test.sh
index e3d4f8d..9ff6908 100755
--- a/bpkg/test.sh
+++ b/bpkg/test.sh
@@ -56,10 +56,20 @@ function fail ()
#
function stat ()
{
- local s=`$bpkg pkg-status -d $cfg $pkg $ver`
+ local c="$bpkg pkg-status -d $cfg"
+
+ if [ $# -eq 1 ]; then
+ c="$c $pkg $ver"
+ elif [ $# -eq 2 ]; then
+ c="$c $1"; shift
+ elif [ $# -eq 3 ]; then
+ c="$c $1 $2"; shift; shift
+ fi
+
+ local s=`$c`
if [ "$s" != "$1" ]; then
- error "status: $s, expected: $1"
+ error "status: '"$s"', expected: '"$1"'"
fi
}
@@ -398,6 +408,53 @@ test pkg-purge -f $pkg
stat unknown
##
+## pkg-status (also tested in pkg-{fetch,unpack,configure,disfigure,purge}
+##
+
+test rep-create ../tests/repository/1/status/stable
+test rep-create ../tests/repository/1/status/extra
+test rep-create ../tests/repository/1/status/testing
+test rep-create ../tests/repository/1/status/unstable
+
+# basics
+#
+test cfg-create --wipe
+stat libfoo 1.0.0 "unknown"
+stat libfoo "unknown"
+test rep-add ../tests/repository/1/status/stable
+test rep-fetch
+stat libfoo 1.0.0 "available"
+stat libfoo "available 1.0.0"
+test pkg-fetch libfoo 1.0.0
+stat libfoo 1.0.0 "fetched"
+stat libfoo "fetched 1.0.0"
+
+# multiple versions/revisions
+#
+test cfg-create --wipe
+test rep-add ../tests/repository/1/status/extra
+test rep-fetch
+stat libbar "available 1.1.0-1"
+test rep-add ../tests/repository/1/status/stable
+test rep-fetch
+stat libbar "available 1.1.0-1 1.0.0"
+
+test cfg-create --wipe
+test rep-add ../tests/repository/1/status/testing
+test rep-fetch
+stat libbar "available 1.1.0 1.0.0-1 1.0.0"
+
+test cfg-create --wipe
+test rep-add ../tests/repository/1/status/unstable
+test rep-fetch
+stat libbar "available 2.0.0 1.1.0 1.0.0-1 1.0.0"
+test pkg-fetch libbar 1.0.0-1
+stat libbar "fetched 1.0.0-1; available 2.0.0 1.1.0"
+test pkg-purge libbar
+test pkg-fetch libbar 2.0.0
+stat libbar "fetched 2.0.0"
+
+##
## pkg-update
##
diff --git a/bpkg/types b/bpkg/types
index e4e1340..a5bda0e 100644
--- a/bpkg/types
+++ b/bpkg/types
@@ -9,6 +9,7 @@
#include <string>
#include <memory> // shared_ptr, unique_ptr
#include <cstddef> // size_t
+#include <cstdint> // uint{8,16,32,64}_t
#include <ostream>
#include <odb/lazy-ptr.hxx>
@@ -20,6 +21,10 @@ namespace bpkg
{
// Commonly-used types.
//
+ using std::uint8_t;
+ using std::uint16_t;
+ using std::uint32_t;
+ using std::uint64_t;
using std::size_t;
using std::string;
diff --git a/tests/repository/1/status/extra/libbar-1.1.0-1.tar.gz b/tests/repository/1/status/extra/libbar-1.1.0-1.tar.gz
new file mode 100644
index 0000000..09ffc97
--- /dev/null
+++ b/tests/repository/1/status/extra/libbar-1.1.0-1.tar.gz
Binary files differ
diff --git a/tests/repository/1/status/extra/repositories b/tests/repository/1/status/extra/repositories
new file mode 100644
index 0000000..ecaa454
--- /dev/null
+++ b/tests/repository/1/status/extra/repositories
@@ -0,0 +1,3 @@
+: 1
+location: ../stable
+:
diff --git a/tests/repository/1/status/stable/libbar-1.0.0.tar.gz b/tests/repository/1/status/stable/libbar-1.0.0.tar.gz
new file mode 100644
index 0000000..97e6e32
--- /dev/null
+++ b/tests/repository/1/status/stable/libbar-1.0.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/status/stable/libfoo-1.0.0.tar.gz b/tests/repository/1/status/stable/libfoo-1.0.0.tar.gz
new file mode 100644
index 0000000..5e7fa17
--- /dev/null
+++ b/tests/repository/1/status/stable/libfoo-1.0.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/status/stable/repositories b/tests/repository/1/status/stable/repositories
new file mode 100644
index 0000000..5b70556
--- /dev/null
+++ b/tests/repository/1/status/stable/repositories
@@ -0,0 +1 @@
+: 1
diff --git a/tests/repository/1/status/testing/libbar-1.0.0-1.tar.gz b/tests/repository/1/status/testing/libbar-1.0.0-1.tar.gz
new file mode 100644
index 0000000..e8a54ca
--- /dev/null
+++ b/tests/repository/1/status/testing/libbar-1.0.0-1.tar.gz
Binary files differ
diff --git a/tests/repository/1/status/testing/libbar-1.1.0.tar.gz b/tests/repository/1/status/testing/libbar-1.1.0.tar.gz
new file mode 100644
index 0000000..b01ac44
--- /dev/null
+++ b/tests/repository/1/status/testing/libbar-1.1.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/status/testing/repositories b/tests/repository/1/status/testing/repositories
new file mode 100644
index 0000000..7bd7269
--- /dev/null
+++ b/tests/repository/1/status/testing/repositories
@@ -0,0 +1,6 @@
+: 1
+location: ../stable
+role: complement
+:
+location: ../extra
+:
diff --git a/tests/repository/1/status/unstable/libbar-2.0.0.tar.gz b/tests/repository/1/status/unstable/libbar-2.0.0.tar.gz
new file mode 100644
index 0000000..6cc5890
--- /dev/null
+++ b/tests/repository/1/status/unstable/libbar-2.0.0.tar.gz
Binary files differ
diff --git a/tests/repository/1/status/unstable/repositories b/tests/repository/1/status/unstable/repositories
new file mode 100644
index 0000000..8f4a5f6
--- /dev/null
+++ b/tests/repository/1/status/unstable/repositories
@@ -0,0 +1,4 @@
+: 1
+location: ../testing
+role: complement
+: