aboutsummaryrefslogtreecommitdiff
path: root/bpkg/rep-list.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-02-24 18:21:39 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-02-26 17:50:24 +0300
commit4fcd32b536f3d29755b1fecc7e3f06be64f996ca (patch)
tree4aebf6eeb7ac4de316ddc91b92c264f252f86d44 /bpkg/rep-list.cxx
parent12a5375f25d6a7be5a5741c728a8f9b8168761a4 (diff)
Add support for rep-list and rep-remove, update rep-add
Diffstat (limited to 'bpkg/rep-list.cxx')
-rw-r--r--bpkg/rep-list.cxx124
1 files changed, 124 insertions, 0 deletions
diff --git a/bpkg/rep-list.cxx b/bpkg/rep-list.cxx
new file mode 100644
index 0000000..f2aca2c
--- /dev/null
+++ b/bpkg/rep-list.cxx
@@ -0,0 +1,124 @@
+// file : bpkg/rep-list.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <bpkg/rep-list.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
+{
+ // Print the repository dependencies, recursively.
+ //
+ // Each line has the following form:
+ //
+ // [(complement|prerequisite) ]<name> <location>
+ //
+ // and is indented with 2 additional spaces for each recursion level.
+ //
+ // Note that we can end up with a repository dependency cycle via
+ // prerequisites. Thus we need to make sure that the repository is not in
+ // the dependency chain yet.
+ //
+ using repositories = set<reference_wrapper<const shared_ptr<repository>>,
+ compare_reference_target>;
+
+ static void
+ print_dependencies (const rep_list_options& o,
+ const shared_ptr<repository>& r,
+ string& indent,
+ repositories& chain)
+ {
+ assert (!r->name.empty ()); // Can't be the root repository.
+
+ if (!chain.insert (r).second) // Is already in the chain.
+ return;
+
+ indent += " ";
+
+ if (o.complements ())
+ {
+ for (const lazy_shared_ptr<repository>& rp: r->complements)
+ {
+ // Skip the root complement (see rep_fetch() for details).
+ //
+ if (rp.object_id () == "")
+ continue;
+
+ shared_ptr<repository> r (rp.load ());
+
+ cout << indent << "complement "
+ << r->location.canonical_name () << " " << r->location << endl;
+
+ print_dependencies (o, r, indent, chain);
+ }
+ }
+
+ if (o.prerequisites ())
+ {
+ for (const lazy_weak_ptr<repository>& rp: r->prerequisites)
+ {
+ shared_ptr<repository> r (rp.load ());
+
+ cout << indent << "prerequisite "
+ << r->location.canonical_name () << " " << r->location << endl;
+
+ print_dependencies (o, r, indent, chain);
+ }
+ }
+
+ indent.pop_back ();
+ indent.pop_back ();
+
+ chain.erase (r);
+ }
+
+ static inline void
+ print_dependencies (const rep_list_options& o,
+ const shared_ptr<repository>& r)
+ {
+ string indent;
+ repositories chain;
+ print_dependencies (o, r, indent, chain);
+ }
+
+ int
+ rep_list (const rep_list_options& o, cli::scanner& args)
+ {
+ tracer trace ("rep_list");
+
+ dir_path c (o.directory ());
+ l4 ([&]{trace << "configuration: " << c;});
+
+ if (args.more ())
+ fail << "unexpected argument '" << args.next () << "'" <<
+ info << "run 'bpkg help rep-list' for more information";
+
+ database db (open (c, trace));
+ transaction t (db.begin ());
+ session s; // Repository dependencies can have cycles.
+
+ shared_ptr<repository> root (db.load<repository> (""));
+
+ for (const lazy_shared_ptr<repository>& rp: root->complements)
+ {
+ shared_ptr<repository> r (rp.load ());
+ cout << r->location.canonical_name () << " " << r->location << endl;
+
+ if (o.complements () || o.prerequisites ())
+ print_dependencies (o, r);
+ }
+
+ t.commit ();
+
+ return 0;
+ }
+}