aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-03-12 09:41:09 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-03-12 09:41:09 +0200
commit4d181c3aad97f8ee224666ce5c757036c5f610d5 (patch)
tree84f217c524bbcd4d38b3419a72df25942232decd
parentd8acf937750958313b565e17eb33191e90dd4b36 (diff)
Store initialized packages for each configuration in database
-rw-r--r--bdep/config.cxx3
-rw-r--r--bdep/init.cxx51
-rwxr-xr-xbdep/odb.sh4
-rw-r--r--bdep/project.cxx43
-rw-r--r--bdep/project.hxx59
-rw-r--r--bdep/project.xml17
-rw-r--r--bdep/utility.hxx2
-rw-r--r--bdep/utility.txx15
8 files changed, 158 insertions, 36 deletions
diff --git a/bdep/config.cxx b/bdep/config.cxx
index f7d74ed..1e646a3 100644
--- a/bdep/config.cxx
+++ b/bdep/config.cxx
@@ -48,7 +48,8 @@ namespace bdep
name,
path,
move (rel_path),
- *def});
+ *def,
+ {} /* packages */});
try
{
diff --git a/bdep/init.cxx b/bdep/init.cxx
index 44eb37e..1e864eb 100644
--- a/bdep/init.cxx
+++ b/bdep/init.cxx
@@ -6,6 +6,7 @@
#include <bdep/config.hxx>
#include <bdep/project.hxx>
+#include <bdep/project-odb.hxx>
#include <bdep/database.hxx>
#include <bdep/diagnostics.hxx>
@@ -24,8 +25,8 @@ namespace bdep
const dir_path& prj (pp.project);
text << prj;
- for (const dir_path& d: pp.packages)
- text << " " << (prj / d);
+ for (const package_location& pl: pp.packages)
+ text << " " << pl.name << " " << (prj / pl.path);
// Create .bdep/.
//
@@ -103,17 +104,55 @@ namespace bdep
// Fall through.
}
- transaction t (db.begin ());
-
// If this is the default mode, then find the configurations the user
// wants us to use.
//
if (cfgs.empty ())
+ {
+ transaction t (db.begin ());
cfgs = find_configurations (prj, t, o);
+ t.commit ();
+ }
- //@@ TODO: print project/package(s) being initialized.
+ // Initialize each package in each configuration skipping those that are
+ // already initialized. Do each configuration in a separate transaction so
+ // that our state reflects the bpkg configuration as closely as possible.
+ //
+ for (const shared_ptr<configuration>& c: cfgs)
+ {
+ transaction t (db.begin ());
+
+ // Add project repository to the configuration. Note that we don't fetch
+ // it since sync is going to do it anyway.
+ //
+ run_bpkg (o,
+ "add",
+ "-d", c->path,
+ "--type", "dir",
+ prj);
+
+ for (const package_location& p: pp.packages)
+ {
+ if (find_if (c->packages.begin (),
+ c->packages.end (),
+ [&p] (const package_state& s)
+ {
+ return p.name == s.name;
+ }) != c->packages.end ())
+ {
+ info << "package " << p.name << " is already initialized "
+ << "in configuration " << *c;
+ continue;
+ }
+
+ c->packages.push_back (package_state {p.name});
+ }
- t.commit ();
+ db.update (c);
+ t.commit ();
+ }
+
+ //@@ TODO: print project/package(s) being initialized.
return 0;
}
diff --git a/bdep/odb.sh b/bdep/odb.sh
index 4bd83b5..07c744a 100755
--- a/bdep/odb.sh
+++ b/bdep/odb.sh
@@ -11,7 +11,7 @@ lib="\
$odb $lib -I.. -I../../libbpkg -I../../libbutl \
-DLIBODB_BUILD2 -DLIBODB_SQLITE_BUILD2 --generate-schema \
- -d sqlite --std c++11 --generate-query \
+ -d sqlite --std c++14 --generate-query \
--odb-epilogue '#include <bdep/wrapper-traits.hxx>' \
--hxx-prologue '#include <bdep/wrapper-traits.hxx>' \
--include-with-brackets --include-prefix bdep --guard-prefix BDEP \
@@ -19,7 +19,7 @@ $odb $lib -I.. -I../../libbpkg -I../../libbutl \
$odb $lib -I.. -I../../libbpkg -I../../libbutl \
-DLIBODB_BUILD2 -DLIBODB_SQLITE_BUILD2 \
- -d sqlite --std c++11 --generate-query \
+ -d sqlite --std c++14 --generate-query \
--odb-epilogue '#include <bdep/wrapper-traits.hxx>' \
--hxx-prologue '#include <bdep/wrapper-traits.hxx>' \
--include-with-brackets --include-prefix bdep --guard-prefix BDEP \
diff --git a/bdep/project.cxx b/bdep/project.cxx
index 84b7acd..d3e3f11 100644
--- a/bdep/project.cxx
+++ b/bdep/project.cxx
@@ -208,11 +208,16 @@ namespace bdep
{
// Suppress duplicate packages.
//
- if (find (r.packages.begin (),
- r.packages.end (),
- *p.package) == r.packages.end ())
+ if (find_if (r.packages.begin (),
+ r.packages.end (),
+ [&p] (const package_location& pl)
+ {
+ return *p.package == pl.path;
+ }) == r.packages.end ())
{
- r.packages.push_back (move (*p.package));
+ // Name is to be extracted later.
+ //
+ r.packages.push_back (package_location {"", move (*p.package)});
}
}
}
@@ -225,7 +230,9 @@ namespace bdep
if (!ignore_packages && p.package)
{
- r.packages.push_back (move (*p.package));
+ // Name is to be extracted later.
+ //
+ r.packages.push_back (move (package_location {"", *p.package}));
}
}
@@ -263,8 +270,10 @@ namespace bdep
if (r.packages.empty ())
{
+ // Name is to be extracted later.
+ //
for (package_manifest& m: ms)
- r.packages.push_back (location (m));
+ r.packages.push_back (package_location {"", location (m)});
}
else
{
@@ -272,16 +281,18 @@ namespace bdep
// comparison. We, however, do not expect more than a handful of
// packages so we are probably ok.
//
- for (const dir_path& pd: r.packages)
+ for (const package_location& pl: r.packages)
{
+ const dir_path& p (pl.path);
+
if (find_if (ms.begin (),
ms.end (),
- [&pd, &location] (const package_manifest& m)
+ [&p, &location] (const package_manifest& m)
{
- return pd == location (m);
+ return p == location (m);
}) == ms.end ())
{
- fail << "package directory " << pd << " not listed in " << f;
+ fail << "package directory " << p << " is not listed in " << f;
}
}
}
@@ -291,7 +302,17 @@ namespace bdep
// If packages.manifest does not exist, then this must be a simple
// project.
//
- assert (r.packages.size () == 1 && r.packages[0].empty ());
+ assert (r.packages.size () == 1 && r.packages[0].path.empty ());
+ }
+
+ // Load each package's manifest and obtain its name (name is normally
+ // the first value so we could optimize this, if necessary).
+ //
+ for (package_location& pl: r.packages)
+ {
+ path f (r.project / pl.path / manifest_file);
+ auto m (parse_manifest<bpkg::package_manifest> (f, "package"));
+ pl.name = move (m.name);
}
}
diff --git a/bdep/project.hxx b/bdep/project.hxx
index 42f520a..2d0d3f1 100644
--- a/bdep/project.hxx
+++ b/bdep/project.hxx
@@ -36,13 +36,28 @@ namespace bdep
to((?) ? (?)->string () : bdep::optional_string ()) \
from((?) ? bdep::dir_path (*(?)) : bdep::optional_dir_path ())
- //@@ TODO: do we need session/shared_ptr?
+ // State of a package in a configuration.
+ //
+ // Pretty much everything about the package can change (including location
+ // within the project) with the only immutable data being its name (even the
+ // version in the manifest could be bogus without the fix-up). As a result,
+ // that't the only thing we store in the database with everything else (like
+ // location) always loaded from the manifest on each run. We may, however,
+ // need to store some additional state (like manifest hash to speed up noop
+ // syncs) in the future.
+ //
+ #pragma db value
+ struct package_state
+ {
+ string name;
+ };
+ // Configuration associated with a project.
+ //
#pragma db object pointer(shared_ptr) session
class configuration
{
public:
-
// The configuration stores an absolute and normalized path to the bpkg
// configuration. It may also have a name. A configuration can be moved or
// renamed so we also have the id (it is NULL'able so that we can assign
@@ -62,11 +77,18 @@ namespace bdep
bool default_;
+ // We made it a vector instead of set/map since we are unlikely to have
+ // more than a handful of packages. We may, however, want to use a change-
+ // tracking vector later (e.g., to optimize updates).
+ //
+ vector<package_state> packages;
+
// Database mapping.
//
#pragma db member(id) id auto
#pragma db member(name) unique
#pragma db member(path) unique
+ #pragma db member(packages) value_column("")
// Make path comparison case-insensitive for certain platforms.
//
@@ -85,6 +107,19 @@ namespace bdep
configuration () = default;
};
+ // Print configuration name if available and path otherwise.
+ //
+ inline ostream&
+ operator<< (ostream& os, const configuration& c)
+ {
+ if (c.name)
+ os << '@' << *c.name;
+ else
+ os << c.path;
+
+ return os;
+ }
+
#pragma db view object(configuration)
struct configuration_count
{
@@ -106,17 +141,25 @@ namespace bdep
const project_options&);
// Given the project options (and CWD) locate the packages and their
- // project. The result is the absolute and normalized project directory and
- // a vector of relative (to the project directory) package directories
- // (which will be empty if ignore_packages is true).
+ // project. The result is an absolute and normalized project directory and a
+ // vector of relative (to the project directory) package locations (which
+ // will be empty if ignore_packages is true).
//
// Note that if the package directory is the same as project, then the
- // package directory will be empty (and not ./).
+ // package path will be empty (and not ./).
//
+ struct package_location
+ {
+ string name;
+ dir_path path;
+ };
+
+ using package_locations = vector<package_location>;
+
struct project_packages
{
- dir_path project;
- dir_paths packages;
+ dir_path project;
+ package_locations packages;
};
project_packages
diff --git a/bdep/project.xml b/bdep/project.xml
index cf8d2c7..5685945 100644
--- a/bdep/project.xml
+++ b/bdep/project.xml
@@ -16,5 +16,22 @@
<column name="path"/>
</index>
</table>
+ <table name="configuration_packages" kind="container">
+ <column name="object_id" type="INTEGER" null="true"/>
+ <column name="index" type="INTEGER" null="true"/>
+ <column name="name" type="TEXT" null="true"/>
+ <foreign-key name="object_id_fk" on-delete="CASCADE">
+ <column name="object_id"/>
+ <references table="configuration">
+ <column name="id"/>
+ </references>
+ </foreign-key>
+ <index name="configuration_packages_object_id_i">
+ <column name="object_id"/>
+ </index>
+ <index name="configuration_packages_index_i">
+ <column name="index"/>
+ </index>
+ </table>
</model>
</changelog>
diff --git a/bdep/utility.hxx b/bdep/utility.hxx
index 36a405c..d8a4983 100644
--- a/bdep/utility.hxx
+++ b/bdep/utility.hxx
@@ -100,7 +100,7 @@ namespace bdep
start_bpkg (const common_options&, O&& out, E&& err, A&&... args);
template <typename... A>
- process_exit
+ void
run_bpkg (const common_options&, A&&... args);
// Manifest parsing and serialization.
diff --git a/bdep/utility.txx b/bdep/utility.txx
index 52bbfdb..b796f69 100644
--- a/bdep/utility.txx
+++ b/bdep/utility.txx
@@ -32,7 +32,7 @@ namespace bdep
// Map verbosity level. If we are running quiet or at level 1, then run
// bpkg quiet. Otherwise, run it at the same level as us.
//
- bool quiet (false); // Maybe will become an argument one day.
+ bool quiet (true); // Maybe will become an argument one day.
string vl;
if (verb <= (quiet ? 1 : 0))
ops.push_back ("-q");
@@ -80,21 +80,22 @@ namespace bdep
}
template <typename... A>
- process_exit
+ void
run_bpkg (const common_options& co, A&&... args)
{
process pr (start_bpkg (co,
1 /* stdout */,
2 /* stderr */,
forward<A> (args)...));
- pr.wait ();
+ if (!pr.wait ())
+ {
+ const process_exit& e (*pr.exit);
- const process_exit& e (*pr.exit);
+ if (e.normal ())
+ throw failed (); // Assume the child issued diagnostics.
- if (!e.normal ())
fail << "process " << name_bpkg (co) << " " << e;
-
- return e;
+ }
}
// *_manifest()