aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/brep-module.conf3
-rw-r--r--libbrep/build-extra.sql3
-rw-r--r--libbrep/common.hxx30
-rw-r--r--libbrep/package.cxx12
-rw-r--r--libbrep/package.hxx17
-rw-r--r--libbrep/package.xml28
-rw-r--r--load/load.cli22
-rw-r--r--load/load.cxx240
-rw-r--r--mod/mod-package-version-details.cxx87
-rw-r--r--mod/page.cxx46
-rw-r--r--tests/load/driver.cxx1705
-rw-r--r--tests/load/git-cache/packages.manifest14
-rw-r--r--tests/load/git-cache/repositories.manifest7
-rw-r--r--tests/load/git-loadtab1
14 files changed, 1256 insertions, 959 deletions
diff --git a/etc/brep-module.conf b/etc/brep-module.conf
index 2dc738e..ca02227 100644
--- a/etc/brep-module.conf
+++ b/etc/brep-module.conf
@@ -23,6 +23,7 @@
menu Packages=
# menu Builds=?builds
# menu Submit=?submit
+# menu CI=?ci
menu About=?about
@@ -262,7 +263,7 @@ menu About=?about
# not exit in the alloted time, then it is killed and its termination is
# treated as abnormal.
#
-# submit-handler-timeout 60
+# submit-handler-timeout
# The directory to save CI request data to. If unspecified, the package CI
diff --git a/libbrep/build-extra.sql b/libbrep/build-extra.sql
index 96e355c..e0aa92a 100644
--- a/libbrep/build-extra.sql
+++ b/libbrep/build-extra.sql
@@ -14,7 +14,8 @@ DROP FOREIGN TABLE IF EXISTS build_repository;
--
CREATE FOREIGN TABLE build_repository (
name TEXT NOT NULL,
- location TEXT NOT NULL,
+ location_url TEXT NOT NULL,
+ location_type TEXT NOT NULL,
certificate_fingerprint TEXT NULL)
SERVER package_server OPTIONS (table_name 'repository');
diff --git a/libbrep/common.hxx b/libbrep/common.hxx
index 5b172ec..0163ca0 100644
--- a/libbrep/common.hxx
+++ b/libbrep/common.hxx
@@ -218,21 +218,39 @@ namespace brep
// repository_type
//
using bpkg::repository_type;
+ using bpkg::to_repository_type;
+
+ #pragma db map type(repository_type) as(string) \
+ to(to_string (?)) \
+ from(brep::to_repository_type (?))
// repository_url
//
using bpkg::repository_url;
+ #pragma db map type(repository_url) as(string) \
+ to((?).string ()) \
+ from((?).empty () ? brep::repository_url () : brep::repository_url (?))
+
// repository_location
//
using bpkg::repository_location;
- #pragma db map type(repository_location) as(string) \
- to((?).url ().string ()) \
- from(brep::repository_location ((?).empty () \
- ? bpkg::repository_url () \
- : brep::repository_url (?), \
- brep::repository_type::pkg))
+ #pragma db value
+ struct _repository_location
+ {
+ repository_url url;
+ repository_type type;
+ };
+
+ // Note that the type() call fails for an empty repository location.
+ //
+ #pragma db map type(repository_location) as(_repository_location) \
+ to(brep::_repository_location {(?).url (), \
+ (?).empty () \
+ ? brep::repository_type::pkg \
+ : (?).type ()}) \
+ from(brep::repository_location (std::move ((?).url), (?).type))
// Version comparison operators.
//
diff --git a/libbrep/package.cxx b/libbrep/package.cxx
index 5b729c8..6d4550d 100644
--- a/libbrep/package.cxx
+++ b/libbrep/package.cxx
@@ -15,16 +15,10 @@ namespace brep
{
// dependency
//
- package_name dependency::
- name () const
- {
- return package.object_id ().name;
- }
-
ostream&
operator<< (ostream& o, const dependency& d)
{
- o << d.name ();
+ o << d.name;
if (d.constraint)
o << ' ' << *d.constraint;
@@ -35,7 +29,7 @@ namespace brep
bool
operator== (const dependency& x, const dependency& y)
{
- return x.name () == y.name () && x.constraint == y.constraint;
+ return x.name == y.name && x.constraint == y.constraint;
}
bool
@@ -67,6 +61,7 @@ namespace brep
requirements_type rq,
build_constraints_type bc,
optional<path> lc,
+ optional<string> fr,
optional<string> sh,
shared_ptr<repository_type> rp)
: id (move (nm), vr),
@@ -93,6 +88,7 @@ namespace brep
: build_constraints_type ()),
internal_repository (move (rp)),
location (move (lc)),
+ fragment (move (fr)),
sha256sum (move (sh))
{
assert (internal_repository->internal);
diff --git a/libbrep/package.hxx b/libbrep/package.hxx
index e7a8338..3d281b0 100644
--- a/libbrep/package.hxx
+++ b/libbrep/package.hxx
@@ -120,17 +120,16 @@ namespace brep
{
using package_type = brep::package;
- lazy_shared_ptr<package_type> package;
+ package_name name;
optional<dependency_constraint> constraint;
- // Prerequisite package name.
+ // Resolved dependency package. NULL if the repository load was shallow
+ // and so the package dependencies are not resolved.
//
- package_name
- name () const;
+ lazy_shared_ptr<package_type> package;
// Database mapping.
//
- #pragma db member(package) column("") not_null
#pragma db member(constraint) column("")
};
@@ -212,7 +211,7 @@ namespace brep
//
uint16_t priority;
- optional<string> url;
+ optional<string> interface_url;
// Present only for internal repositories.
//
@@ -318,6 +317,7 @@ namespace brep
requirements_type,
build_constraints_type,
optional<path> location,
+ optional<string> fragment,
optional<string> sha256sum,
shared_ptr<repository_type>);
@@ -370,6 +370,11 @@ namespace brep
//
optional<path> location;
+ // Present only for packages that come from the supporting fragmentation
+ // internal repository (normally version control-based).
+ //
+ optional<string> fragment;
+
// Present only for internal packages.
//
optional<string> sha256sum;
diff --git a/libbrep/package.xml b/libbrep/package.xml
index 47ff071..55baae9 100644
--- a/libbrep/package.xml
+++ b/libbrep/package.xml
@@ -2,15 +2,17 @@
<model version="7">
<table name="repository" kind="object">
<column name="name" type="TEXT" null="false"/>
- <column name="location" type="TEXT" null="false"/>
+ <column name="location_url" type="TEXT" null="false"/>
+ <column name="location_type" type="TEXT" null="false"/>
<column name="display_name" type="TEXT" null="false"/>
<column name="priority" type="INTEGER" null="false"/>
- <column name="url" type="TEXT" null="true"/>
+ <column name="interface_url" type="TEXT" null="true"/>
<column name="email" type="TEXT" null="true"/>
<column name="email_comment" type="TEXT" null="true"/>
<column name="summary" type="TEXT" null="true"/>
<column name="description" type="TEXT" null="true"/>
- <column name="cache_location" type="TEXT" null="false"/>
+ <column name="cache_location_url" type="TEXT" null="false"/>
+ <column name="cache_location_type" type="TEXT" null="false"/>
<column name="certificate_fingerprint" type="TEXT" null="true"/>
<column name="certificate_name" type="TEXT" null="true"/>
<column name="certificate_organization" type="TEXT" null="true"/>
@@ -99,6 +101,7 @@
<column name="build_email_comment" type="TEXT" null="true"/>
<column name="internal_repository" type="TEXT" null="true"/>
<column name="location" type="TEXT" null="true"/>
+ <column name="fragment" type="TEXT" null="true"/>
<column name="sha256sum" type="TEXT" null="true"/>
<column name="search_index" type="tsvector" null="true"/>
<primary-key>
@@ -259,10 +262,6 @@
<column name="dependency_index" type="BIGINT" null="false"/>
<column name="index" type="BIGINT" null="false"/>
<column name="dep_name" type="CITEXT" null="false"/>
- <column name="dep_version_epoch" type="INTEGER" null="false"/>
- <column name="dep_version_canonical_upstream" type="TEXT" null="false"/>
- <column name="dep_version_canonical_release" type="TEXT" null="false" options="COLLATE &quot;C&quot;"/>
- <column name="dep_version_revision" type="INTEGER" null="false"/>
<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"/>
@@ -277,6 +276,11 @@
<column name="dep_max_version_release" type="TEXT" null="true"/>
<column name="dep_min_open" type="BOOLEAN" null="true"/>
<column name="dep_max_open" type="BOOLEAN" null="true"/>
+ <column name="dep_package_name" type="CITEXT" null="true"/>
+ <column name="dep_package_version_epoch" type="INTEGER" null="true"/>
+ <column name="dep_package_version_canonical_upstream" type="TEXT" null="true"/>
+ <column name="dep_package_version_canonical_release" type="TEXT" null="true" options="COLLATE &quot;C&quot;"/>
+ <column name="dep_package_version_revision" type="INTEGER" null="true"/>
<foreign-key name="object_id_fk" on-delete="CASCADE">
<column name="name"/>
<column name="version_epoch"/>
@@ -299,11 +303,11 @@
<column name="version_revision"/>
</index>
<foreign-key name="dep_package_fk" deferrable="DEFERRED">
- <column name="dep_name"/>
- <column name="dep_version_epoch"/>
- <column name="dep_version_canonical_upstream"/>
- <column name="dep_version_canonical_release"/>
- <column name="dep_version_revision"/>
+ <column name="dep_package_name"/>
+ <column name="dep_package_version_epoch"/>
+ <column name="dep_package_version_canonical_upstream"/>
+ <column name="dep_package_version_canonical_release"/>
+ <column name="dep_package_version_revision"/>
<references table="package">
<column name="name"/>
<column name="version_epoch"/>
diff --git a/load/load.cli b/load/load.cli
index 6db6048..bbe54ff 100644
--- a/load/load.cli
+++ b/load/load.cli
@@ -10,7 +10,7 @@ include <libbrep/types.hxx>;
"\section=1"
"\name=brep-load"
-"\summary=load build2 repositories into brep package database"
+"\summary=load repositories into brep package database"
{
"<options> <loadtab>",
@@ -23,10 +23,10 @@ include <libbrep/types.hxx>;
\h|DESCRIPTION|
- \cb{brep-load} reads the list of repositories from the specified
- <loadtab> configuration file, fetches their manifest files, and loads the
- repository and package information into the \cb{package} database, suitable
- for consumption by the \cb{brep} web module.
+ \cb{brep-load} reads the list of repositories from the specified <loadtab>
+ configuration file, fetches their manifest files, and loads the repository
+ and package information into the \cb{package} database, suitable for
+ consumption by the \cb{brep} web module.
Note that \cb{brep-load} expects the \cb{package} database schema to have
already been created using \l{brep-migrate(1)}.
@@ -40,6 +40,18 @@ class options
{
"\h|OPTIONS|"
+ bool --force
+ {
+ "Reload package information regardless of the repository manifest file
+ timestamps."
+ };
+
+ bool --shallow
+ {
+ "Don't load package information from prerequisite or complement
+ repositories."
+ };
+
std::string --db-user|-u
{
"<user>",
diff --git a/load/load.cxx b/load/load.cxx
index 1875f2a..01d77c2 100644
--- a/load/load.cxx
+++ b/load/load.cxx
@@ -68,12 +68,34 @@ struct internal_repository
using internal_repositories = vector<internal_repository>;
- // Parse loadtab file.
- //
- // loadtab consists of lines in the following format:
- //
- // <remote-repository-location> <display-name> cache:<local-repository-location> [fingerprint:<fingerprint>]
- //
+// Parse loadtab file.
+//
+// loadtab consists of lines in the following format:
+//
+// <remote-repository-location> <display-name> cache:<local-repository-location> [fingerprint:<fingerprint>]
+//
+// Note that if the remote repository location is a pkg repository, then the
+// repository cache should be its local copy. Otherwise, the cache directory
+// is expected to contain just repositories.manifest and packages.manifest
+// files as dumped by bpkg-rep-info, for example:
+//
+// $ bpkg rep-info --manifest
+// --repositories-file repositories.manifest
+// --packages-file packages.manifest
+// <remote-repository-location>
+//
+// Specifically, the packages.manifest is not a pkg package manifest list. It
+// contains a raw list of package manifests that may contain values forbidden
+// for the pkg package manifest list (description-file, changes-file) and may
+// omit the required ones (sha256sum).
+//
+// @@ Latter, we may also want to support loading bpkg repositories using
+// manifest files produced by bpkg-rep-info command. This, in particular,
+// will allow handling CI requests for bpkg repositories.
+//
+// The current thinking is that the CI handler will be able to "suggest"
+// this using (the planned) cache:file+dir:// form.
+//
static internal_repositories
load_repositories (path p)
{
@@ -116,8 +138,10 @@ load_repositories (path p)
try
{
- r.location = repository_location (repository_url (tl[i].value),
- repository_type::pkg);
+ repository_url u (tl[i].value);
+
+ r.location = repository_location (u,
+ guess_type (u, false /* local */));
}
catch (const invalid_argument& e)
{
@@ -164,9 +188,15 @@ load_repositories (path p)
if (cache_path.relative ())
cache_path = p.directory () / cache_path;
+ // A non-pkg repository cache is not a real repository (see
+ // above). We create the location of the dir type for such a cache
+ // to distinguish it when it comes to the manifest files parsing.
+ //
r.cache_location = repository_location (
repository_url (cache_path.string ()),
- repository_type::pkg);
+ r.location.type () == repository_type::pkg
+ ? r.location.type ()
+ : repository_type::dir);
// Created from the absolute path repository location can not be
// other than absolute.
@@ -318,8 +348,10 @@ load_packages (const shared_ptr<repository>& rp, database& db)
//
assert (!rp->cache_location.empty ());
- pkg_package_manifests pkm;
- path p (rp->cache_location.path () / packages);
+ vector<package_manifest> pms;
+ const repository_location& cl (rp->cache_location);
+
+ path p (cl.path () / packages);
try
{
@@ -327,7 +359,25 @@ load_packages (const shared_ptr<repository>& rp, database& db)
rp->packages_timestamp = file_mtime (p);
manifest_parser mp (ifs, p.string ());
- pkm = pkg_package_manifests (mp);
+
+ // If the repository cache directory is not a pkg repository, then the
+ // packages.manifest file it contains is a raw list of the package
+ // manifests that we need to parse manually (see above).
+ //
+ if (cl.type () != repository_type::pkg)
+ {
+ // We put no restrictions on the manifest values present since it's not
+ // critical for displaying and building if the packages omit some
+ // manifest values (see libbpkg/manifest.hxx for details).
+ //
+ for (manifest_name_value nv (mp.next ()); !nv.empty (); nv = mp.next ())
+ pms.emplace_back (mp,
+ move (nv),
+ false /* ignore_unknown */,
+ package_manifest_flags::none);
+ }
+ else
+ pms = pkg_package_manifests (mp);
}
catch (const io_error& e)
{
@@ -335,15 +385,15 @@ load_packages (const shared_ptr<repository>& rp, database& db)
throw failed ();
}
- for (auto& pm: pkm)
+ for (auto& pm: pms)
{
shared_ptr<package> p (
db.find<package> (package_id (pm.name, pm.version)));
// sha256sum should always be present if the package manifest comes from
- // the packages.manifest file.
+ // the packages.manifest file belonging to the pkg repository.
//
- assert (pm.sha256sum);
+ assert (pm.sha256sum || cl.type () != repository_type::pkg);
if (p == nullptr)
{
@@ -354,23 +404,34 @@ load_packages (const shared_ptr<repository>& rp, database& db)
optional<string> dsc;
if (pm.description)
{
- assert (!pm.description->file);
- dsc = move (pm.description->text);
+ // The description value should not be of the file type if the
+ // package manifest comes from the pkg repository.
+ //
+ assert (!pm.description->file || cl.type () != repository_type::pkg);
+
+ if (!pm.description->file)
+ dsc = move (pm.description->text);
}
string chn;
for (auto& c: pm.changes)
{
- assert (!c.file);
+ // The changes value should not be of the file type if the package
+ // manifest comes from the pkg repository.
+ //
+ assert (!c.file || cl.type () != repository_type::pkg);
- if (chn.empty ())
- chn = move (c.text);
- else
+ if (!c.file)
{
- if (chn.back () != '\n')
- chn += '\n'; // Always have a blank line as a separator.
+ if (chn.empty ())
+ chn = move (c.text);
+ else
+ {
+ if (chn.back () != '\n')
+ chn += '\n'; // Always have a blank line as a separator.
- chn += "\n" + c.text;
+ chn += "\n" + c.text;
+ }
}
}
@@ -392,14 +453,12 @@ load_packages (const shared_ptr<repository>& rp, database& db)
ds.emplace_back (pda.conditional, pda.buildtime, move (pda.comment));
for (auto& pd: pda)
- // Proper version will be assigned during dependency resolution
- // procedure. Here we rely on the fact the foreign key constraint
- // check is deferred until the current transaction commit.
+ // The package member will be assigned during dependency
+ // resolution procedure.
//
- ds.back ().push_back ({
- lazy_shared_ptr<package> (
- db, package_id (move (pd.name), version ())),
- move (pd.constraint)});
+ ds.back ().push_back ({move (pd.name),
+ move (pd.constraint),
+ nullptr /* package */});
}
// Cache before the package name is moved.
@@ -427,6 +486,7 @@ load_packages (const shared_ptr<repository>& rp, database& db)
move (pm.requirements),
move (pm.build_constraints),
move (pm.location),
+ move (pm.fragment),
move (pm.sha256sum),
rp);
}
@@ -444,13 +504,24 @@ load_packages (const shared_ptr<repository>& rp, database& db)
//
assert (!rp->internal || p->internal ());
- if (rp->internal && pm.sha256sum != p->sha256sum)
- cerr << "warning: sha256sum mismatch for package " << p->id.name
- << " " << p->version << endl
- << " info: " << p->internal_repository.load ()->location
- << " has " << *p->sha256sum << endl
- << " info: " << rp->location << " has " << *pm.sha256sum
- << endl;
+ // Note that the sha256sum manifest value can only be present if the
+ // package comes from the pkg repository.
+ //
+ if (rp->internal && pm.sha256sum)
+ {
+ // Save the package sha256sum if it is not present yet, match
+ // otherwise.
+ //
+ if (!p->sha256sum)
+ p->sha256sum = move (pm.sha256sum);
+ else if (*pm.sha256sum != *p->sha256sum)
+ cerr << "warning: sha256sum mismatch for package " << p->id.name
+ << " " << p->version << endl
+ << " info: " << p->internal_repository.load ()->location
+ << " has " << *p->sha256sum << endl
+ << " info: " << rp->location << " has " << *pm.sha256sum
+ << endl;
+ }
p->other_repositories.push_back (rp);
db.update (p);
@@ -460,13 +531,15 @@ load_packages (const shared_ptr<repository>& rp, database& db)
db.persist (rp); // Save the repository state.
}
-// Load the repository manifest values, prerequsite repositories, and their
-// complements state from the repositories.manifest file. Update the repository
-// persistent state to save changed members. Should be called once per
-// persisted internal repository.
+// Load the repository manifest values from the repositories.manifest file.
+// Unless this is a shallow load, also load prerequsite repositories and
+// their complements state. Update the repository persistent state to save
+// changed members. Should be called once per persisted internal repository.
//
static void
-load_repositories (const shared_ptr<repository>& rp, database& db)
+load_repositories (const shared_ptr<repository>& rp,
+ database& db,
+ bool shallow)
{
// repositories_timestamp other than timestamp_nonexistent signals that
// repository prerequisites are already loaded.
@@ -508,11 +581,11 @@ load_repositories (const shared_ptr<repository>& rp, database& db)
if (rm.effective_role () == repository_role::base)
{
- assert (rp->location.remote () && !rp->url);
+ assert (rp->location.remote () && !rp->interface_url);
// Update the base repository with manifest values.
//
- rp->url = rm.effective_url (rp->location);
+ rp->interface_url = rm.effective_url (rp->location);
// @@ Should we throw if url is not available for external repository ?
// Can, basically, repository be available on the web but have no web
@@ -521,11 +594,11 @@ load_repositories (const shared_ptr<repository>& rp, database& db)
// Yes, there can be no web interface. So we should just not form
// links to packages from such repos.
//
- if (rp->url)
+ if (rp->interface_url)
{
// Normalize web interface url adding trailing '/' if not present.
//
- auto& u (*rp->url);
+ auto& u (*rp->interface_url);
assert (!u.empty ());
if (u.back () != '/')
u += '/';
@@ -561,8 +634,12 @@ load_repositories (const shared_ptr<repository>& rp, database& db)
continue;
}
- // Load prerequisite or complement repository.
+ // Load prerequisite or complement repository unless this is a shallow
+ // load.
//
+ if (shallow)
+ continue;
+
assert (!rm.location.empty ());
repository_location rl;
@@ -581,8 +658,7 @@ load_repositories (const shared_ptr<repository>& rp, database& db)
{
// Absolute path location make no sense for the web interface.
//
- if (rm.location.type () != repository_type::pkg ||
- rm.location.absolute ())
+ if (rm.location.absolute ())
bad_location ();
// Convert the relative repository location to remote one, leave remote
@@ -639,7 +715,7 @@ load_repositories (const shared_ptr<repository>& rp, database& db)
}
load_packages (pr, db);
- load_repositories (pr, db);
+ load_repositories (pr, db, false /* shallow */);
}
db.update (rp);
@@ -680,7 +756,7 @@ find (const lazy_shared_ptr<repository>& r,
return false;
}
-// Resolve package dependencies. Ensure that the best matching dependency
+// Resolve package dependencies. Make sure that the best matching dependency
// belongs to the package repositories, their immediate prerequisite
// repositories, or their complements, recursively. Should be called once per
// internal package.
@@ -701,10 +777,10 @@ resolve_dependencies (package& p, database& db)
{
// Dependency should not be resolved yet.
//
- assert (d.package.object_id ().version.empty ());
+ assert (d.package == nullptr);
using query = query<package>;
- query q (query::id.name == d.name ());
+ query q (query::id.name == d.name);
const auto& vm (query::id.version);
if (d.constraint)
@@ -755,7 +831,7 @@ resolve_dependencies (package& p, database& db)
}
}
- if (d.package.object_id ().version.empty ())
+ if (d.package == nullptr)
{
cerr << "error: can't resolve dependency " << d << " of the package "
<< p.id.name << " " << p.version << endl
@@ -778,16 +854,17 @@ resolve_dependencies (package& p, database& db)
using package_ids = vector<package_id>;
-// Ensure the package dependency chain do not contain the package id. Throw
-// failed otherwise. Continue the chain with the package id and call itself
-// recursively for each prerequisite of the package. Should be called once per
-// internal package.
+// Make sure the package dependency chain doesn't contain the package id.
+// Throw failed otherwise. Continue the chain with the package id and call
+// itself recursively for each prerequisite of the package. Should be called
+// once per internal package.
//
// @@ This should probably be eventually moved to bpkg.
//
static void
-detect_dependency_cycle (
- const package_id& id, package_ids& chain, database& db)
+detect_dependency_cycle (const package_id& id,
+ package_ids& chain,
+ database& db)
{
// Package of one version depending on the same package of another version
// is something obscure. So the comparison is made up to a package name.
@@ -1042,7 +1119,7 @@ try
//
internal_repositories irs (load_repositories (path (argv[1])));
- if (changed (irs, db))
+ if (ops.force () || changed (irs, db))
{
// Rebuild repositories persistent state from scratch.
//
@@ -1055,11 +1132,13 @@ try
uint16_t priority (1);
for (const auto& ir: irs)
{
- optional<certificate> cert (
- certificate_info (
+ optional<certificate> cert;
+
+ if (ir.location.type () == repository_type::pkg)
+ cert = certificate_info (
ops,
!ir.cache_location.empty () ? ir.cache_location : ir.location,
- ir.fingerprint));
+ ir.fingerprint);
shared_ptr<repository> r (
make_shared<repository> (ir.location,
@@ -1080,24 +1159,27 @@ try
shared_ptr<repository> r (
db.load<repository> (ir.location.canonical_name ()));
- load_repositories (r, db);
+ load_repositories (r, db, ops.shallow ());
}
- session s;
- using query = query<package>;
-
- // Resolve internal packages dependencies.
+ // Resolve internal packages dependencies unless this is a shallow load.
//
- for (auto& p:
- db.query<package> (query::internal_repository.is_not_null ()))
- resolve_dependencies (p, db);
+ if (!ops.shallow ())
+ {
+ session s;
+ using query = query<package>;
- // Ensure there is no package dependency cycles.
- //
- package_ids chain;
- for (const auto& p:
- db.query<package> (query::internal_repository.is_not_null ()))
- detect_dependency_cycle (p.id, chain, db);
+ for (auto& p:
+ db.query<package> (query::internal_repository.is_not_null ()))
+ resolve_dependencies (p, db);
+
+ // Make sure there is no package dependency cycles.
+ //
+ package_ids chain;
+ for (const auto& p:
+ db.query<package> (query::internal_repository.is_not_null ()))
+ detect_dependency_cycle (p.id, chain, db);
+ }
}
t.commit ();
diff --git a/mod/mod-package-version-details.cxx b/mod/mod-package-version-details.cxx
index 0e3b3f7..d2d96d2 100644
--- a/mod/mod-package-version-details.cxx
+++ b/mod/mod-package-version-details.cxx
@@ -184,8 +184,6 @@ handle (request& rq, response& rs)
: P_DESCRIPTION (*d, options_->package_description (),
url (!full, id)));
- assert (pkg->location && pkg->sha256sum);
-
const repository_location& rl (pkg->internal_repository.load ()->location);
s << TABLE(CLASS="proplist", ID="version")
@@ -198,10 +196,22 @@ handle (request& rq, response& rs)
<< TR_PRIORITY (pkg->priority)
<< TR_LICENSES (pkg->license_alternatives)
<< TR_REPOSITORY (rl.canonical_name (), root)
- << TR_LOCATION (rl)
- << TR_DOWNLOAD (rl.string () + "/" + pkg->location->string ())
- << TR_SHA256SUM (*pkg->sha256sum)
- << ~TBODY
+ << TR_LOCATION (rl);
+
+ if (rl.type () == repository_type::pkg)
+ {
+ assert (pkg->location);
+
+ s << TR_DOWNLOAD (rl.string () + "/" + pkg->location->string ());
+ }
+
+ if (pkg->fragment)
+ s << TR_VALUE ("fragment", *pkg->fragment);
+
+ if (pkg->sha256sum)
+ s << TR_SHA256SUM (*pkg->sha256sum);
+
+ s << ~TBODY
<< ~TABLE
<< TABLE(CLASS="proplist", ID="package")
@@ -267,38 +277,49 @@ handle (request& rq, response& rs)
if (&d != &da[0])
s << " | ";
- shared_ptr<package> p (d.package.load ());
- assert (p->internal () || !p->other_repositories.empty ());
-
- shared_ptr<repository> r (
- p->internal ()
- ? p->internal_repository.load ()
- : p->other_repositories[0].load ());
-
const auto& dcon (d.constraint);
- const package_name& dname (p->id.name);
- string ename (mime_url_encode (dname.string (), false));
-
- if (r->url)
- {
- string u (*r->url + ename);
- s << A(HREF=u) << dname << ~A;
+ const package_name& dname (d.name);
- if (dcon)
- s << ' ' << A(HREF=u + "/" + p->version.string ()) << *dcon << ~A;
- }
- else if (p->internal ())
+ // Try to display the dependency as a link if it is resolved.
+ // Otherwise display it as a plain text.
+ //
+ if (d.package != nullptr)
{
- dir_path u (root / dir_path (ename));
- s << A(HREF=u) << dname << ~A;
-
- if (dcon)
- s << ' ' << A(HREF=u / path (p->version.string ())) << *dcon << ~A;
+ shared_ptr<package> p (d.package.load ());
+ assert (p->internal () || !p->other_repositories.empty ());
+
+ shared_ptr<repository> r (
+ p->internal ()
+ ? p->internal_repository.load ()
+ : p->other_repositories[0].load ());
+
+ string ename (mime_url_encode (dname.string (), false));
+
+ if (r->interface_url)
+ {
+ string u (*r->interface_url + ename);
+ s << A(HREF=u) << dname << ~A;
+
+ if (dcon)
+ s << ' '
+ << A(HREF=u + "/" + p->version.string ()) << *dcon << ~A;
+ }
+ else if (p->internal ())
+ {
+ dir_path u (root / dir_path (ename));
+ s << A(HREF=u) << dname << ~A;
+
+ if (dcon)
+ s << ' '
+ << A(HREF=u / path (p->version.string ())) << *dcon << ~A;
+ }
+ else
+ // Display the dependency as a plain text if no repository URL
+ // available.
+ //
+ s << d;
}
else
- // Display the dependency as a plain text if no repository URL
- // available.
- //
s << d;
}
diff --git a/mod/page.cxx b/mod/page.cxx
index 3a6e989..46b5e71 100644
--- a/mod/page.cxx
+++ b/mod/page.cxx
@@ -401,7 +401,7 @@ namespace brep
//
set<package_name> names;
for (const auto& da: d)
- names.emplace (da.name ());
+ names.emplace (da.name);
bool mult (names.size () > 1);
@@ -411,7 +411,7 @@ namespace brep
bool first (true);
for (const auto& da: d)
{
- package_name n (da.name ());
+ const package_name& n (da.name);
if (names.find (n) != names.end ())
{
names.erase (n);
@@ -421,24 +421,32 @@ namespace brep
else
s << " | ";
- shared_ptr<package> p (da.package.load ());
- assert (p->internal () || !p->other_repositories.empty ());
-
- shared_ptr<repository> r (
- p->internal ()
- ? p->internal_repository.load ()
- : p->other_repositories[0].load ());
-
- auto en (mime_url_encode (n.string (), false));
-
- if (r->url)
- s << A(HREF=*r->url + en) << n << ~A;
- else if (p->internal ())
- s << A(HREF=root_ / path (en)) << n << ~A;
+ // Try to display the dependency as a link if it is resolved.
+ // Otherwise display it as plain text.
+ //
+ if (da.package != nullptr)
+ {
+ shared_ptr<package> p (da.package.load ());
+ assert (p->internal () || !p->other_repositories.empty ());
+
+ shared_ptr<repository> r (
+ p->internal ()
+ ? p->internal_repository.load ()
+ : p->other_repositories[0].load ());
+
+ auto en (mime_url_encode (n.string (), false));
+
+ if (r->interface_url)
+ s << A(HREF=*r->interface_url + en) << n << ~A;
+ else if (p->internal ())
+ s << A(HREF=root_ / path (en)) << n << ~A;
+ else
+ // Display the dependency as plain text if no repository URL
+ // available.
+ //
+ s << n;
+ }
else
- // Display the dependency as a plain text if no repository URL
- // available.
- //
s << n;
}
}
diff --git a/tests/load/driver.cxx b/tests/load/driver.cxx
index 8e7c86e..b387b9b 100644
--- a/tests/load/driver.cxx
+++ b/tests/load/driver.cxx
@@ -60,29 +60,53 @@ namespace bpkg
}
}
+static void
+test_pkg_repos (const cstrings& loader_args,
+ const dir_path& loadtab_dir,
+ odb::pgsql::database&);
+
+static void
+test_git_repos (const cstrings& loader_args,
+ const dir_path& loadtab_dir,
+ odb::pgsql::database&);
+
int
main (int argc, char* argv[])
{
auto print_usage = [argv]()
{
- cerr << "usage: " << argv[0]
- << " <loader_path> [loader_options] <loadtab_file>" << endl;
+ cerr << "usage: " << argv[0] << " (pkg|git) "
+ << "<loader-path> [loader-options] <loadtab-dir>" << endl;
};
- if (argc < 3)
+ if (argc < 4)
{
print_usage ();
return 1;
}
+ int i (1);
+ repository_type rt;
+
+ try
+ {
+ rt = to_repository_type (argv[i++]);
+ }
+ catch (const invalid_argument&)
+ {
+ print_usage ();
+ return 1;
+ }
+
+ // Parse the database options.
+ //
string user;
string password;
string name ("brep_package");
string host;
unsigned int port (0);
- int i (2);
- for (; i < argc - 1; ++i)
+ for (++i; i < argc - 1; ++i)
{
string n (argv[i]);
if (n == "--db-user" || n == "-u")
@@ -103,32 +127,24 @@ main (int argc, char* argv[])
return 1;
}
- try
- {
- path cp (argv[argc - 1]);
+ dir_path loadtab_dir (argv[i]);
- // Make configuration file path absolute to use it's directory as base for
- // internal repositories relative local paths.
- //
- if (cp.relative ())
- cp.complete ();
-
- // Update the packages.manifest file timestamp to enforce the loader to
- // update the persistent state.
- //
- path p (cp.directory () / dir_path ("1/stable") / packages);
- char const* args[] = {"touch", p.string ().c_str (), nullptr};
- assert (process (args).wait ());
-
- timestamp srt (file_mtime (p));
+ // Make configuration file directory absolute to use it as base for internal
+ // repositories relative local paths.
+ //
+ if (loadtab_dir.relative ())
+ loadtab_dir.complete ();
- // Run the loader.
- //
- char const** ld_args (const_cast<char const**> (argv + 1));
- assert (process (ld_args).wait ());
+ // Extract the loader args that are common for all tests (database options,
+ // etc). Note that they don't contain the loadtab path and the trailing
+ // NULL.
+ //
+ cstrings loader_args;
+ for (int i (2); i != argc - 1; ++i)
+ loader_args.push_back (argv[i]);
- // Check persistent objects validity.
- //
+ try
+ {
odb::pgsql::database db (
user,
password,
@@ -137,773 +153,868 @@ main (int argc, char* argv[])
port,
"options='-c default_transaction_isolation=serializable'");
+ switch (rt)
{
- session s;
- transaction t (db.begin ());
-
- assert (db.query<repository> ().size () == 7);
- assert (db.query<package> ().size () == 18);
-
- shared_ptr<repository> sr (
- db.load<repository> ("pkg:dev.cppget.org/stable"));
-
- shared_ptr<repository> mr (
- db.load<repository> ("pkg:dev.cppget.org/math"));
-
- shared_ptr<repository> cr (
- db.load<repository> ("pkg:dev.cppget.org/misc"));
-
- shared_ptr<repository> tr (
- db.load<repository> ("pkg:dev.cppget.org/testing"));
-
- shared_ptr<repository> gr (
- db.load<repository> ("pkg:dev.cppget.org/staging"));
-
- // Verify 'stable' repository.
- //
- assert (sr->location.canonical_name () == "pkg:dev.cppget.org/stable");
- assert (sr->location.string () ==
- "http://dev.cppget.org/1/stable");
- assert (sr->display_name == "stable");
- assert (sr->priority == 1);
- assert (!sr->url);
- assert (sr->email && *sr->email == "repoman@dev.cppget.org" &&
- sr->email->comment == "public mailing list");
- assert (sr->summary &&
- *sr->summary == "General C++ package stable repository");
- assert (sr->description && *sr->description ==
- "This is the awesome C++ package repository full of exciting "
- "stuff.");
-
- dir_path srp (cp.directory () / dir_path ("1/stable"));
- assert (sr->cache_location.path () == srp.normalize ());
-
- assert (sr->packages_timestamp == srt);
- assert (sr->repositories_timestamp ==
- file_mtime (sr->cache_location.path () / repositories));
-
- assert (sr->internal);
- assert (sr->complements.empty ());
- assert (sr->prerequisites.size () == 2);
- assert (sr->prerequisites[0].load () == cr);
- assert (sr->prerequisites[1].load () == mr);
-
- // Verify libfoo package versions.
- //
- // libfoo-+0-X.Y
- //
- shared_ptr<package> fpvxy (
- db.load<package> (
- package_id (package_name ("libfoo"), version ("+0-X.Y"))));
-
- assert (fpvxy->project == package_name ("libfoo"));
- assert (fpvxy->summary == "The Foo Library");
- assert (fpvxy->tags.empty ());
- assert (!fpvxy->description);
- assert (!fpvxy->url);
- assert (!fpvxy->package_url);
- assert (!fpvxy->email);
- assert (!fpvxy->package_email);
-
- assert (fpvxy->internal_repository.load () == mr);
- assert (fpvxy->other_repositories.empty ());
-
- assert (fpvxy->priority == priority::low);
- assert (fpvxy->changes.empty ());
-
- assert (fpvxy->license_alternatives.size () == 1);
- assert (fpvxy->license_alternatives[0].size () == 1);
- assert (fpvxy->license_alternatives[0][0] == "MIT");
-
- assert (fpvxy->dependencies.empty ());
- assert (fpvxy->requirements.empty ());
-
- assert (check_location (fpvxy));
-
- assert (fpvxy->sha256sum && *fpvxy->sha256sum ==
- "c994fd49f051ab7fb25f3a4e68ca878e484c5d3c2cb132b37d41224b0621b618");
-
- // libfoo-1.0
- //
- shared_ptr<package> fpv1 (
- db.load<package> (
- package_id (package_name ("libfoo"), version ("1.0"))));
-
- assert (fpv1->summary == "The Foo Library");
- assert (fpv1->tags.empty ());
- assert (!fpv1->description);
- assert (!fpv1->url);
- assert (!fpv1->package_url);
- assert (!fpv1->email);
- assert (!fpv1->package_email);
-
- assert (fpv1->internal_repository.load () == sr);
- assert (fpv1->other_repositories.size () == 2);
- assert (fpv1->other_repositories[0].load () == mr);
- assert (fpv1->other_repositories[1].load () == cr);
-
- assert (fpv1->priority == priority::low);
- assert (fpv1->changes.empty ());
-
- assert (fpv1->license_alternatives.size () == 1);
- assert (fpv1->license_alternatives[0].size () == 1);
- assert (fpv1->license_alternatives[0][0] == "MIT");
-
- assert (fpv1->dependencies.empty ());
- assert (fpv1->requirements.empty ());
-
- assert (check_location (fpv1));
-
- assert (fpv1->sha256sum && *fpv1->sha256sum ==
- "0df6d45a3514c6101609bdcfefe7659b5754e505c6cf6b4107141d8217bb981d");
-
- // libfoo-1.2.2
- //
- shared_ptr<package> fpv2 (
- db.load<package> (
- package_id (package_name ("libfoo"), version ("1.2.2"))));
-
- assert (fpv2->summary == "The Foo library");
- assert (fpv2->tags == strings ({"c++", "foo"}));
- assert (!fpv2->description);
- assert (fpv2->url && *fpv2->url == "http://www.example.com/foo/");
- assert (!fpv2->package_url);
- assert (fpv2->email && *fpv2->email == "foo-users@example.com");
- assert (!fpv2->package_email);
-
- assert (fpv2->internal_repository.load () == sr);
- assert (fpv2->other_repositories.empty ());
- assert (fpv2->priority == priority::low);
- assert (fpv2->changes.empty ());
-
- assert (fpv2->license_alternatives.size () == 1);
- assert (fpv2->license_alternatives[0].size () == 1);
- assert (fpv2->license_alternatives[0][0] == "MIT");
-
- assert (fpv2->dependencies.size () == 2);
- assert (fpv2->dependencies[0].size () == 1);
- assert (fpv2->dependencies[1].size () == 1);
-
- auto dep = [&db] (
- const char* n, const optional<dependency_constraint>& c) -> dependency
+ case repository_type::pkg:
+ {
+ test_pkg_repos (loader_args, loadtab_dir, db);
+ break;
+ }
+ case repository_type::git:
{
- return {lazy_shared_ptr<package> (
- db, package_id (package_name (n), version ())), c};
- };
-
- assert (fpv2->dependencies[0][0] ==
- dep (
- "libbar",
- optional<dependency_constraint> (
- dependency_constraint (
- nullopt, true, version ("2.4.0"), false))));
-
- assert (fpv2->dependencies[1][0] ==
- dep (
- "libexp",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("+2-1.2"), false, version ("+2-1.2"), false))));
-
- assert (check_location (fpv2));
-
- assert (fpv2->sha256sum && *fpv2->sha256sum ==
- "088068ea3d69542a153f829cf836013374763148fba0a43d8047974f58b5efd7");
-
- // libfoo-1.2.2-alpha.1
- //
- shared_ptr<package> fpv2a (
- db.load<package> (
- package_id (package_name ("libfoo"), version ("1.2.2-alpha.1"))));
-
- assert (fpv2a->summary == "The Foo library");
- assert (fpv2a->tags == strings ({"c++", "foo"}));
- assert (!fpv2a->description);
- assert (fpv2a->url && *fpv2a->url == "http://www.example.com/foo/");
- assert (!fpv2a->package_url);
- assert (fpv2a->email && *fpv2a->email == "foo-users@example.com");
- assert (!fpv2a->package_email);
-
- assert (fpv2a->internal_repository.load () == sr);
- assert (fpv2a->other_repositories.empty ());
- assert (fpv2a->priority == priority::low);
- assert (fpv2a->changes.empty ());
-
- assert (fpv2a->license_alternatives.size () == 1);
- assert (fpv2a->license_alternatives[0].size () == 1);
- assert (fpv2a->license_alternatives[0][0] == "MIT");
-
- assert (fpv2a->dependencies.size () == 3);
- assert (fpv2a->dependencies[0].size () == 2);
- assert (fpv2a->dependencies[1].size () == 1);
- assert (fpv2a->dependencies[2].size () == 2);
-
- assert (fpv2a->dependencies[0][0] ==
- dep (
- "libmisc",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("0.1"), false, version ("2.0.0-"), true))));
-
- assert (fpv2a->dependencies[0][1] ==
- dep (
- "libmisc",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("2.0"), false, version ("5.0"), false))));
-
- assert (fpv2a->dependencies[1][0] ==
- dep (
- "libgenx",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("0.2"), true, version ("3.0"), true))));
-
- assert (fpv2a->dependencies[2][0] ==
- dep (
- "libexpat",
- optional<dependency_constraint> (
- dependency_constraint (
- nullopt, true, version ("5.2"), true))));
-
- assert (fpv2a->dependencies[2][1] ==
- dep (
- "libexpat",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("1"), true, version ("5.1"), false))));
-
- assert (fpv2a->requirements.empty ());
-
- assert (check_location (fpv2a));
-
- assert (fpv2a->sha256sum && *fpv2a->sha256sum ==
- "34fc224087bfd9212de4acfbbf5275513ebc57678b5f029546918a62c57d15cb");
-
- // libfoo-1.2.3-4
- //
- shared_ptr<package> fpv3 (
- db.load<package> (
- package_id (package_name ("libfoo"), version ("1.2.3+4"))));
-
- assert (fpv3->summary == "The Foo library");
- assert (fpv3->tags == strings ({"c++", "foo"}));
- assert (!fpv3->description);
- assert (fpv3->url && *fpv3->url == "http://www.example.com/foo/");
- assert (!fpv3->package_url);
- assert (fpv3->email && *fpv3->email == "foo-users@example.com");
- assert (!fpv3->package_email);
-
- assert (fpv3->internal_repository.load () == sr);
- assert (fpv3->other_repositories.empty ());
- assert (fpv3->priority == priority::low);
-
- assert (fpv3->changes.empty ());
-
- assert (fpv3->license_alternatives.size () == 1);
- assert (fpv3->license_alternatives[0].size () == 1);
- assert (fpv3->license_alternatives[0][0] == "MIT");
-
- assert (fpv3->dependencies.size () == 1);
- assert (fpv3->dependencies[0].size () == 1);
- assert (fpv3->dependencies[0][0] ==
- dep (
- "libmisc",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("2.0.0"), false, nullopt, true))));
-
- assert (check_location (fpv3));
-
- assert (fpv3->sha256sum && *fpv3->sha256sum ==
- "204fb25edf2404e9e88e1bef8b2a444281a807d9087093147a2cc80a1ffba79a");
-
- // libfoo-1.2.4
- //
- shared_ptr<package> fpv4 (
- db.load<package> (
- package_id (package_name ("libfoo"), version ("1.2.4"))));
-
- assert (fpv4->summary == "The Foo Library");
- assert (fpv4->tags == strings ({"c++", "foo"}));
- assert (*fpv4->description == "Very good foo library.");
- assert (fpv4->url && *fpv4->url == "http://www.example.com/foo/");
- assert (!fpv4->package_url);
- assert (fpv4->email && *fpv4->email == "foo-users@example.com");
- assert (!fpv4->package_email);
-
- assert (fpv4->internal_repository.load () == sr);
- assert (fpv4->other_repositories.empty ());
- assert (fpv4->priority == priority::low);
- assert (fpv4->changes == "some changes 1\n\nsome changes 2");
-
- assert (fpv4->license_alternatives.size () == 1);
- assert (fpv4->license_alternatives[0].comment ==
- "Permissive free software license.");
- assert (fpv4->license_alternatives[0].size () == 1);
- assert (fpv4->license_alternatives[0][0] == "MIT");
-
- assert (fpv4->dependencies.size () == 1);
- assert (fpv4->dependencies[0].size () == 1);
- assert (fpv4->dependencies[0][0] ==
- dep (
- "libmisc",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("2.0.0"), false, nullopt, true))));
-
- assert (check_location (fpv4));
-
- assert (fpv4->sha256sum && *fpv4->sha256sum ==
- "aa1606323bfc59b70de642629dc5d8318cc5348e3646f90ed89406d975db1e1d");
-
- // Verify 'math' repository.
- //
- assert (mr->location.canonical_name () == "pkg:dev.cppget.org/math");
- assert (mr->location.string () ==
- "http://dev.cppget.org/1/math");
- assert (mr->display_name == "math");
- assert (mr->priority == 2);
- assert (!mr->url);
- assert (mr->email && *mr->email == "repoman@dev.cppget.org");
- assert (mr->summary && *mr->summary == "Math C++ package repository");
- assert (mr->description && *mr->description ==
- "This is the awesome C++ package repository full of remarkable "
- "algorithms and\nAPIs.");
-
- dir_path mrp (cp.directory () / dir_path ("1/math"));
- assert (mr->cache_location.path () == mrp.normalize ());
-
- assert (mr->packages_timestamp ==
- file_mtime (mr->cache_location.path () / packages));
-
- assert (mr->repositories_timestamp ==
- file_mtime (mr->cache_location.path () / repositories));
-
- assert (mr->internal);
-
- assert (mr->complements.empty ());
- assert (mr->prerequisites.size () == 1);
- assert (mr->prerequisites[0].load () == cr);
-
- // Verify libstudxml package version.
- //
- shared_ptr<package> xpv (
- db.load<package> (
- package_id (package_name ("libstudxml"), version ("1.0.0+1"))));
-
- assert (xpv->summary == "Modern C++ XML API");
- assert (xpv->tags == strings ({"c++", "xml", "parser", "serializer",
- "pull", "streaming", "modern"}));
- assert (!xpv->description);
- assert (xpv->url &&
- *xpv->url == "http://www.codesynthesis.com/projects/libstudxml/");
- assert (!xpv->package_url);
- assert (xpv->email && *xpv->email ==
- email ("studxml-users@codesynthesis.com",
- "Public mailing list, posts by non-members "
- "are allowed but moderated."));
- assert (xpv->package_email &&
- *xpv->package_email == email ("boris@codesynthesis.com",
- "Direct email to the author."));
-
- assert (xpv->internal_repository.load () == mr);
- assert (xpv->other_repositories.empty ());
- assert (xpv->priority == priority::low);
- assert (xpv->changes.empty ());
-
- assert (xpv->license_alternatives.size () == 1);
- assert (xpv->license_alternatives[0].size () == 1);
- assert (xpv->license_alternatives[0][0] == "MIT");
-
- assert (xpv->dependencies.size () == 2);
- assert (xpv->dependencies[0].size () == 1);
- assert (xpv->dependencies[0][0] ==
- dep (
- "libexpat",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("2.0.0"), false, nullopt, true))));
-
- assert (xpv->dependencies[1].size () == 1);
- assert (xpv->dependencies[1][0] == dep ("libgenx", nullopt));
-
- assert (xpv->requirements.empty ());
-
- assert (check_location (xpv));
-
- assert (xpv->sha256sum && *xpv->sha256sum ==
- "cfa4b1f89f8e903d48eff1e1d14628c32aa4d126d09b0b056d2cd80f8dc78580");
-
- // Verify libfoo package versions.
- //
- // libfoo-1.2.4-1
- //
- shared_ptr<package> fpv5 (
- db.load<package> (
- package_id (package_name ("libfoo"), version ("1.2.4+1"))));
-
- assert (fpv5->summary == "The Foo Math Library");
- assert (fpv5->tags == strings ({"c++", "foo", "math"}));
- assert (*fpv5->description ==
- "A modern C++ library with easy to use linear algebra and lot "
- "of optimization\ntools.\n\nThere are over 100 functions in "
- "total with an extensive test suite. The API is\nsimilar to "
- "MATLAB.\n\nUseful for conversion of research code into "
- "production environments.");
-
- assert (fpv5->url && *fpv5->url == "http://www.example.com/foo/");
-
- assert (fpv5->doc_url && *fpv5->doc_url ==
- "http://www.example.org/projects/libfoo/man.xhtml" &&
- fpv5->doc_url->comment == "Documentation page.");
-
- assert (fpv5->src_url && *fpv5->src_url ==
- "http://scm.example.com/?p=odb/libodb.git;a=tree" &&
- fpv5->src_url->comment == "Source tree url.");
-
- assert (fpv5->package_url &&
- *fpv5->package_url == "http://www.example.com/foo/pack");
- assert (fpv5->email && *fpv5->email == "foo-users@example.com");
- assert (fpv5->package_email &&
- *fpv5->package_email == "pack@example.com");
-
- assert (fpv5->internal_repository.load () == mr);
- assert (fpv5->other_repositories.size () == 1);
- assert (fpv5->other_repositories[0].load () == cr);
-
- assert (fpv5->priority == priority::high);
- assert (fpv5->priority.comment ==
- "Critical bug fixes, performance improvement.");
-
- const char ch[] = R"DLM(1.2.4+1
+ test_git_repos (loader_args, loadtab_dir, db);
+ break;
+ }
+ default:
+ {
+ print_usage ();
+ return 1;
+ }
+ }
+ }
+ // Fully qualified to avoid ambiguity with odb exception.
+ //
+ catch (const std::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
+static inline dependency
+dep (const char* n, optional<dependency_constraint> c)
+{
+ return dependency {package_name (n), move (c), nullptr};
+}
+
+static void
+test_git_repos (const cstrings& loader_args,
+ const dir_path& loadtab_dir,
+ odb::pgsql::database& db)
+{
+ path loadtab (loadtab_dir / "git-loadtab");
+
+ cstrings args (loader_args);
+ args.push_back ("--force");
+ args.push_back ("--shallow");
+ args.push_back (loadtab.string ().c_str ());
+ args.push_back (nullptr);
+
+ {
+ // Run the loader.
+ //
+ assert (process (args.data ()).wait ());
+
+ // Check persistent objects.
+ //
+ session s;
+ transaction t (db.begin ());
+
+ assert (db.query<repository> ().size () == 1);
+ assert (db.query<package> ().size () == 1);
+
+ // Verify 'foo' repository.
+ //
+ shared_ptr<repository> r (
+ db.load<repository> ("git:example.com/foo#master"));
+
+ assert (r->location.string () == "https://git.example.com/foo.git#master");
+ assert (r->summary && *r->summary == "foo project repository");
+
+ // Verify libfoo package version.
+ //
+ // libfoo-1.0
+ //
+ shared_ptr<package> p (
+ db.load<package> (
+ package_id (package_name ("libfoo"), version ("1.0"))));
+
+ assert (p->fragment &&
+ *p->fragment == "0f50af28d1cfb0c22f5b88e2bf674ab732e058d9");
+
+ assert (p->dependencies.size () == 1);
+ assert (p->dependencies[0].size () == 1);
+
+ assert (p->dependencies[0][0] ==
+ dep ("libmisc",
+ dependency_constraint (
+ version ("1.0"), false, version ("1.0"), false)));
+
+ t.commit ();
+ }
+}
+
+static void
+test_pkg_repos (const cstrings& loader_args,
+ const dir_path& loadtab_dir,
+ odb::pgsql::database& db)
+{
+ path p (loadtab_dir / dir_path ("1/stable") / packages);
+ timestamp srt (file_mtime (p));
+
+ path loadtab (loadtab_dir / "loadtab");
+
+ // Load the repositories and check persistent objects validity.
+ //
+ {
+ cstrings args (loader_args);
+ args.push_back ("--force");
+ args.push_back (loadtab.string ().c_str ());
+ args.push_back (nullptr);
+
+ // Run the loader.
+ //
+ assert (process (args.data ()).wait ());
+
+ // Check persistent objects.
+ //
+ session s;
+ transaction t (db.begin ());
+
+ assert (db.query<repository> ().size () == 7);
+ assert (db.query<package> ().size () == 18);
+
+ shared_ptr<repository> sr (
+ db.load<repository> ("pkg:dev.cppget.org/stable"));
+
+ shared_ptr<repository> mr (
+ db.load<repository> ("pkg:dev.cppget.org/math"));
+
+ shared_ptr<repository> cr (
+ db.load<repository> ("pkg:dev.cppget.org/misc"));
+
+ shared_ptr<repository> tr (
+ db.load<repository> ("pkg:dev.cppget.org/testing"));
+
+ shared_ptr<repository> gr (
+ db.load<repository> ("pkg:dev.cppget.org/staging"));
+
+ // Verify 'stable' repository.
+ //
+ assert (sr->location.canonical_name () == "pkg:dev.cppget.org/stable");
+ assert (sr->location.string () ==
+ "http://dev.cppget.org/1/stable");
+ assert (sr->display_name == "stable");
+ assert (sr->priority == 1);
+ assert (!sr->interface_url);
+ assert (sr->email && *sr->email == "repoman@dev.cppget.org" &&
+ sr->email->comment == "public mailing list");
+ assert (sr->summary &&
+ *sr->summary == "General C++ package stable repository");
+ assert (sr->description && *sr->description ==
+ "This is the awesome C++ package repository full of exciting "
+ "stuff.");
+
+ dir_path srp (loadtab.directory () / dir_path ("1/stable"));
+ assert (sr->cache_location.path () == srp.normalize ());
+
+ assert (sr->packages_timestamp == srt);
+ assert (sr->repositories_timestamp ==
+ file_mtime (sr->cache_location.path () / repositories));
+
+ assert (sr->internal);
+ assert (sr->complements.empty ());
+ assert (sr->prerequisites.size () == 2);
+ assert (sr->prerequisites[0].load () == cr);
+ assert (sr->prerequisites[1].load () == mr);
+
+ // Verify libfoo package versions.
+ //
+ // libfoo-+0-X.Y
+ //
+ shared_ptr<package> fpvxy (
+ db.load<package> (
+ package_id (package_name ("libfoo"), version ("+0-X.Y"))));
+
+ assert (fpvxy->project == package_name ("libfoo"));
+ assert (fpvxy->summary == "The Foo Library");
+ assert (fpvxy->tags.empty ());
+ assert (!fpvxy->description);
+ assert (!fpvxy->url);
+ assert (!fpvxy->package_url);
+ assert (!fpvxy->email);
+ assert (!fpvxy->package_email);
+
+ assert (fpvxy->internal_repository.load () == mr);
+ assert (fpvxy->other_repositories.empty ());
+
+ assert (fpvxy->priority == priority::low);
+ assert (fpvxy->changes.empty ());
+
+ assert (fpvxy->license_alternatives.size () == 1);
+ assert (fpvxy->license_alternatives[0].size () == 1);
+ assert (fpvxy->license_alternatives[0][0] == "MIT");
+
+ assert (fpvxy->dependencies.empty ());
+ assert (fpvxy->requirements.empty ());
+
+ assert (check_location (fpvxy));
+
+ assert (fpvxy->sha256sum && *fpvxy->sha256sum ==
+ "c994fd49f051ab7fb25f3a4e68ca878e484c5d3c2cb132b37d41224b0621b618");
+
+ // libfoo-1.0
+ //
+ shared_ptr<package> fpv1 (
+ db.load<package> (
+ package_id (package_name ("libfoo"), version ("1.0"))));
+
+ assert (fpv1->summary == "The Foo Library");
+ assert (fpv1->tags.empty ());
+ assert (!fpv1->description);
+ assert (!fpv1->url);
+ assert (!fpv1->package_url);
+ assert (!fpv1->email);
+ assert (!fpv1->package_email);
+
+ assert (fpv1->internal_repository.load () == sr);
+ assert (fpv1->other_repositories.size () == 2);
+ assert (fpv1->other_repositories[0].load () == mr);
+ assert (fpv1->other_repositories[1].load () == cr);
+
+ assert (fpv1->priority == priority::low);
+ assert (fpv1->changes.empty ());
+
+ assert (fpv1->license_alternatives.size () == 1);
+ assert (fpv1->license_alternatives[0].size () == 1);
+ assert (fpv1->license_alternatives[0][0] == "MIT");
+
+ assert (fpv1->dependencies.empty ());
+ assert (fpv1->requirements.empty ());
+
+ assert (check_location (fpv1));
+
+ assert (fpv1->sha256sum && *fpv1->sha256sum ==
+ "0df6d45a3514c6101609bdcfefe7659b5754e505c6cf6b4107141d8217bb981d");
+
+ // libfoo-1.2.2
+ //
+ shared_ptr<package> fpv2 (
+ db.load<package> (
+ package_id (package_name ("libfoo"), version ("1.2.2"))));
+
+ assert (fpv2->summary == "The Foo library");
+ assert (fpv2->tags == strings ({"c++", "foo"}));
+ assert (!fpv2->description);
+ assert (fpv2->url && *fpv2->url == "http://www.example.com/foo/");
+ assert (!fpv2->package_url);
+ assert (fpv2->email && *fpv2->email == "foo-users@example.com");
+ assert (!fpv2->package_email);
+
+ assert (fpv2->internal_repository.load () == sr);
+ assert (fpv2->other_repositories.empty ());
+ assert (fpv2->priority == priority::low);
+ assert (fpv2->changes.empty ());
+
+ assert (fpv2->license_alternatives.size () == 1);
+ assert (fpv2->license_alternatives[0].size () == 1);
+ assert (fpv2->license_alternatives[0][0] == "MIT");
+
+ assert (fpv2->dependencies.size () == 2);
+ assert (fpv2->dependencies[0].size () == 1);
+ assert (fpv2->dependencies[1].size () == 1);
+
+ assert (fpv2->dependencies[0][0] ==
+ dep ("libbar",
+ dependency_constraint (
+ nullopt, true, version ("2.4.0"), false)));
+
+ assert (fpv2->dependencies[1][0] ==
+ dep ("libexp",
+ dependency_constraint (
+ version ("+2-1.2"), false, version ("+2-1.2"), false)));
+
+ assert (check_location (fpv2));
+
+ assert (fpv2->sha256sum && *fpv2->sha256sum ==
+ "088068ea3d69542a153f829cf836013374763148fba0a43d8047974f58b5efd7");
+
+ // libfoo-1.2.2-alpha.1
+ //
+ shared_ptr<package> fpv2a (
+ db.load<package> (
+ package_id (package_name ("libfoo"), version ("1.2.2-alpha.1"))));
+
+ assert (fpv2a->summary == "The Foo library");
+ assert (fpv2a->tags == strings ({"c++", "foo"}));
+ assert (!fpv2a->description);
+ assert (fpv2a->url && *fpv2a->url == "http://www.example.com/foo/");
+ assert (!fpv2a->package_url);
+ assert (fpv2a->email && *fpv2a->email == "foo-users@example.com");
+ assert (!fpv2a->package_email);
+
+ assert (fpv2a->internal_repository.load () == sr);
+ assert (fpv2a->other_repositories.empty ());
+ assert (fpv2a->priority == priority::low);
+ assert (fpv2a->changes.empty ());
+
+ assert (fpv2a->license_alternatives.size () == 1);
+ assert (fpv2a->license_alternatives[0].size () == 1);
+ assert (fpv2a->license_alternatives[0][0] == "MIT");
+
+ assert (fpv2a->dependencies.size () == 3);
+ assert (fpv2a->dependencies[0].size () == 2);
+ assert (fpv2a->dependencies[1].size () == 1);
+ assert (fpv2a->dependencies[2].size () == 2);
+
+ assert (fpv2a->dependencies[0][0] ==
+ dep ("libmisc",
+ dependency_constraint (
+ version ("0.1"), false, version ("2.0.0-"), true)));
+
+ assert (fpv2a->dependencies[0][1] ==
+ dep ("libmisc",
+ dependency_constraint (
+ version ("2.0"), false, version ("5.0"), false)));
+
+ assert (fpv2a->dependencies[1][0] ==
+ dep ("libgenx",
+ dependency_constraint (
+ version ("0.2"), true, version ("3.0"), true)));
+
+ assert (fpv2a->dependencies[2][0] ==
+ dep ("libexpat",
+ dependency_constraint (
+ nullopt, true, version ("5.2"), true)));
+
+ assert (fpv2a->dependencies[2][1] ==
+ dep ("libexpat",
+ dependency_constraint (
+ version ("1"), true, version ("5.1"), false)));
+
+ assert (fpv2a->requirements.empty ());
+
+ assert (check_location (fpv2a));
+
+ assert (fpv2a->sha256sum && *fpv2a->sha256sum ==
+ "34fc224087bfd9212de4acfbbf5275513ebc57678b5f029546918a62c57d15cb");
+
+ // libfoo-1.2.3-4
+ //
+ shared_ptr<package> fpv3 (
+ db.load<package> (
+ package_id (package_name ("libfoo"), version ("1.2.3+4"))));
+
+ assert (fpv3->summary == "The Foo library");
+ assert (fpv3->tags == strings ({"c++", "foo"}));
+ assert (!fpv3->description);
+ assert (fpv3->url && *fpv3->url == "http://www.example.com/foo/");
+ assert (!fpv3->package_url);
+ assert (fpv3->email && *fpv3->email == "foo-users@example.com");
+ assert (!fpv3->package_email);
+
+ assert (fpv3->internal_repository.load () == sr);
+ assert (fpv3->other_repositories.empty ());
+ assert (fpv3->priority == priority::low);
+
+ assert (fpv3->changes.empty ());
+
+ assert (fpv3->license_alternatives.size () == 1);
+ assert (fpv3->license_alternatives[0].size () == 1);
+ assert (fpv3->license_alternatives[0][0] == "MIT");
+
+ assert (fpv3->dependencies.size () == 1);
+ assert (fpv3->dependencies[0].size () == 1);
+ assert (fpv3->dependencies[0][0] ==
+ dep ("libmisc",
+ dependency_constraint (
+ version ("2.0.0"), false, nullopt, true)));
+
+ assert (check_location (fpv3));
+
+ assert (fpv3->sha256sum && *fpv3->sha256sum ==
+ "204fb25edf2404e9e88e1bef8b2a444281a807d9087093147a2cc80a1ffba79a");
+
+ // libfoo-1.2.4
+ //
+ shared_ptr<package> fpv4 (
+ db.load<package> (
+ package_id (package_name ("libfoo"), version ("1.2.4"))));
+
+ assert (fpv4->summary == "The Foo Library");
+ assert (fpv4->tags == strings ({"c++", "foo"}));
+ assert (*fpv4->description == "Very good foo library.");
+ assert (fpv4->url && *fpv4->url == "http://www.example.com/foo/");
+ assert (!fpv4->package_url);
+ assert (fpv4->email && *fpv4->email == "foo-users@example.com");
+ assert (!fpv4->package_email);
+
+ assert (fpv4->internal_repository.load () == sr);
+ assert (fpv4->other_repositories.empty ());
+ assert (fpv4->priority == priority::low);
+ assert (fpv4->changes == "some changes 1\n\nsome changes 2");
+
+ assert (fpv4->license_alternatives.size () == 1);
+ assert (fpv4->license_alternatives[0].comment ==
+ "Permissive free software license.");
+ assert (fpv4->license_alternatives[0].size () == 1);
+ assert (fpv4->license_alternatives[0][0] == "MIT");
+
+ assert (fpv4->dependencies.size () == 1);
+ assert (fpv4->dependencies[0].size () == 1);
+ assert (fpv4->dependencies[0][0] ==
+ dep ("libmisc",
+ dependency_constraint (
+ version ("2.0.0"), false, nullopt, true)));
+
+ assert (check_location (fpv4));
+
+ assert (fpv4->sha256sum && *fpv4->sha256sum ==
+ "aa1606323bfc59b70de642629dc5d8318cc5348e3646f90ed89406d975db1e1d");
+
+ // Verify 'math' repository.
+ //
+ assert (mr->location.canonical_name () == "pkg:dev.cppget.org/math");
+ assert (mr->location.string () ==
+ "http://dev.cppget.org/1/math");
+ assert (mr->display_name == "math");
+ assert (mr->priority == 2);
+ assert (!mr->interface_url);
+ assert (mr->email && *mr->email == "repoman@dev.cppget.org");
+ assert (mr->summary && *mr->summary == "Math C++ package repository");
+ assert (mr->description && *mr->description ==
+ "This is the awesome C++ package repository full of remarkable "
+ "algorithms and\nAPIs.");
+
+ dir_path mrp (loadtab.directory () / dir_path ("1/math"));
+ assert (mr->cache_location.path () == mrp.normalize ());
+
+ assert (mr->packages_timestamp ==
+ file_mtime (mr->cache_location.path () / packages));
+
+ assert (mr->repositories_timestamp ==
+ file_mtime (mr->cache_location.path () / repositories));
+
+ assert (mr->internal);
+
+ assert (mr->complements.empty ());
+ assert (mr->prerequisites.size () == 1);
+ assert (mr->prerequisites[0].load () == cr);
+
+ // Verify libstudxml package version.
+ //
+ shared_ptr<package> xpv (
+ db.load<package> (
+ package_id (package_name ("libstudxml"), version ("1.0.0+1"))));
+
+ assert (xpv->summary == "Modern C++ XML API");
+ assert (xpv->tags == strings ({"c++", "xml", "parser", "serializer",
+ "pull", "streaming", "modern"}));
+ assert (!xpv->description);
+ assert (xpv->url &&
+ *xpv->url == "http://www.codesynthesis.com/projects/libstudxml/");
+ assert (!xpv->package_url);
+ assert (xpv->email && *xpv->email ==
+ email ("studxml-users@codesynthesis.com",
+ "Public mailing list, posts by non-members "
+ "are allowed but moderated."));
+ assert (xpv->package_email &&
+ *xpv->package_email == email ("boris@codesynthesis.com",
+ "Direct email to the author."));
+
+ assert (xpv->internal_repository.load () == mr);
+ assert (xpv->other_repositories.empty ());
+ assert (xpv->priority == priority::low);
+ assert (xpv->changes.empty ());
+
+ assert (xpv->license_alternatives.size () == 1);
+ assert (xpv->license_alternatives[0].size () == 1);
+ assert (xpv->license_alternatives[0][0] == "MIT");
+
+ assert (xpv->dependencies.size () == 2);
+ assert (xpv->dependencies[0].size () == 1);
+ assert (xpv->dependencies[0][0] ==
+ dep ("libexpat",
+ dependency_constraint (
+ version ("2.0.0"), false, nullopt, true)));
+
+ assert (xpv->dependencies[1].size () == 1);
+ assert (xpv->dependencies[1][0] == dep ("libgenx", nullopt));
+
+ assert (xpv->requirements.empty ());
+
+ assert (check_location (xpv));
+
+ assert (xpv->sha256sum && *xpv->sha256sum ==
+ "cfa4b1f89f8e903d48eff1e1d14628c32aa4d126d09b0b056d2cd80f8dc78580");
+
+ // Verify libfoo package versions.
+ //
+ // libfoo-1.2.4-1
+ //
+ shared_ptr<package> fpv5 (
+ db.load<package> (
+ package_id (package_name ("libfoo"), version ("1.2.4+1"))));
+
+ assert (fpv5->summary == "The Foo Math Library");
+ assert (fpv5->tags == strings ({"c++", "foo", "math"}));
+ assert (*fpv5->description ==
+ "A modern C++ library with easy to use linear algebra and lot "
+ "of optimization\ntools.\n\nThere are over 100 functions in "
+ "total with an extensive test suite. The API is\nsimilar to "
+ "MATLAB.\n\nUseful for conversion of research code into "
+ "production environments.");
+
+ assert (fpv5->url && *fpv5->url == "http://www.example.com/foo/");
+
+ assert (fpv5->doc_url && *fpv5->doc_url ==
+ "http://www.example.org/projects/libfoo/man.xhtml" &&
+ fpv5->doc_url->comment == "Documentation page.");
+
+ assert (fpv5->src_url && *fpv5->src_url ==
+ "http://scm.example.com/?p=odb/libodb.git;a=tree" &&
+ fpv5->src_url->comment == "Source tree url.");
+
+ assert (fpv5->package_url &&
+ *fpv5->package_url == "http://www.example.com/foo/pack");
+ assert (fpv5->email && *fpv5->email == "foo-users@example.com");
+ assert (fpv5->package_email &&
+ *fpv5->package_email == "pack@example.com");
+
+ assert (fpv5->internal_repository.load () == mr);
+ assert (fpv5->other_repositories.size () == 1);
+ assert (fpv5->other_repositories[0].load () == cr);
+
+ assert (fpv5->priority == priority::high);
+ assert (fpv5->priority.comment ==
+ "Critical bug fixes, performance improvement.");
+
+ const char ch[] = R"DLM(1.2.4+1
* applied patch for critical bug-219
* regenerated documentation
1.2.4
* test suite extended significantly)DLM";
- assert (fpv5->changes == ch);
-
- assert (fpv5->license_alternatives.size () == 2);
- assert (fpv5->license_alternatives[0].comment ==
- "If using with GNU TLS.");
- assert (fpv5->license_alternatives[0].size () == 2);
- assert (fpv5->license_alternatives[0][0] == "LGPLv2");
- assert (fpv5->license_alternatives[0][1] == "MIT");
- assert (fpv5->license_alternatives[1].comment ==
- "If using with OpenSSL.");
- assert (fpv5->license_alternatives[1].size () == 1);
- assert (fpv5->license_alternatives[1][0] == "BSD");
-
- assert (fpv5->dependencies.size () == 3);
- assert (fpv5->dependencies[0].size () == 2);
- assert (fpv5->dependencies[0].comment ==
- "Crashes with 1.1.0-2.3.0.");
-
- assert (fpv5->dependencies[0][0] ==
- dep (
- "libmisc",
- optional<dependency_constraint> (
- dependency_constraint (
- nullopt, true, version ("1.1"), true))));
-
- assert (fpv5->dependencies[0][1] ==
- dep (
- "libmisc",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("2.3.0"), true, nullopt, true))));
-
- assert (fpv5->dependencies[1].size () == 1);
- assert (fpv5->dependencies[1].comment.empty ());
-
- assert (fpv5->dependencies[1][0] ==
- dep ("libexp",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("1.0"), false, nullopt, true))));
-
- assert (fpv5->dependencies[2].size () == 2);
- assert (fpv5->dependencies[2].comment == "The newer the better.");
-
- assert (fpv5->dependencies[2][0] == dep ("libstudxml", nullopt));
- assert (fpv5->dependencies[2][1] == dep ("libexpat", nullopt));
-
- requirements& fpvr5 (fpv5->requirements);
- assert (fpvr5.size () == 4);
-
- assert (fpvr5[0] == strings ({"linux", "windows", "macosx"}));
- assert (!fpvr5[0].conditional);
- assert (fpvr5[0].comment == "Symbian support is coming.");
-
- assert (fpvr5[1] == strings ({"c++11"}));
- assert (!fpvr5[1].conditional);
- assert (fpvr5[1].comment.empty ());
-
- assert (fpvr5[2].empty ());
- assert (fpvr5[2].conditional);
- assert (fpvr5[2].comment ==
- "libc++ standard library if using Clang on Mac OS X.");
-
- assert (fpvr5[3] == strings ({"vc++ >= 12.0"}));
- assert (fpvr5[3].conditional);
- assert (fpvr5[3].comment == "Only if using VC++ on Windows.");
-
- assert (check_location (fpv5));
-
- assert (fpv5->sha256sum && *fpv5->sha256sum ==
- "c5e593d8efdc34a258f8c0b8cc352dc7193ea4a1d666bcf8d48708c7dd82d0d6");
-
- // Verify libexp package version.
- //
- // libexp-+2-1.2
- //
- shared_ptr<package> epv (
- db.load<package> (
- package_id (package_name ("libexp"), version ("+2-1.2+1"))));
-
- assert (epv->project == "mathLab");
- assert (epv->summary == "The exponent");
- assert (epv->tags == strings ({"mathlab", "c++", "exponent"}));
- assert (epv->description && *epv->description ==
- "The exponent math function.");
- assert (epv->url && *epv->url == "http://www.exp.com");
- assert (!epv->package_url);
- assert (epv->email && *epv->email == email ("users@exp.com"));
- assert (!epv->package_email);
- assert (epv->build_email && *epv->build_email == "builds@exp.com");
-
- assert (epv->internal_repository.load () == mr);
- assert (epv->other_repositories.empty ());
- assert (epv->priority == priority (priority::low));
- assert (epv->changes.empty ());
-
- assert (epv->license_alternatives.size () == 1);
- assert (epv->license_alternatives[0].size () == 1);
- assert (epv->license_alternatives[0][0] == "MIT");
-
- assert (epv->dependencies.size () == 2);
- assert (epv->dependencies[0].size () == 1);
- assert (epv->dependencies[0][0] == dep ("libmisc", nullopt));
-
- assert (epv->dependencies[1].size () == 1);
- assert (epv->dependencies[1][0] ==
- dep ("libpq",
- optional<dependency_constraint> (
- dependency_constraint (
- version ("9.0.0"), false, nullopt, true))));
-
- assert (epv->requirements.empty ());
-
- db.load (*epv, epv->build_section);
-
- assert (
- epv->build_constraints ==
- build_constraints ({
+ assert (fpv5->changes == ch);
+
+ assert (fpv5->license_alternatives.size () == 2);
+ assert (fpv5->license_alternatives[0].comment ==
+ "If using with GNU TLS.");
+ assert (fpv5->license_alternatives[0].size () == 2);
+ assert (fpv5->license_alternatives[0][0] == "LGPLv2");
+ assert (fpv5->license_alternatives[0][1] == "MIT");
+ assert (fpv5->license_alternatives[1].comment ==
+ "If using with OpenSSL.");
+ assert (fpv5->license_alternatives[1].size () == 1);
+ assert (fpv5->license_alternatives[1][0] == "BSD");
+
+ assert (fpv5->dependencies.size () == 3);
+ assert (fpv5->dependencies[0].size () == 2);
+ assert (fpv5->dependencies[0].comment ==
+ "Crashes with 1.1.0-2.3.0.");
+
+ assert (fpv5->dependencies[0][0] ==
+ dep ("libmisc",
+ dependency_constraint (
+ nullopt, true, version ("1.1"), true)));
+
+ assert (fpv5->dependencies[0][1] ==
+ dep ("libmisc",
+ dependency_constraint (
+ version ("2.3.0"), true, nullopt, true)));
+
+ assert (fpv5->dependencies[1].size () == 1);
+ assert (fpv5->dependencies[1].comment.empty ());
+
+ assert (fpv5->dependencies[1][0] ==
+ dep ("libexp",
+ dependency_constraint (
+ version ("1.0"), false, nullopt, true)));
+
+ assert (fpv5->dependencies[2].size () == 2);
+ assert (fpv5->dependencies[2].comment == "The newer the better.");
+
+ assert (fpv5->dependencies[2][0] == dep ("libstudxml", nullopt));
+ assert (fpv5->dependencies[2][1] == dep ("libexpat", nullopt));
+
+ requirements& fpvr5 (fpv5->requirements);
+ assert (fpvr5.size () == 4);
+
+ assert (fpvr5[0] == strings ({"linux", "windows", "macosx"}));
+ assert (!fpvr5[0].conditional);
+ assert (fpvr5[0].comment == "Symbian support is coming.");
+
+ assert (fpvr5[1] == strings ({"c++11"}));
+ assert (!fpvr5[1].conditional);
+ assert (fpvr5[1].comment.empty ());
+
+ assert (fpvr5[2].empty ());
+ assert (fpvr5[2].conditional);
+ assert (fpvr5[2].comment ==
+ "libc++ standard library if using Clang on Mac OS X.");
+
+ assert (fpvr5[3] == strings ({"vc++ >= 12.0"}));
+ assert (fpvr5[3].conditional);
+ assert (fpvr5[3].comment == "Only if using VC++ on Windows.");
+
+ assert (check_location (fpv5));
+
+ assert (fpv5->sha256sum && *fpv5->sha256sum ==
+ "c5e593d8efdc34a258f8c0b8cc352dc7193ea4a1d666bcf8d48708c7dd82d0d6");
+
+ // Verify libexp package version.
+ //
+ // libexp-+2-1.2
+ //
+ shared_ptr<package> epv (
+ db.load<package> (
+ package_id (package_name ("libexp"), version ("+2-1.2+1"))));
+
+ assert (epv->project == "mathLab");
+ assert (epv->summary == "The exponent");
+ assert (epv->tags == strings ({"mathlab", "c++", "exponent"}));
+ assert (epv->description && *epv->description ==
+ "The exponent math function.");
+ assert (epv->url && *epv->url == "http://www.exp.com");
+ assert (!epv->package_url);
+ assert (epv->email && *epv->email == email ("users@exp.com"));
+ assert (!epv->package_email);
+ assert (epv->build_email && *epv->build_email == "builds@exp.com");
+
+ assert (epv->internal_repository.load () == mr);
+ assert (epv->other_repositories.empty ());
+ assert (epv->priority == priority (priority::low));
+ assert (epv->changes.empty ());
+
+ assert (epv->license_alternatives.size () == 1);
+ assert (epv->license_alternatives[0].size () == 1);
+ assert (epv->license_alternatives[0][0] == "MIT");
+
+ assert (epv->dependencies.size () == 2);
+ assert (epv->dependencies[0].size () == 1);
+ assert (epv->dependencies[0][0] == dep ("libmisc", nullopt));
+
+ assert (epv->dependencies[1].size () == 1);
+ assert (epv->dependencies[1][0] ==
+ dep ("libpq",
+ dependency_constraint (
+ version ("9.0.0"), false, nullopt, true)));
+
+ assert (epv->requirements.empty ());
+
+ db.load (*epv, epv->build_section);
+
+ assert (
+ epv->build_constraints ==
+ build_constraints ({
build_constraint (true, "*", nullopt, "Only supported on Linux."),
- build_constraint (false, "linux*", nullopt, "")}));
-
- assert (check_location (epv));
- assert (epv->sha256sum && *epv->sha256sum ==
- "bc68940a1b3b7e345cbceac35d308b4e04b304f49ff2087340949f2879709967");
-
- // Verify libpq package version.
- //
- // libpq-0
- //
- shared_ptr<package> qpv (
- db.load<package> (package_id (package_name ("libpq"), version ("0"))));
-
- assert (qpv->summary == "PostgreSQL C API client library");
-
- // Verify 'misc' repository.
- //
- assert (cr->location.canonical_name () == "pkg:dev.cppget.org/misc");
- assert (cr->location.string () ==
- "http://dev.cppget.org/1/misc");
- assert (cr->display_name.empty ());
- assert (cr->priority == 0);
- assert (cr->url && *cr->url == "http://misc.cppget.org/");
- assert (!cr->email);
- assert (!cr->summary);
- assert (!cr->description);
-
- dir_path crp (cp.directory () / dir_path ("1/misc"));
- assert (cr->cache_location.path () == crp.normalize ());
-
- assert (cr->packages_timestamp ==
- file_mtime (cr->cache_location.path () / packages));
-
- assert (cr->repositories_timestamp ==
- file_mtime (cr->cache_location.path () / repositories));
-
- assert (!cr->internal);
- assert (cr->prerequisites.empty ());
- assert (cr->complements.size () == 1);
- assert (cr->complements[0].load () == tr);
-
- // Verify libbar package version.
- //
- // libbar-2.4.0+3
- //
- shared_ptr<package> bpv (
- db.load<package> (
- package_id (package_name ("libbar"), version ("2.4.0+3"))));
-
- assert (check_external (*bpv));
- assert (bpv->other_repositories.size () == 1);
- assert (bpv->other_repositories[0].load () == cr);
- assert (check_location (bpv));
-
- // Verify libfoo package versions.
- //
- // libfoo-0.1
- //
- shared_ptr<package> fpv0 (
- db.load<package> (
- package_id (package_name ("libfoo"), version ("0.1"))));
-
- assert (check_external (*fpv0));
- assert (fpv0->other_repositories.size () == 1);
- assert (fpv0->other_repositories[0].load () == cr);
- assert (check_location (fpv0));
-
- // libfoo-1.2.4-2
- //
- shared_ptr<package> fpv6 (
- db.load<package> (
- package_id (package_name ("libfoo"), version ("1.2.4+2"))));
-
- assert (check_external (*fpv6));
- assert (fpv6->other_repositories.size () == 1);
- assert (fpv6->other_repositories[0].load () == cr);
- assert (check_location (fpv6));
-
- // Verify 'testing' repository.
- //
- assert (tr->location.canonical_name () == "pkg:dev.cppget.org/testing");
- assert (tr->location.string () ==
- "http://dev.cppget.org/1/testing");
- assert (tr->display_name.empty ());
- assert (tr->priority == 0);
- assert (tr->url && *tr->url == "http://test.cppget.org/hello/");
- assert (!tr->email);
- assert (!tr->summary);
- assert (!tr->description);
-
- dir_path trp (cp.directory () / dir_path ("1/testing"));
- assert (tr->cache_location.path () == trp.normalize ());
-
- assert (tr->packages_timestamp ==
- file_mtime (tr->cache_location.path () / packages));
-
- assert (tr->repositories_timestamp ==
- file_mtime (tr->cache_location.path () / repositories));
-
- assert (!tr->internal);
- assert (tr->prerequisites.empty ());
- assert (tr->complements.size () == 1);
- assert (tr->complements[0].load () == gr);
-
- // Verify libmisc package version.
- //
- // libmisc-2.4.0
- //
- shared_ptr<package> mpv0 (
- db.load<package> (
- package_id (package_name ("libmisc"), version ("2.4.0"))));
-
- assert (check_external (*mpv0));
- assert (mpv0->other_repositories.size () == 1);
- assert (mpv0->other_repositories[0].load () == tr);
- assert (check_location (mpv0));
-
- // libmisc-2.3.0+1
- //
- shared_ptr<package> mpv1 (
- db.load<package> (
- package_id (package_name ("libmisc"), version ("2.3.0+1"))));
-
- assert (check_external (*mpv1));
- assert (mpv1->other_repositories.size () == 1);
- assert (mpv1->other_repositories[0].load () == tr);
- assert (check_location (mpv1));
-
- // Verify 'staging' repository.
- //
- assert (gr->location.canonical_name () == "pkg:dev.cppget.org/staging");
- assert (gr->location.string () ==
- "http://dev.cppget.org/1/staging");
- assert (gr->display_name.empty ());
- assert (gr->priority == 0);
- assert (gr->url && *gr->url == "http://dev.cppget.org/");
- assert (!gr->email);
- assert (!gr->summary);
- assert (!gr->description);
-
- dir_path grp (cp.directory () / dir_path ("1/staging"));
- assert (gr->cache_location.path () == grp.normalize ());
-
- assert (gr->packages_timestamp ==
- file_mtime (gr->cache_location.path () / packages));
-
- assert (gr->repositories_timestamp ==
- file_mtime (gr->cache_location.path () / repositories));
-
- assert (!gr->internal);
- assert (gr->prerequisites.empty ());
- assert (gr->complements.empty ());
-
- // Verify libexpat package version.
- //
- // libexpat-5.1
- //
- shared_ptr<package> tpv (
- db.load<package> (
- package_id (package_name ("libexpat"), version ("5.1"))));
-
- assert (check_external (*tpv));
- assert (tpv->other_repositories.size () == 1);
- assert (tpv->other_repositories[0].load () == gr);
- assert (check_location (tpv));
-
- // Verify libgenx package version.
- //
- // libgenx-1.0
- //
- shared_ptr<package> gpv (
- db.load<package> (
- package_id (package_name ("libgenx"), version ("1.0"))));
-
- assert (check_external (*gpv));
- assert (gpv->other_repositories.size () == 1);
- assert (gpv->other_repositories[0].load () == gr);
- assert (check_location (gpv));
-
- // Verify libmisc package version.
- //
- // libmisc-1.0
- //
- shared_ptr<package> mpv2 (
- db.load<package> (
- package_id (package_name ("libmisc"), version ("1.0"))));
-
- assert (check_external (*mpv2));
- assert (mpv2->other_repositories.size () == 1);
- assert (mpv2->other_repositories[0].load () == gr);
- assert (check_location (mpv2));
-
- // Change package summary, update the object persistent state, rerun
- // loader and ensure the model were not rebuilt.
- //
- bpv->summary = "test";
- db.update (bpv);
-
- t.commit ();
- }
+ build_constraint (false, "linux*", nullopt, "")}));
+
+ assert (check_location (epv));
+ assert (epv->sha256sum && *epv->sha256sum ==
+ "bc68940a1b3b7e345cbceac35d308b4e04b304f49ff2087340949f2879709967");
+
+ // Verify libpq package version.
+ //
+ // libpq-0
+ //
+ shared_ptr<package> qpv (
+ db.load<package> (package_id (package_name ("libpq"), version ("0"))));
+
+ assert (qpv->summary == "PostgreSQL C API client library");
+
+ // Verify 'misc' repository.
+ //
+ assert (cr->location.canonical_name () == "pkg:dev.cppget.org/misc");
+ assert (cr->location.string () ==
+ "http://dev.cppget.org/1/misc");
+ assert (cr->display_name.empty ());
+ assert (cr->priority == 0);
+ assert (cr->interface_url &&
+ *cr->interface_url == "http://misc.cppget.org/");
+ assert (!cr->email);
+ assert (!cr->summary);
+ assert (!cr->description);
+
+ dir_path crp (loadtab.directory () / dir_path ("1/misc"));
+ assert (cr->cache_location.path () == crp.normalize ());
+
+ assert (cr->packages_timestamp ==
+ file_mtime (cr->cache_location.path () / packages));
+
+ assert (cr->repositories_timestamp ==
+ file_mtime (cr->cache_location.path () / repositories));
+
+ assert (!cr->internal);
+ assert (cr->prerequisites.empty ());
+ assert (cr->complements.size () == 1);
+ assert (cr->complements[0].load () == tr);
+
+ // Verify libbar package version.
+ //
+ // libbar-2.4.0+3
+ //
+ shared_ptr<package> bpv (
+ db.load<package> (
+ package_id (package_name ("libbar"), version ("2.4.0+3"))));
+
+ assert (check_external (*bpv));
+ assert (bpv->other_repositories.size () == 1);
+ assert (bpv->other_repositories[0].load () == cr);
+ assert (check_location (bpv));
+
+ // Verify libfoo package versions.
+ //
+ // libfoo-0.1
+ //
+ shared_ptr<package> fpv0 (
+ db.load<package> (
+ package_id (package_name ("libfoo"), version ("0.1"))));
+
+ assert (check_external (*fpv0));
+ assert (fpv0->other_repositories.size () == 1);
+ assert (fpv0->other_repositories[0].load () == cr);
+ assert (check_location (fpv0));
+
+ // libfoo-1.2.4-2
+ //
+ shared_ptr<package> fpv6 (
+ db.load<package> (
+ package_id (package_name ("libfoo"), version ("1.2.4+2"))));
+
+ assert (check_external (*fpv6));
+ assert (fpv6->other_repositories.size () == 1);
+ assert (fpv6->other_repositories[0].load () == cr);
+ assert (check_location (fpv6));
+
+ // Verify 'testing' repository.
+ //
+ assert (tr->location.canonical_name () == "pkg:dev.cppget.org/testing");
+ assert (tr->location.string () ==
+ "http://dev.cppget.org/1/testing");
+ assert (tr->display_name.empty ());
+ assert (tr->priority == 0);
+ assert (tr->interface_url &&
+ *tr->interface_url == "http://test.cppget.org/hello/");
+ assert (!tr->email);
+ assert (!tr->summary);
+ assert (!tr->description);
+
+ dir_path trp (loadtab.directory () / dir_path ("1/testing"));
+ assert (tr->cache_location.path () == trp.normalize ());
+
+ assert (tr->packages_timestamp ==
+ file_mtime (tr->cache_location.path () / packages));
+
+ assert (tr->repositories_timestamp ==
+ file_mtime (tr->cache_location.path () / repositories));
+
+ assert (!tr->internal);
+ assert (tr->prerequisites.empty ());
+ assert (tr->complements.size () == 1);
+ assert (tr->complements[0].load () == gr);
+
+ // Verify libmisc package version.
+ //
+ // libmisc-2.4.0
+ //
+ shared_ptr<package> mpv0 (
+ db.load<package> (
+ package_id (package_name ("libmisc"), version ("2.4.0"))));
+
+ assert (check_external (*mpv0));
+ assert (mpv0->other_repositories.size () == 1);
+ assert (mpv0->other_repositories[0].load () == tr);
+ assert (check_location (mpv0));
+
+ // libmisc-2.3.0+1
+ //
+ shared_ptr<package> mpv1 (
+ db.load<package> (
+ package_id (package_name ("libmisc"), version ("2.3.0+1"))));
+
+ assert (check_external (*mpv1));
+ assert (mpv1->other_repositories.size () == 1);
+ assert (mpv1->other_repositories[0].load () == tr);
+ assert (check_location (mpv1));
+
+ // Verify 'staging' repository.
+ //
+ assert (gr->location.canonical_name () == "pkg:dev.cppget.org/staging");
+ assert (gr->location.string () ==
+ "http://dev.cppget.org/1/staging");
+ assert (gr->display_name.empty ());
+ assert (gr->priority == 0);
+ assert (gr->interface_url &&
+ *gr->interface_url == "http://dev.cppget.org/");
+ assert (!gr->email);
+ assert (!gr->summary);
+ assert (!gr->description);
+
+ dir_path grp (loadtab.directory () / dir_path ("1/staging"));
+ assert (gr->cache_location.path () == grp.normalize ());
+
+ assert (gr->packages_timestamp ==
+ file_mtime (gr->cache_location.path () / packages));
+
+ assert (gr->repositories_timestamp ==
+ file_mtime (gr->cache_location.path () / repositories));
+
+ assert (!gr->internal);
+ assert (gr->prerequisites.empty ());
+ assert (gr->complements.empty ());
+
+ // Verify libexpat package version.
+ //
+ // libexpat-5.1
+ //
+ shared_ptr<package> tpv (
+ db.load<package> (
+ package_id (package_name ("libexpat"), version ("5.1"))));
+
+ assert (check_external (*tpv));
+ assert (tpv->other_repositories.size () == 1);
+ assert (tpv->other_repositories[0].load () == gr);
+ assert (check_location (tpv));
+
+ // Verify libgenx package version.
+ //
+ // libgenx-1.0
+ //
+ shared_ptr<package> gpv (
+ db.load<package> (
+ package_id (package_name ("libgenx"), version ("1.0"))));
+
+ assert (check_external (*gpv));
+ assert (gpv->other_repositories.size () == 1);
+ assert (gpv->other_repositories[0].load () == gr);
+ assert (check_location (gpv));
+
+ // Verify libmisc package version.
+ //
+ // libmisc-1.0
+ //
+ shared_ptr<package> mpv2 (
+ db.load<package> (
+ package_id (package_name ("libmisc"), version ("1.0"))));
+
+ assert (check_external (*mpv2));
+ assert (mpv2->other_repositories.size () == 1);
+ assert (mpv2->other_repositories[0].load () == gr);
+ assert (check_location (mpv2));
+
+ // Change package summary, update the object persistent state, rerun
+ // the loader and make sure the model were not rebuilt.
+ //
+ bpv->summary = "test";
+ db.update (bpv);
+
+ t.commit ();
+ }
+
+ // Rerun the loader without --force and make sure the model were not
+ // rebuilt.
+ //
+ {
+ cstrings args (loader_args);
+ args.push_back (loadtab.string ().c_str ());
+ args.push_back (nullptr);
+
+ assert (process (args.data ()).wait ());
- assert (process (ld_args).wait ());
transaction t (db.begin ());
shared_ptr<package> bpv (
@@ -914,11 +1025,27 @@ main (int argc, char* argv[])
t.commit ();
}
- // Fully qualified to avoid ambiguity with odb exception.
+
+ // Restore the original setup.
//
- catch (const std::exception& e)
{
- cerr << e << endl;
- return 1;
+ cstrings args (loader_args);
+ args.push_back ("--force");
+ args.push_back (loadtab.string ().c_str ());
+ args.push_back (nullptr);
+
+ assert (process (args.data ()).wait ());
+
+ transaction t (db.begin ());
+
+ shared_ptr<package> bpv (
+ db.find<package> (
+ package_id (package_name ("libbar"), version ("2.4.0+3"))));
+
+ // External package summary is not saved.
+ //
+ assert (bpv->summary.empty ());
+
+ t.commit ();
}
}
diff --git a/tests/load/git-cache/packages.manifest b/tests/load/git-cache/packages.manifest
new file mode 100644
index 0000000..1cec922
--- /dev/null
+++ b/tests/load/git-cache/packages.manifest
@@ -0,0 +1,14 @@
+: 1
+name: libfoo
+version: 1.0
+project: foo
+summary: The Foo Library
+license: MIT
+tags: c++, foo
+description-file: README
+changes-file: NEWS
+url: http://www.example.com/foo/
+email: foo-users@example.com
+depends: libmisc == 1.0
+location: libfoo
+fragment: 0f50af28d1cfb0c22f5b88e2bf674ab732e058d9
diff --git a/tests/load/git-cache/repositories.manifest b/tests/load/git-cache/repositories.manifest
new file mode 100644
index 0000000..f8f5696
--- /dev/null
+++ b/tests/load/git-cache/repositories.manifest
@@ -0,0 +1,7 @@
+: 1
+location: ../libmisc.git##HEAD
+type: git
+role: prerequisite
+fragment: 0f50af28d1cfb0c22f5b88e2bf674ab732e058d9
+:
+summary: foo project repository
diff --git a/tests/load/git-loadtab b/tests/load/git-loadtab
new file mode 100644
index 0000000..eb8f88b
--- /dev/null
+++ b/tests/load/git-loadtab
@@ -0,0 +1 @@
+https://git.example.com/foo.git#master foo cache:git-cache