From 9ffd711094b68d8ce5bb464621020ccc993d787c Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 15 Mar 2018 13:08:45 +0200 Subject: Add --immediate|-i and --recursive|-r to pkg-status for dependencies --- bpkg/pkg-status.cxx | 171 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 110 insertions(+), 61 deletions(-) (limited to 'bpkg/pkg-status.cxx') diff --git a/bpkg/pkg-status.cxx b/bpkg/pkg-status.cxx index 35b3db0..b440ad9 100644 --- a/bpkg/pkg-status.cxx +++ b/bpkg/pkg-status.cxx @@ -25,69 +25,19 @@ namespace bpkg }; using packages = vector; - int - pkg_status (const pkg_status_options& o, cli::scanner& args) + // If single is true, then omit the package name. If recursive or immediate + // is true, then print status for dependencies indented by two spaces. + // + static void + pkg_status (database& db, + const packages& pkgs, + bool single, + string& indent, + bool recursive, + bool immediate) { tracer trace ("pkg_status"); - const dir_path& c (o.directory ()); - l4 ([&]{trace << "configuration: " << c;}); - - database db (open (c, trace)); - transaction t (db.begin ()); - session s; - - packages pkgs; - bool single (false); // True if single package specified by the user. - { - using query = query; - - if (args.more ()) - { - while (args.more ()) - { - const char* arg (args.next ()); - package p {parse_package_name (arg), - parse_package_version (arg), - nullptr}; - - // Search in the packages that already exist in this configuration. - // - { - query q (query::name == p.name); - - if (!p.version.empty ()) - q = q && compare_version_eq (query::version, - p.version, - p.version.revision != 0); - - p.selected = db.query_one (q); - } - - pkgs.push_back (move (p)); - } - - single = (pkgs.size () == 1); - } - else - { - // Find all held packages. - // - for (shared_ptr s: - pointer_result ( - db.query (query::hold_package))) - { - pkgs.push_back (package {s->name, version (), move (s)}); - } - - if (pkgs.empty ()) - { - info << "no held packages in the configuration"; - return 0; - } - } - } - for (const package& p: pkgs) { l4 ([&]{trace << "package " << p.name << "; version " << p.version;}); @@ -135,10 +85,12 @@ namespace bpkg } } + cout << indent; + // Suppress printing the package name if there is only one and it was // specified by the user. // - if (!single) + if (!single || immediate || recursive) { cout << p.name; @@ -214,7 +166,104 @@ namespace bpkg cout << "unknown"; cout << endl; + + if (recursive || immediate) + { + // Collect and recurse. + // + packages dpkgs; + if (p.selected != nullptr) + { + for (const auto& pair: p.selected->prerequisites) + { + shared_ptr d (pair.first.load ()); + dpkgs.push_back (package {d->name, version (), move (d)}); + } + } + + if (!dpkgs.empty ()) + { + indent += " "; + pkg_status (db, + dpkgs, + false /* single */, + indent, + recursive, + false /* immediate */); + indent.resize (indent.size () - 2); + } + } } + } + + int + pkg_status (const pkg_status_options& o, cli::scanner& args) + { + tracer trace ("pkg_status"); + + if (o.immediate () && o.recursive ()) + fail << "both --immediate|-i and --recursive|-r specified"; + + const dir_path& c (o.directory ()); + l4 ([&]{trace << "configuration: " << c;}); + + database db (open (c, trace)); + transaction t (db.begin ()); + session s; + + packages pkgs; + bool single (false); // True if single package specified by the user. + { + using query = query; + + if (args.more ()) + { + while (args.more ()) + { + const char* arg (args.next ()); + package p {parse_package_name (arg), + parse_package_version (arg), + nullptr}; + + // Search in the packages that already exist in this configuration. + // + { + query q (query::name == p.name); + + if (!p.version.empty ()) + q = q && compare_version_eq (query::version, + p.version, + p.version.revision != 0); + + p.selected = db.query_one (q); + } + + pkgs.push_back (move (p)); + } + + single = (pkgs.size () == 1); + } + else + { + // Find all held packages. + // + for (shared_ptr s: + pointer_result ( + db.query (query::hold_package))) + { + pkgs.push_back (package {s->name, version (), move (s)}); + } + + if (pkgs.empty ()) + { + info << "no held packages in the configuration"; + return 0; + } + } + } + + string indent; + pkg_status (db, pkgs, single, indent, o.recursive (), o.immediate ()); t.commit (); return 0; -- cgit v1.1