aboutsummaryrefslogtreecommitdiff
path: root/bpkg/cfg-info.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/cfg-info.cxx')
-rw-r--r--bpkg/cfg-info.cxx101
1 files changed, 85 insertions, 16 deletions
diff --git a/bpkg/cfg-info.cxx b/bpkg/cfg-info.cxx
index da49d62..fc65b7b 100644
--- a/bpkg/cfg-info.cxx
+++ b/bpkg/cfg-info.cxx
@@ -3,8 +3,11 @@
#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>
@@ -20,35 +23,101 @@ namespace bpkg
dir_path c (o.directory ());
l4 ([&]{trace << "configuration: " << c;});
- database db (c, trace, o.link ());
+ if (o.recursive () && !o.link () && !o.backlink ())
+ fail << "--recursive requires --link or --backlink";
try
{
cout.exceptions (ostream::badbit | ostream::failbit);
- auto print = [] (const database& db)
+ // 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
{
- cout << "path: " << db.config << endl
- << "uuid: " << db.uuid << endl
- << "type: " << db.type << endl
- << "name: " << (db.name ? *db.name : "") << endl;
+ 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;
};
- print (db);
+ using query = odb::query<configuration>;
- // Note that there will be no explicit links loaded, unless the --link
- // option is specified.
+ 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.
//
- for (const linked_config& lc: db.explicit_links ())
+ q = q + "ORDER BY" + query::id;
+
+ auto print_db = [&o, &q, &print] (database& db,
+ bool links,
+ const auto& print_db)
{
- // Skip the self-link.
- //
- if (lc.id != 0)
+ if (!print (db.config, db.uuid, db.type, db.name))
+ return;
+
+ if (links)
{
- cout << endl;
- print (lc.db);
+ 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&)
{