aboutsummaryrefslogtreecommitdiff
path: root/bpkg/pkg-command.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-05-11 14:41:12 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-05-11 16:01:16 +0300
commite035fbaf5e5ae862191dc3d9eb047ac0abba6dbb (patch)
treeafa96dfcbf0b8af174bf7c4ed171cd43a6a7dcb1 /bpkg/pkg-command.cxx
parentca387611165403835655db1f3620ef8e65cb92b5 (diff)
Add support for recursive pkg-test
Diffstat (limited to 'bpkg/pkg-command.cxx')
-rw-r--r--bpkg/pkg-command.cxx68
1 files changed, 59 insertions, 9 deletions
diff --git a/bpkg/pkg-command.cxx b/bpkg/pkg-command.cxx
index 4475ea7..b28c99a 100644
--- a/bpkg/pkg-command.cxx
+++ b/bpkg/pkg-command.cxx
@@ -4,6 +4,8 @@
#include <bpkg/pkg-command.hxx>
+#include <algorithm> // find_if()
+
#include <bpkg/package.hxx>
#include <bpkg/package-odb.hxx>
#include <bpkg/database.hxx>
@@ -86,31 +88,69 @@ namespace bpkg
run ();
}
+ static void
+ collect_dependencies (const shared_ptr<selected_package>& p,
+ bool recursive,
+ vector<pkg_command_vars>& ps)
+ {
+ for (const auto& pr: p->prerequisites)
+ {
+ shared_ptr<selected_package> d (pr.first.load ());
+
+ // The selected package can only be configured if all its dependencies
+ // are configured.
+ //
+ assert (d->state == package_state::configured);
+
+ // Skip configured as system and duplicate dependencies.
+ //
+ if (d->substate != package_substate::system &&
+ find_if (ps.begin (), ps.end (),
+ [&d] (const pkg_command_vars& i) {return i.pkg == d;}) ==
+ ps.end ())
+ {
+ // Note: no package-specific variables (global ones still apply).
+ //
+ ps.push_back (pkg_command_vars {d, strings () /* vars */});
+
+ if (recursive)
+ collect_dependencies (d, recursive, ps);
+ }
+ }
+ }
+
int
pkg_command (const string& cmd,
const configuration_options& o,
const string& cmd_v,
+ bool recursive,
+ bool immediate,
cli::scanner& args)
{
tracer trace ("pkg_command");
+ // We can as well count on the immediate/recursive option names.
+ //
+ if (immediate && recursive)
+ fail << "both --immediate|-i and --recursive|-r specified";
+
const dir_path& c (o.directory ());
l4 ([&]{trace << "configuration: " << c;});
// First read the common variables.
//
auto read_vars = [&args](strings& v)
+ {
+ for (; args.more (); args.next ())
{
- for (; args.more (); args.next ())
- {
- string a (args.peek ());
+ string a (args.peek ());
- if (a.find ('=') == string::npos)
- break;
+ if (a.find ('=') == string::npos)
+ break;
- v.push_back (move (a));
- }
- };
+ v.push_back (move (a));
+ }
+ };
strings cvars;
read_vars (cvars);
@@ -124,6 +164,11 @@ namespace bpkg
database db (open (c, trace));
transaction t (db);
+ // We need to suppress duplicate dependencies for the recursive command
+ // execution.
+ //
+ session ses;
+
while (args.more ())
{
string n (args.next ());
@@ -146,7 +191,12 @@ namespace bpkg
strings vars;
read_vars (vars);
- ps.push_back (pkg_command_vars {move (p), move (vars)});
+ ps.push_back (pkg_command_vars {p, move (vars)});
+
+ // Note that it can only be recursive or immediate but not both.
+ //
+ if (recursive || immediate)
+ collect_dependencies (p, recursive, ps);
}
t.commit ();