diff options
-rw-r--r-- | bpkg/bpkg-options.cli | 7 | ||||
-rw-r--r-- | bpkg/bpkg.cxx | 22 | ||||
-rw-r--r-- | bpkg/build | 17 | ||||
-rw-r--r-- | bpkg/build-options.cli | 33 | ||||
-rw-r--r-- | bpkg/build.cxx | 229 | ||||
-rw-r--r-- | bpkg/buildfile | 18 | ||||
-rw-r--r-- | bpkg/configuration-options.cli (renamed from bpkg/pkg-common-options.cli) | 6 | ||||
-rw-r--r-- | bpkg/database | 4 | ||||
-rw-r--r-- | bpkg/manifest-utility | 10 | ||||
-rw-r--r-- | bpkg/manifest-utility.cxx | 39 | ||||
-rw-r--r-- | bpkg/package | 16 | ||||
-rw-r--r-- | bpkg/package.cxx | 66 | ||||
-rw-r--r-- | bpkg/pkg-clean-options.cli | 4 | ||||
-rw-r--r-- | bpkg/pkg-command | 4 | ||||
-rw-r--r-- | bpkg/pkg-command.cxx | 2 | ||||
-rw-r--r-- | bpkg/pkg-configure-options.cli | 4 | ||||
-rw-r--r-- | bpkg/pkg-disfigure-options.cli | 4 | ||||
-rw-r--r-- | bpkg/pkg-fetch-options.cli | 4 | ||||
-rw-r--r-- | bpkg/pkg-purge-options.cli | 4 | ||||
-rw-r--r-- | bpkg/pkg-status-options.cli | 4 | ||||
-rw-r--r-- | bpkg/pkg-status.cxx | 40 | ||||
-rw-r--r-- | bpkg/pkg-unpack-options.cli | 4 | ||||
-rw-r--r-- | bpkg/pkg-update-options.cli | 4 | ||||
-rw-r--r-- | bpkg/rep-add-options.cli | 10 | ||||
-rw-r--r-- | bpkg/rep-fetch-options.cli | 10 | ||||
-rw-r--r-- | bpkg/rep-fetch.cxx | 4 | ||||
-rw-r--r-- | bpkg/utility | 2 |
27 files changed, 473 insertions, 98 deletions
diff --git a/bpkg/bpkg-options.cli b/bpkg/bpkg-options.cli index c67f8d7..c8a18a5 100644 --- a/bpkg/bpkg-options.cli +++ b/bpkg/bpkg-options.cli @@ -21,6 +21,13 @@ namespace bpkg "" }; + bool build + { + "<pkg>...", + "Build one or more packages.", + "" + }; + bool pkg-verify { "<archive>", diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx index 059d7c5..51c3b0a 100644 --- a/bpkg/bpkg.cxx +++ b/bpkg/bpkg.cxx @@ -16,6 +16,8 @@ // #include <bpkg/help> +#include <bpkg/build> + #include <bpkg/pkg-verify> #include <bpkg/pkg-status> #include <bpkg/pkg-fetch> @@ -165,20 +167,26 @@ try // return 0; // } // -#define ANY_COMMAND(OBJ, CMD) \ - if (cmd.OBJ##_##CMD ()) \ +#define COMMAND_IMPL(NP, SP, CMD) \ + if (cmd.NP##CMD ()) \ { \ if (h) \ - help (ho, #OBJ"-"#CMD, OBJ##_##CMD##_options::print_usage); \ + help (ho, SP#CMD, NP##CMD##_options::print_usage); \ else \ - OBJ##_##CMD (parse<OBJ##_##CMD##_options> (co, args), args); \ + NP##CMD (parse<NP##CMD##_options> (co, args), args); \ \ break; \ } + // High-level commands. + // +#define COMMAND(CMD) COMMAND_IMPL(, "", CMD) + + COMMAND(build); + // pkg-* commands // -#define PKG_COMMAND(CMD) ANY_COMMAND(pkg, CMD) +#define PKG_COMMAND(CMD) COMMAND_IMPL(pkg_, "pkg-", CMD) PKG_COMMAND (verify); PKG_COMMAND (status); @@ -192,13 +200,13 @@ try // cfg-* commands // -#define CFG_COMMAND(CMD) ANY_COMMAND(cfg, CMD) +#define CFG_COMMAND(CMD) COMMAND_IMPL(cfg_, "cfg-", CMD) CFG_COMMAND (create); // rep-* commands // -#define REP_COMMAND(CMD) ANY_COMMAND(rep, CMD) +#define REP_COMMAND(CMD) COMMAND_IMPL(rep_, "rep-", CMD) REP_COMMAND (add); REP_COMMAND (fetch); diff --git a/bpkg/build b/bpkg/build new file mode 100644 index 0000000..cc89599 --- /dev/null +++ b/bpkg/build @@ -0,0 +1,17 @@ +// file : bpkg/build -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BPKG_BUILD +#define BPKG_BUILD + +#include <bpkg/types> +#include <bpkg/build-options> + +namespace bpkg +{ + void + build (const build_options&, cli::scanner& args); +} + +#endif // BPKG_BUILD diff --git a/bpkg/build-options.cli b/bpkg/build-options.cli new file mode 100644 index 0000000..9782f95 --- /dev/null +++ b/bpkg/build-options.cli @@ -0,0 +1,33 @@ +// file : bpkg/build-options.cli +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +include <bpkg/configuration-options.cli>; + +/* +"\section=1" +"\name=bpkg-build" + +"\h{SYNOPSIS} + +bpkg build [<options>] (<pkg>[/<ver>]|<file>|<dir>)..." + +"\h{DESCRIPTION} + +The \cb{build} command builds one or more packages including all their +prerequisites. Each package can be specified as just the name (<pkg>) +with optional package version (<ver>) in which case the package will +be automatically fetched from one of the configuration's source +repositories (see \cb{rep-add} and \cb{rep-fetch}). Alternatively, +the package can be specified as either the path to the package +source archive (<file>) or package source directory (<dir>). See +\cb{pkg-fetch} and \cb{pkg-unpack} for more information on the +semantics of specifying the package as an archive or directory. +*/ + +namespace bpkg +{ + class build_options: configuration_options + { + }; +} diff --git a/bpkg/build.cxx b/bpkg/build.cxx new file mode 100644 index 0000000..361cd9a --- /dev/null +++ b/bpkg/build.cxx @@ -0,0 +1,229 @@ +// file : bpkg/build.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <bpkg/build> + +#include <vector> + +#include <bpkg/types> +#include <bpkg/package> +#include <bpkg/package-odb> +#include <bpkg/utility> +#include <bpkg/database> +#include <bpkg/diagnostics> +#include <bpkg/manifest-utility> + +#include <bpkg/pkg-verify> + +using namespace std; +using namespace butl; + +namespace bpkg +{ + struct selected_package // @@ Swap names. + { + shared_ptr<available_package> ap; // Note: might be transient. + + optional<path> archive; + optional<dir_path> directory; + }; + + using packages = vector<selected_package>; + + void + build (const build_options& o, cli::scanner& args) + { + tracer trace ("build"); + + const dir_path& c (o.directory ()); + level4 ([&]{trace << "configuration: " << c;}); + + if (!args.more ()) + fail << "package name argument expected" << + info << "run 'bpkg help build' for more information"; + + database db (open (c, trace)); + transaction t (db.begin ()); + session s; + + shared_ptr<repository> root (db.load<repository> ("")); + + // Start assembling the list of packages we will need to build + // by first collecting the user's selection. + // + packages pkgs; + + while (args.more ()) + { + const char* s (args.next ()); + + selected_package pkg; + + // Reduce all the potential variations (archive, directory, + // package, package version) to the single available_package + // object. + // + string n; + version v; + shared_ptr<available_package>& ap (pkg.ap); + + // Is this a package archive? + // + try + { + path a (s); + if (exists (a)) + { + package_manifest m (pkg_verify (o, a, false)); + + // This is a package archive (note that we shouldn't throw + // failed from here on). + // + level4 ([&]{trace << "archive " << a;}); + n = m.name; + v = m.version; + ap = make_shared<available_package> (move (m)); + pkg.archive = move (a); + } + } + catch (const invalid_path&) + { + // Not a valid path so cannot be an archive. + } + catch (const failed&) + { + // Not a valid package archive. + } + + // Is this a package directory? + // + try + { + dir_path d (s); + if (exists (d)) + { + package_manifest m (pkg_verify (d, false)); + + // This is a package directory (note that we shouldn't throw + // failed from here on). + // + level4 ([&]{trace << "directory " << d;}); + n = m.name; + v = m.version; + ap = make_shared<available_package> (move (m)); + pkg.directory = move (d); + } + } + catch (const invalid_path&) + { + // Not a valid path so cannot be an archive. + } + catch (const failed&) + { + // Not a valid package archive. + } + + // Then it got to be a package name with optional version. + // + if (ap == nullptr) + { + n = parse_package_name (s); + v = parse_package_version (s); + level4 ([&]{trace << "package " << n << "; version " << v;}); + + // Find the available package, if any. + // + using query = query<available_package>; + + query q (query::id.name == n); + + // Either get the user-specified version or the latest. + // + if (!v.empty ()) + q = q && query::id.version == v; + else + q += order_by_version_desc (query::id.version); + + // Only consider packages that are in repositories that were + // explicitly added to the configuration and their complements, + // recursively. + // + ap = filter_one (root, db.query<available_package> (q)); + } + + // Load the package that may have already been selected and + // figure out what exactly we need to do here. The end goal + // is the available_package object corresponding to the actual + // package that we will be building (which may or may not be + // the same as the selected package). + // + shared_ptr<package> p (db.find<package> (n)); + + if (p != nullptr && p->state == state::broken) + fail << "unable to build broken package " << n << + info << "use 'pkg-purge --force' to remove"; + + // If the user asked for a specific version, then that's what + // we should be building. + // + if (!v.empty ()) + { + for (;;) + { + if (ap != nullptr) // Must be that version, see above. + break; + + // Otherwise, our only chance is that the already selected + // object is that exact version. + // + if (p != nullptr && p->version == v) + break; // Set ap to p below. + + fail << "unknown package " << n << " " << v; + } + } + // + // No explicit version was specified by the user. + // + else + { + if (ap != nullptr) + { + // See if what we already have is newer. + // + if (p != nullptr && ap->id.version < p->version) + ap = nullptr; // Set ap to p below. + } + else + { + if (p == nullptr) + fail << "unknown package " << n; + + // Set ap to p below. + } + } + + // If the available_package object is still NULL, then it means + // we need to get one corresponding to the selected package. + // + if (ap == nullptr) + { + assert (p != nullptr); + + // The package is in at least fetched state, which means we + // can get its manifest. + // + ap = make_shared<available_package> ( + p->state == state::fetched + ? pkg_verify (o, *p->archive) + : pkg_verify (*p->src_root)); + } + + level4 ([&]{trace << "building " << ap->id.name << " " << ap->version;}); + pkgs.push_back (move (pkg)); + } + + t.commit (); + } +} diff --git a/bpkg/buildfile b/bpkg/buildfile index 54226f3..e9f00f2 100644 --- a/bpkg/buildfile +++ b/bpkg/buildfile @@ -14,7 +14,8 @@ exe{bpkg}: cxx{fetch package package-odb manifest-utility database \ cli.cxx{common-options} cxx{types-parsers} \ cxx{bpkg} cli.cxx{bpkg-options} \ cxx{help} cli.cxx{help-options} \ - cli.cxx{pkg-common-options} \ + cli.cxx{configuration-options} \ + cxx{build} cli.cxx{build-options} \ cxx{pkg-command} \ cxx{pkg-verify} cli.cxx{pkg-verify-options} \ cxx{pkg-status} cli.cxx{pkg-status-options} \ @@ -48,11 +49,15 @@ cli.cxx{bpkg-options}: cli.options += --short-usage cli.cxx{help-options}: cli{help-options} cli.cxx{help-options}: cli.options += --exclude-base -# pkg-* +cli.cxx{configuration-options}: cli{configuration-options} +cli.cxx{configuration-options}: cli.options += --exclude-base + +# # -cli.cxx{pkg-common-options}: cli{pkg-common-options} -cli.cxx{pkg-common-options}: cli.options += --exclude-base +cli.cxx{build-options}: cli{build-options} +# pkg-* +# cli.cxx{pkg-status-options}: cli{pkg-status-options} cli.cxx{pkg-fetch-options}: cli{pkg-fetch-options} cli.cxx{pkg-unpack-options}: cli{pkg-unpack-options} @@ -72,11 +77,8 @@ cli.cxx{cfg-create-options}: cli.options += --exclude-base # rep-* # -cli.cxx{rep-add-options}: cli{rep-add-options} -cli.cxx{rep-add-options}: cli.options += --exclude-base - +cli.cxx{rep-add-options}: cli{rep-add-options} cli.cxx{rep-fetch-options}: cli{rep-fetch-options} -cli.cxx{rep-fetch-options}: cli.options += --exclude-base cli.cxx{rep-info-options}: cli{rep-info-options} cli.cxx{rep-info-options}: cli.options += --exclude-base diff --git a/bpkg/pkg-common-options.cli b/bpkg/configuration-options.cli index d7097ff..712c7da 100644 --- a/bpkg/pkg-common-options.cli +++ b/bpkg/configuration-options.cli @@ -1,4 +1,4 @@ -// file : bpkg/pkg-common-options.cli +// file : bpkg/configuration-options.cli // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file @@ -6,7 +6,9 @@ include <bpkg/common-options.cli>; namespace bpkg { - class pkg_common_options: common_options + // Common options for commands that operate on a configuration. + // + class configuration_options: common_options { dir_path --directory|-d (".") { diff --git a/bpkg/database b/bpkg/database index 7ff3129..d1419d4 100644 --- a/bpkg/database +++ b/bpkg/database @@ -8,10 +8,10 @@ #include <utility> // forward() #include <type_traits> // remove_reference +#include <odb/query.hxx> #include <odb/result.hxx> #include <odb/session.hxx> -#include <odb/sqlite/query.hxx> #include <odb/sqlite/database.hxx> #include <bpkg/types> @@ -19,10 +19,10 @@ namespace bpkg { + using odb::query; using odb::result; using odb::session; - using odb::sqlite::query; using odb::sqlite::database; using odb::sqlite::transaction; diff --git a/bpkg/manifest-utility b/bpkg/manifest-utility index f9766c7..4d127f4 100644 --- a/bpkg/manifest-utility +++ b/bpkg/manifest-utility @@ -12,8 +12,16 @@ namespace bpkg { + // Extract name and version components from <name>[/<version>]. + // + string + parse_package_name (const char*); + + version + parse_package_version (const char*); + version - parse_version (const char*); + parse_version (const char*); //@@ TMP // First use the passed location as is. If the result is relative, // then assume this is a relative path to the repository directory diff --git a/bpkg/manifest-utility.cxx b/bpkg/manifest-utility.cxx index 76c1957..e44936f 100644 --- a/bpkg/manifest-utility.cxx +++ b/bpkg/manifest-utility.cxx @@ -12,6 +12,45 @@ using namespace std; namespace bpkg { + string + parse_package_name (const char* s) + { + using traits = string::traits_type; + + size_t n (traits::length (s)); + + if (const char* p = traits::find (s, n, '/')) + n = static_cast<size_t> (p - s); + + if (n == 0) + fail << "empty package name in '" << s << "'"; + + return string (s, n); + } + + version + parse_package_version (const char* s) + { + using traits = string::traits_type; + + if (const char* p = traits::find (s, traits::length (s), '/')) + { + if (*++p == '\0') + fail << "empty package version in '" << s << "'"; + + try + { + return version (p); + } + catch (const invalid_argument& e) + { + fail << "invalid package version '" << p << "': " << e.what (); + } + } + + return version (); + } + version parse_version (const char* s) try diff --git a/bpkg/package b/bpkg/package index 9b616f6..5967448 100644 --- a/bpkg/package +++ b/bpkg/package @@ -222,11 +222,11 @@ namespace bpkg // List of repositories to which this package version belongs (yes, // in our world, it can be in multiple, unrelated repositories). // - std::vector<package_location> locations; + std::vector<package_location> locations; //@@ Map? public: - available_package (string name, bpkg::version v) - : id (move (name), v), version (move (v)) {} + available_package (package_manifest&& m) + : id (move (m.name), m.version), version (move (m.version)) {} // Database mapping. // @@ -251,6 +251,16 @@ namespace bpkg operator size_t () const {return result;} }; + // Only return packages that are in the specified repository or its + // complements, recursively. While you could maybe come up with a + // (barely comprehensible) view/query to achieve this, doing it on + // the "client side" is definitely more straightforward. + // + std::vector<shared_ptr<available_package>> + filter (const shared_ptr<repository>&, odb::result<available_package>&&); + + shared_ptr<available_package> + filter_one (const shared_ptr<repository>&, odb::result<available_package>&&); // state // diff --git a/bpkg/package.cxx b/bpkg/package.cxx index ad54e51..c6f5dcf 100644 --- a/bpkg/package.cxx +++ b/bpkg/package.cxx @@ -3,9 +3,12 @@ // license : MIT; see accompanying LICENSE file #include <bpkg/package> +#include <bpkg/package-odb> #include <stdexcept> // invalid_argument +#include <bpkg/database> + using namespace std; namespace bpkg @@ -34,6 +37,69 @@ namespace bpkg return xv.revision < yv.revision; } + // available_package + // + + // Check if the package is available from the specified repository or + // one of its complements, recursively. Return the first repository + // that contains the package or NULL if none are. + // + static shared_ptr<repository> + find (const shared_ptr<repository>& r, + const shared_ptr<available_package>& ap) + { + const auto& cs (r->complements); + + for (const package_location& pl: ap->locations) + { + // First check the repository itself. + // + if (pl.repository.object_id () == r->name) + return r; + + // Then check all the complements without loading them. + // + if (cs.find (pl.repository) != cs.end ()) + return pl.repository.load (); + + // Finally, load the complements and check them recursively. + // + for (const lazy_shared_ptr<repository>& cr: cs) + { + if (shared_ptr<repository> r = find (cr.load (), ap)) + return r; + } + } + + return nullptr; + } + + vector<shared_ptr<available_package>> + filter (const shared_ptr<repository>& r, result<available_package>&& apr) + { + vector<shared_ptr<available_package>> aps; + + for (shared_ptr<available_package> ap: pointer_result (apr)) + { + if (find (r, ap) != nullptr) + aps.push_back (move (ap)); + } + + return aps; + } + + shared_ptr<available_package> + filter_one (const shared_ptr<repository>& r, result<available_package>&& apr) + { + for (shared_ptr<available_package> ap: pointer_result (apr)) + { + if (find (r, ap) != nullptr) + return ap; + } + + return nullptr; + } + // state // string diff --git a/bpkg/pkg-clean-options.cli b/bpkg/pkg-clean-options.cli index c9d9bca..bc8b0eb 100644 --- a/bpkg/pkg-clean-options.cli +++ b/bpkg/pkg-clean-options.cli @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -include <bpkg/pkg-common-options.cli>; +include <bpkg/configuration-options.cli>; /* "\section=1" @@ -21,7 +21,7 @@ do much more than run (\cb{b clean})." namespace bpkg { - class pkg_clean_options: pkg_common_options + class pkg_clean_options: configuration_options { }; } diff --git a/bpkg/pkg-command b/bpkg/pkg-command index 225a112..0628a06 100644 --- a/bpkg/pkg-command +++ b/bpkg/pkg-command @@ -6,7 +6,7 @@ #define BPKG_PKG_COMMAND #include <bpkg/types> -#include <bpkg/pkg-common-options> +#include <bpkg/configuration-options> namespace bpkg { @@ -14,7 +14,7 @@ namespace bpkg // void pkg_command (const string& cmd, // Without the 'pkg-' prefix. - const pkg_common_options&, + const configuration_options&, cli::scanner& args); } diff --git a/bpkg/pkg-command.cxx b/bpkg/pkg-command.cxx index b4e2893..fc8deb9 100644 --- a/bpkg/pkg-command.cxx +++ b/bpkg/pkg-command.cxx @@ -18,7 +18,7 @@ namespace bpkg { void pkg_command (const string& cmd, - const pkg_common_options& o, + const configuration_options& o, cli::scanner& args) { tracer trace ("pkg_command"); diff --git a/bpkg/pkg-configure-options.cli b/bpkg/pkg-configure-options.cli index 85e4fa9..f7b8f9f 100644 --- a/bpkg/pkg-configure-options.cli +++ b/bpkg/pkg-configure-options.cli @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -include <bpkg/pkg-common-options.cli>; +include <bpkg/configuration-options.cli>; /* "\section=1" @@ -24,7 +24,7 @@ after the package name." namespace bpkg { - class pkg_configure_options: pkg_common_options + class pkg_configure_options: configuration_options { }; } diff --git a/bpkg/pkg-disfigure-options.cli b/bpkg/pkg-disfigure-options.cli index 9ffe20b..2fe045e 100644 --- a/bpkg/pkg-disfigure-options.cli +++ b/bpkg/pkg-disfigure-options.cli @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -include <bpkg/pkg-common-options.cli>; +include <bpkg/configuration-options.cli>; /* "\section=1" @@ -20,7 +20,7 @@ The \cb{pkg-disfigure} command disfigures the previously configured namespace bpkg { - class pkg_disfigure_options: pkg_common_options + class pkg_disfigure_options: configuration_options { }; } diff --git a/bpkg/pkg-fetch-options.cli b/bpkg/pkg-fetch-options.cli index 54a2f50..def4b09 100644 --- a/bpkg/pkg-fetch-options.cli +++ b/bpkg/pkg-fetch-options.cli @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -include <bpkg/pkg-common-options.cli>; +include <bpkg/configuration-options.cli>; /* "\section=1" @@ -27,7 +27,7 @@ attempt to remove the archive when the package is purged with the namespace bpkg { - class pkg_fetch_options: pkg_common_options + class pkg_fetch_options: configuration_options { bool --existing|-e { diff --git a/bpkg/pkg-purge-options.cli b/bpkg/pkg-purge-options.cli index 2341b74..f5fef62 100644 --- a/bpkg/pkg-purge-options.cli +++ b/bpkg/pkg-purge-options.cli @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -include <bpkg/pkg-common-options.cli>; +include <bpkg/configuration-options.cli>; /* "\section=1" @@ -26,7 +26,7 @@ this mode)." namespace bpkg { - class pkg_purge_options: pkg_common_options + class pkg_purge_options: configuration_options { bool --keep|-k { diff --git a/bpkg/pkg-status-options.cli b/bpkg/pkg-status-options.cli index b094e34..5f1c05b 100644 --- a/bpkg/pkg-status-options.cli +++ b/bpkg/pkg-status-options.cli @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -include <bpkg/pkg-common-options.cli>; +include <bpkg/configuration-options.cli>; /* "\section=1" @@ -22,7 +22,7 @@ Note that the status is written to \cb{STDOUT}, not \cb{STDERR}. namespace bpkg { - class pkg_status_options: pkg_common_options + class pkg_status_options: configuration_options { }; } diff --git a/bpkg/pkg-status.cxx b/bpkg/pkg-status.cxx index dbd2bd0..196106a 100644 --- a/bpkg/pkg-status.cxx +++ b/bpkg/pkg-status.cxx @@ -84,45 +84,9 @@ namespace bpkg // Only consider packages that are in repositories that were // explicitly added to the configuration and their complements, - // transitively. While we could maybe come up with a (barely - // comprehensible) view/query to achieve this, doing it on the - // "client side" is definitely more straightforward. + // recursively. // - shared_ptr<repository> root (db.load<repository> ("")); - - for (shared_ptr<available_package> ap: - pointer_result (db.query<available_package> (q))) - { - function<bool (const shared_ptr<repository>&)> find = - [&ap, &find](const shared_ptr<repository>& r) -> bool - { - const auto& cs (r->complements); - - for (const package_location& pl: ap->locations) - { - // First check all the complements without loading them. - // - if (cs.find (pl.repository) != cs.end ()) - return true; - - // If not found, then load the complements and check them - // recursively. - // - for (lazy_shared_ptr<repository> cr: cs) - { - if (find (cr.load ())) - return true; - } - } - - return false; - }; - - level4 ([&]{trace << "available " << ap->version;}); - - if (find (root)) - aps.push_back (ap); - } + aps = filter (db.load<repository> (""), db.query<available_package> (q)); } t.commit (); diff --git a/bpkg/pkg-unpack-options.cli b/bpkg/pkg-unpack-options.cli index 06fda13..c9101a9 100644 --- a/bpkg/pkg-unpack-options.cli +++ b/bpkg/pkg-unpack-options.cli @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -include <bpkg/pkg-common-options.cli>; +include <bpkg/configuration-options.cli>; /* "\section=1" @@ -27,7 +27,7 @@ command." namespace bpkg { - class pkg_unpack_options: pkg_common_options + class pkg_unpack_options: configuration_options { bool --existing|-e { diff --git a/bpkg/pkg-update-options.cli b/bpkg/pkg-update-options.cli index d259ce3..8ad9c02 100644 --- a/bpkg/pkg-update-options.cli +++ b/bpkg/pkg-update-options.cli @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -include <bpkg/pkg-common-options.cli>; +include <bpkg/configuration-options.cli>; /* "\section=1" @@ -21,7 +21,7 @@ do much more than run (\cb{b update})." namespace bpkg { - class pkg_update_options: pkg_common_options + class pkg_update_options: configuration_options { }; } diff --git a/bpkg/rep-add-options.cli b/bpkg/rep-add-options.cli index f798692..fc6cbf3 100644 --- a/bpkg/rep-add-options.cli +++ b/bpkg/rep-add-options.cli @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -include <bpkg/common-options.cli>; +include <bpkg/configuration-options.cli>; /* "\section=1" @@ -23,13 +23,7 @@ packages list for the newly added repository. To do that, use the namespace bpkg { - class rep_add_options: common_options + class rep_add_options: configuration_options { - dir_path --directory|-d (".") - { - "<dir>", - "Assume configuration is in <dir> rather than in the current working - directory." - }; }; } diff --git a/bpkg/rep-fetch-options.cli b/bpkg/rep-fetch-options.cli index 0e43eda..0cba10d 100644 --- a/bpkg/rep-fetch-options.cli +++ b/bpkg/rep-fetch-options.cli @@ -2,7 +2,7 @@ // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -include <bpkg/common-options.cli>; +include <bpkg/configuration-options.cli>; /* "\section=1" @@ -21,13 +21,7 @@ and available package lists for all the repositories that were added namespace bpkg { - class rep_fetch_options: common_options + class rep_fetch_options: configuration_options { - dir_path --directory|-d (".") - { - "<dir>", - "Assume configuration is in <dir> rather than in the current working - directory." - }; }; } diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx index 1823909..f091f24 100644 --- a/bpkg/rep-fetch.cxx +++ b/bpkg/rep-fetch.cxx @@ -81,7 +81,7 @@ namespace bpkg if (pr == nullptr) { - pr.reset (new repository (move (rm.location))); + pr = make_shared<repository> (move (rm.location)); db.persist (pr); // Enter into session, important if recursive. } @@ -148,7 +148,7 @@ namespace bpkg if (p == nullptr) { - p.reset (new available_package (move (pm.name), move (pm.version))); + p = make_shared<available_package> (move (pm)); persist = true; } diff --git a/bpkg/utility b/bpkg/utility index 02d447c..b07d502 100644 --- a/bpkg/utility +++ b/bpkg/utility @@ -5,6 +5,7 @@ #ifndef BPKG_UTILITY #define BPKG_UTILITY +#include <memory> // make_shared() #include <cassert> #include <utility> // move() #include <exception> // uncaught_exception () @@ -16,6 +17,7 @@ namespace bpkg { using std::move; + using std::make_shared; // Filesystem. // |