diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2018-02-24 18:21:39 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2018-02-26 17:50:24 +0300 |
commit | 4fcd32b536f3d29755b1fecc7e3f06be64f996ca (patch) | |
tree | 4aebf6eeb7ac4de316ddc91b92c264f252f86d44 /bpkg/rep-list.cxx | |
parent | 12a5375f25d6a7be5a5741c728a8f9b8168761a4 (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.cxx | 124 |
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; + } +} |