aboutsummaryrefslogtreecommitdiff
path: root/bpkg
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2021-09-04 15:41:41 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-09-06 11:53:45 +0300
commit03c40ed68ce10b26a5f9f509e914b1b54f060215 (patch)
tree42e79327baa90f4cfdee1ba04dba98250293fcfd /bpkg
parent22165c649ca2c5ef216ae3f99fbfb2dc0fff99ab (diff)
Add --backlink, --dangling, and --recursive options to cfg-info
Diffstat (limited to 'bpkg')
-rw-r--r--bpkg/cfg-info.cli33
-rw-r--r--bpkg/cfg-info.cxx101
-rw-r--r--bpkg/cfg-link.cli2
-rw-r--r--bpkg/cfg-link.cxx2
-rw-r--r--bpkg/cfg-link.hxx2
-rw-r--r--bpkg/cfg-unlink.cli4
-rw-r--r--bpkg/cfg-unlink.cxx12
-rw-r--r--bpkg/database.cxx33
-rw-r--r--bpkg/database.hxx7
-rw-r--r--bpkg/package.hxx2
10 files changed, 153 insertions, 45 deletions
diff --git a/bpkg/cfg-info.cli b/bpkg/cfg-info.cli
index 8002abd..8801ec9 100644
--- a/bpkg/cfg-info.cli
+++ b/bpkg/cfg-info.cli
@@ -19,14 +19,22 @@ namespace bpkg
\h|DESCRIPTION|
The \cb{cfg-info} command prints the current configuration's absolute
- path, id, type, and name. If the \cb{--link} option is specified then
- this information is also printed for each linked configuration, if any.
+ path, id, type, and name. If the \cb{--link} and/or \cb{--backlink}
+ options are specified, then this information is also printed for each
+ linked and/or implicitly backlinked configuration, if any. Note that the
+ dangling implicit backlinks are silently skipped, unless \cb{--dangling}
+ is specified, in which case this information is also printed for them.
Note that the information is written to \cb{stdout}, not \cb{stderr}.
+ If the \cb{--recursive} option is specified together with \cb{--link}
+ and/or \cb{--backlink}, then this information is printed for linked
+ and/or implicitly backlinked configuration, recursively.
+
The output format is regular with each value printed on a separate line
- and prefixed with the value name. If the \cb{--link} option is specified
- then information blocks corresponding to configurations are separated
- with blank lines. For example:
+ and prefixed with the value name. If the \cb{--link}, \cb{--backlink},
+ and/or \cb{--dangling} options are specified, then information blocks
+ corresponding to linked configurations are separated with blank
+ lines. For example:
\
path: /path/to/cfg/
@@ -55,6 +63,21 @@ namespace bpkg
{
"Print linked configurations."
}
+
+ bool --backlink
+ {
+ "Print implicitly backlinked configurations."
+ }
+
+ bool --dangling
+ {
+ "Print dangling implicit backlinks."
+ }
+
+ bool --recursive
+ {
+ "Print linked configurations recursively."
+ }
};
"
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&)
{
diff --git a/bpkg/cfg-link.cli b/bpkg/cfg-link.cli
index 562d4c1..906a4d5 100644
--- a/bpkg/cfg-link.cli
+++ b/bpkg/cfg-link.cli
@@ -20,7 +20,7 @@ namespace bpkg
The \cb{cfg-link} command links the specified \cb{bpkg} configuration
with the current configuration. Note that it also establishes an implicit
- back-link from the specified to the current configuration. See
+ backlink from the specified to the current configuration. See
\l{bpkg-cfg-create(1)} for background on linked configurations. To unlink
previously linked configurations use \l{bpkg-cfg-unlink(1)}.
diff --git a/bpkg/cfg-link.cxx b/bpkg/cfg-link.cxx
index 5cbeef7..1146d22 100644
--- a/bpkg/cfg-link.cxx
+++ b/bpkg/cfg-link.cxx
@@ -139,7 +139,7 @@ namespace bpkg
//
if (lcf != nullptr)
{
- // Verify the back-link integrity.
+ // Verify the backlink integrity.
//
shared_ptr<configuration> cf (
ldb.query_one<configuration> (query::uuid == db.uuid.string ()));
diff --git a/bpkg/cfg-link.hxx b/bpkg/cfg-link.hxx
index 116512b..ee625fa 100644
--- a/bpkg/cfg-link.hxx
+++ b/bpkg/cfg-link.hxx
@@ -17,7 +17,7 @@ namespace bpkg
// Link the configuration specified as the directory path with the current
// configuration, attach the linked configuration database, and return the
- // link. Note that it also establishes an implicit back-link of the current
+ // link. Note that it also establishes an implicit backlink of the current
// configuration with the linked one.
//
// The specified configuration path must be absolute and normalized. If the
diff --git a/bpkg/cfg-unlink.cli b/bpkg/cfg-unlink.cli
index ade3373..6514882 100644
--- a/bpkg/cfg-unlink.cli
+++ b/bpkg/cfg-unlink.cli
@@ -21,7 +21,7 @@ namespace bpkg
The \cb{cfg-unlink} command unlinks the specified \cb{bpkg} configuration
from the current configuration (the first form) or removes dangling
- implicit back-links (the second form). See \l{bpkg-cfg-create(1)} for
+ implicit backlinks (the second form). See \l{bpkg-cfg-create(1)} for
background on linked configurations.
In the first form the configuration to unlink can be specified either as
@@ -54,7 +54,7 @@ namespace bpkg
bool --dangling
{
- "Remove dangling implicit back-links."
+ "Remove dangling implicit backlinks."
}
};
diff --git a/bpkg/cfg-unlink.cxx b/bpkg/cfg-unlink.cxx
index e29d949..52d8969 100644
--- a/bpkg/cfg-unlink.cxx
+++ b/bpkg/cfg-unlink.cxx
@@ -69,7 +69,7 @@ namespace bpkg
// Unlink the configuration in the in-memory model, so we can evaluate
// if the dependent configurations are still linked with it.
//
- // Note that we don't remove the back-link here, since this is not
+ // Note that we don't remove the backlink here, since this is not
// required for the check.
//
if (!priv)
@@ -162,7 +162,7 @@ namespace bpkg
//
assert (uc != nullptr);
- // Implicit back-link.
+ // Implicit backlink.
//
shared_ptr<configuration> cc (
udb.query_one<configuration> (query::uuid == mdb.uuid.string ()));
@@ -172,7 +172,7 @@ namespace bpkg
//
assert (cc != nullptr);
- // If the back-link turns out to be explicit, then, unless the
+ // If the backlink turns out to be explicit, then, unless the
// configuration being unlinked is private, we just turn the explicit
// link into an implicit one rather then remove the direct and back
// links.
@@ -181,7 +181,7 @@ namespace bpkg
{
info << "configurations " << udb.config_orig << " and "
<< mdb.config_orig << " are mutually linked, turning the link "
- << "to " << udb.config_orig << " into implicit back-link";
+ << "to " << udb.config_orig << " into implicit backlink";
uc->expl = false;
mdb.update (uc);
@@ -237,7 +237,7 @@ namespace bpkg
if (!exists (c.effective_path (db.config)))
{
if (verb > 1)
- text << "removing dangling implicit back-link " << c.path;
+ text << "removing dangling implicit backlink " << c.path;
db.erase (c);
++count;
@@ -247,7 +247,7 @@ namespace bpkg
t.commit ();
if (verb && !o.no_result ())
- text << "removed " << count << " dangling implicit back-link(s)";
+ text << "removed " << count << " dangling implicit backlink(s)";
return 0;
}
diff --git a/bpkg/database.cxx b/bpkg/database.cxx
index ab2bcfc..451ade3 100644
--- a/bpkg/database.cxx
+++ b/bpkg/database.cxx
@@ -697,7 +697,7 @@ namespace bpkg
if (!lc.expl && !exists (d))
{
if (verb > 1)
- info << "skipping dangling implicit back-link " << lc.path <<
+ info << "skipping dangling implicit backlink " << lc.path <<
info << "use 'cfg-unlink --dangling' to clean up";
continue;
@@ -714,17 +714,7 @@ namespace bpkg
//
if (lc.expl)
{
- shared_ptr<configuration> cf (
- db.query_one<configuration> (q::uuid == uuid.string ()));
-
- if (cf == nullptr)
- fail << "configuration " << db.config_orig << " is linked with "
- << config_orig << " but latter is not implicitly linked "
- << "with former";
-
- // While at it, verify the integrity of the other end of the link.
- //
- db.verify_link (*cf, *this);
+ shared_ptr<configuration> cf (backlink (db));
if (!cf->expl)
continue;
@@ -746,6 +736,25 @@ namespace bpkg
return implicit_links_;
}
+ shared_ptr<configuration> database::
+ backlink (database& db)
+ {
+ using q = odb::query<configuration>;
+
+ shared_ptr<configuration> cf (
+ db.query_one<configuration> (q::uuid == uuid.string ()));
+
+ if (cf == nullptr)
+ fail << "configuration " << db.config_orig << " is linked with "
+ << config_orig << " but latter is not implicitly linked "
+ << "with former";
+
+ // While at it, verify the integrity of the other end of the link.
+ //
+ db.verify_link (*cf, *this);
+ return cf;
+ }
+
linked_databases database::
dependent_configs (bool sys_rep)
{
diff --git a/bpkg/database.hxx b/bpkg/database.hxx
index 40474d3..889f8a0 100644
--- a/bpkg/database.hxx
+++ b/bpkg/database.hxx
@@ -376,6 +376,13 @@ namespace bpkg
void
verify_link (const configuration&, database&);
+ // Assuming that the passed configuration is explicitly linked to the
+ // current one, return the corresponding backlink. Issue diagnostics and
+ // fail if the backlink is not found.
+ //
+ shared_ptr<configuration>
+ backlink (database&);
+
// Set the specified tracer for the whole linked databases cluster.
//
using tracer_type = odb::tracer;
diff --git a/bpkg/package.hxx b/bpkg/package.hxx
index 6256481..13efcd4 100644
--- a/bpkg/package.hxx
+++ b/bpkg/package.hxx
@@ -160,7 +160,7 @@ namespace bpkg
dir_path path; // Empty for the self-link.
// True if the link is created explicitly by the user rather than
- // automatically as a back-link.
+ // automatically as a backlink.
//
bool expl;