diff options
Diffstat (limited to 'bpkg/cfg-info.cxx')
-rw-r--r-- | bpkg/cfg-info.cxx | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/bpkg/cfg-info.cxx b/bpkg/cfg-info.cxx new file mode 100644 index 0000000..fc65b7b --- /dev/null +++ b/bpkg/cfg-info.cxx @@ -0,0 +1,129 @@ +// file : bpkg/cfg-info.cxx -*- C++ -*- +// license : MIT; see accompanying LICENSE file + +#include <bpkg/cfg-info.hxx> + +#include <set> +#include <iostream> // cout + +#include <bpkg/package.hxx> +#include <bpkg/package-odb.hxx> +#include <bpkg/database.hxx> +#include <bpkg/diagnostics.hxx> + +using namespace std; + +namespace bpkg +{ + int + cfg_info (const cfg_info_options& o, cli::scanner&) + { + tracer trace ("cfg_info"); + + dir_path c (o.directory ()); + l4 ([&]{trace << "configuration: " << c;}); + + if (o.recursive () && !o.link () && !o.backlink ()) + fail << "--recursive requires --link or --backlink"; + + try + { + cout.exceptions (ostream::badbit | ostream::failbit); + + // Return false if the configuration information has already been + // printed and print the information and return true otherwise. + // + auto print = [first = true, + printed = set<dir_path> {}] + (const dir_path& path, + const uuid& uid, + const string& type, + const optional<string>& name) mutable + { + if (!printed.insert (path).second) + return false; + + if (!first) + cout << endl; + else + first = false; + + cout << "path: " << path << endl + << "uuid: " << uid << endl + << "type: " << type << endl + << "name: " << (name ? *name : "") << endl; + + return true; + }; + + using query = odb::query<configuration>; + + query q (false); + + if (o.link ()) + q = q || query::expl; + + if (o.backlink () || o.dangling ()) + q = q || (!query::expl && query::id != 0); + + // Make the output consistent across runs. + // + q = q + "ORDER BY" + query::id; + + auto print_db = [&o, &q, &print] (database& db, + bool links, + const auto& print_db) + { + if (!print (db.config, db.uuid, db.type, db.name)) + return; + + if (links) + { + for (auto& c: db.query<configuration> (q)) + { + const dir_path& d (c.make_effective_path (db.config)); + + auto print_link = [&o, &db, &c, &print_db] () + { + database& ldb (db.attach (c.path)); + db.verify_link (c, ldb); + + // While at it, also verify the backlink. + // + if (c.expl) + db.backlink (ldb); + + print_db (ldb, o.recursive (), print_db); + }; + + if (c.expl) + { + if (o.link ()) + print_link (); + } + else if (exists (d)) + { + if (o.backlink ()) + print_link (); + } + else if (o.dangling ()) + print (d, c.uuid, c.type, c.name); + } + } + }; + + database db (c, trace, false /* pre_attach */); + transaction t (db); + + print_db (db, o.link () || o.backlink () || o.dangling (), print_db); + + t.commit (); + } + catch (const io_error&) + { + fail << "unable to write to stdout"; + } + + return 0; + } +} |