From 4fcd32b536f3d29755b1fecc7e3f06be64f996ca Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sat, 24 Feb 2018 18:21:39 +0300 Subject: Add support for rep-list and rep-remove, update rep-add --- bpkg/rep-list.cxx | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 bpkg/rep-list.cxx (limited to 'bpkg/rep-list.cxx') 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 + +#include +#include // cout + +#include +#include +#include +#include + +using namespace std; + +namespace bpkg +{ + // Print the repository dependencies, recursively. + // + // Each line has the following form: + // + // [(complement|prerequisite) ] + // + // 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>, + compare_reference_target>; + + static void + print_dependencies (const rep_list_options& o, + const shared_ptr& 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& rp: r->complements) + { + // Skip the root complement (see rep_fetch() for details). + // + if (rp.object_id () == "") + continue; + + shared_ptr 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& rp: r->prerequisites) + { + shared_ptr 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& 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 root (db.load ("")); + + for (const lazy_shared_ptr& rp: root->complements) + { + shared_ptr r (rp.load ()); + cout << r->location.canonical_name () << " " << r->location << endl; + + if (o.complements () || o.prerequisites ()) + print_dependencies (o, r); + } + + t.commit (); + + return 0; + } +} -- cgit v1.1