From e59343b3267e82aff33a8f73ab82b51345913c06 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sat, 10 Nov 2018 22:43:09 +0300 Subject: Add support for vars grouping for package commands --- bpkg/auth.cxx | 5 ++- bpkg/bpkg.cxx | 18 ++++++----- bpkg/diagnostics.cxx | 1 - bpkg/fetch-git.cxx | 3 ++ bpkg/pkg-build.cli | 5 +-- bpkg/pkg-build.cxx | 26 +++++++-------- bpkg/pkg-clean.cli | 15 +++++---- bpkg/pkg-clean.hxx | 2 +- bpkg/pkg-command.cxx | 87 +++++++++++++++++++++++++++++++++----------------- bpkg/pkg-command.hxx | 2 +- bpkg/pkg-configure.cli | 4 +-- bpkg/pkg-configure.cxx | 11 ++++++- bpkg/pkg-install.cli | 21 ++++++------ bpkg/pkg-install.hxx | 2 +- bpkg/pkg-test.cli | 15 +++++---- bpkg/pkg-test.hxx | 2 +- bpkg/pkg-uninstall.cli | 16 +++++----- bpkg/pkg-uninstall.hxx | 2 +- bpkg/pkg-update.cli | 15 +++++---- bpkg/pkg-update.hxx | 2 +- bpkg/utility.hxx | 4 +++ 21 files changed, 153 insertions(+), 105 deletions(-) (limited to 'bpkg') diff --git a/bpkg/auth.cxx b/bpkg/auth.cxx index 787a705..7cdf39e 100644 --- a/bpkg/auth.cxx +++ b/bpkg/auth.cxx @@ -5,9 +5,8 @@ #include #include -#include // numeric_limits -#include // strlen(), strcmp() -#include // ostreambuf_iterator +#include // numeric_limits +#include // ostreambuf_iterator #include #include diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx index 018ca7a..00f78cf 100644 --- a/bpkg/bpkg.cxx +++ b/bpkg/bpkg.cxx @@ -6,7 +6,6 @@ # include // signal() #endif -#include // strcmp() #include #include @@ -321,20 +320,23 @@ try // #define PKG_COMMAND(CMD, SEP) COMMAND_IMPL(pkg_, "pkg-", CMD, SEP, true) - PKG_COMMAND (build, true); // Keeps the '--' separator in args. + // These commands need the '--' separator to be kept in args. + // + PKG_COMMAND (build, true); + PKG_COMMAND (clean, true); + PKG_COMMAND (configure, true); + PKG_COMMAND (install, true); + PKG_COMMAND (test, true); + PKG_COMMAND (uninstall, true); + PKG_COMMAND (update, true); + PKG_COMMAND (checkout, false); - PKG_COMMAND (clean, false); - PKG_COMMAND (configure, false); PKG_COMMAND (disfigure, false); PKG_COMMAND (drop, false); PKG_COMMAND (fetch, false); - PKG_COMMAND (install, false); PKG_COMMAND (purge, false); PKG_COMMAND (status, false); - PKG_COMMAND (test, false); - PKG_COMMAND (uninstall, false); PKG_COMMAND (unpack, false); - PKG_COMMAND (update, false); PKG_COMMAND (verify, false); // rep-* commands diff --git a/bpkg/diagnostics.cxx b/bpkg/diagnostics.cxx index 400b352..1048e9b 100644 --- a/bpkg/diagnostics.cxx +++ b/bpkg/diagnostics.cxx @@ -4,7 +4,6 @@ #include -#include // strchr() #include #include diff --git a/bpkg/fetch-git.cxx b/bpkg/fetch-git.cxx index c2e1b36..ff5432e 100644 --- a/bpkg/fetch-git.cxx +++ b/bpkg/fetch-git.cxx @@ -286,6 +286,9 @@ namespace bpkg // command that we use to clone submodules. So to truncate local submodule // histories we will use the file URL notation for local repositories. // + // @@ An update: we don't use the 'submodule--helper clone' command anymore. + // Should we switch to the local path notation for the file:// protocol? + // static string to_git_url (const repository_url& url) { diff --git a/bpkg/pkg-build.cli b/bpkg/pkg-build.cli index f5ece04..9aaf84e 100644 --- a/bpkg/pkg-build.cli +++ b/bpkg/pkg-build.cli @@ -22,7 +22,8 @@ namespace bpkg \c{\b{bpkg pkg-build}|\b{build} [] [\b{--upgrade}|\b{-u} | \b{--patch}|\b{-p}]\n \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [... \b{--}] ...\n - \b{bpkg pkg-build}|\b{build} [] \ \b{--upgrade}|\b{-u} | \b{--patch}|\b{-p}} + \b{bpkg pkg-build}|\b{build} [] \ \b{--upgrade}|\b{-u} | \b{--patch}|\b{-p}\n + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [... \b{--}]} \c{ = [](([\b{:}][\b{/}])\b{,}...[\b{@}] | \n \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\b{@}] \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | \n @@ -104,7 +105,7 @@ namespace bpkg specified before packages () and should be separated with \cb{--}. Such variables are effective only when configuring and only for packages that were explicitly specified on the command line (they can - also be specified to apply only to specific packages using the argument + also be specified to only apply to specific packages using the argument grouping mechanism discussed below). See \l{bpkg-pkg-configure(1)} for more information on configuration variables. diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index 27e509b..655f0de 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -7,7 +7,7 @@ #include #include #include -#include // strlen(), strcmp(), strchr() +#include // strlen() #include // cout #include // find_if() @@ -2297,14 +2297,14 @@ namespace bpkg vector specs; { - // Parse the global configuration variables until we reach the "--" + // Read the common configuration variables until we reach the "--" // separator, eos or an argument. Non-empty variables list should always // be terminated with the "--". Furthermore, argument list that contains // anything that looks like a variable (has the '=' character) should be // preceded with "--". // - strings config_vars; - bool vars_separated (false); + strings cvars; + bool sep (false); // Seen '--'. while (args.more ()) { @@ -2314,7 +2314,7 @@ namespace bpkg // if (strcmp (a, "--") == 0) { - vars_separated = true; + sep = true; args.next (); break; } @@ -2333,10 +2333,10 @@ namespace bpkg fail << "unexpected options group for configuration variable '" << v << "'"; - config_vars.push_back (move (v)); + cvars.push_back (move (v)); } - if (!config_vars.empty () && !vars_separated) + if (!cvars.empty () && !sep) fail << "configuration variables must be separated from packages " << "with '--'"; @@ -2351,7 +2351,7 @@ namespace bpkg // Make sure the argument can not be misinterpreted as a configuration // variable. // - if (a.find ('=') != string::npos && !vars_separated) + if (a.find ('=') != string::npos && !sep) fail << "unexpected configuration variable '" << a << "'" << info << "use the '--' separator to treat it as a package"; @@ -2365,10 +2365,10 @@ namespace bpkg cli::scanner& ag (args.group ()); po.parse (ag, cli::unknown_mode::fail, cli::unknown_mode::stop); - // Merge the global and package-specific configuration variables - // (globals go first). + // Merge the common and package-specific configuration variables + // (commons go first). // - ps.config_vars = config_vars; + ps.config_vars = cvars; while (ag.more ()) { @@ -4260,8 +4260,8 @@ namespace bpkg { if (*p.action == build_package::drop) { - // Note that the selected system package has already gone being - // disfigured (see above). + // Note that the selected system package is gone once disfigured + // (see above). // if (sp != nullptr) { diff --git a/bpkg/pkg-clean.cli b/bpkg/pkg-clean.cli index 9e40e89..8d57845 100644 --- a/bpkg/pkg-clean.cli +++ b/bpkg/pkg-clean.cli @@ -15,21 +15,22 @@ namespace bpkg "\h|SYNOPSIS| - \c{\b{bpkg pkg-clean}|\b{clean} [] [] ( [])...\n + \c{\b{bpkg pkg-clean}|\b{clean} [] [] ...\n \b{bpkg pkg-clean}|\b{clean} [] [] \b{--all}|\b{-a}} \h|DESCRIPTION| The \cb{pkg-clean} command cleans the specified packages (the first form) or all the held packages (the second form, see \l{bpkg-pkg-status(1)}). - Underneath, this command doesn't do much more than run \cb{b clean}. - - In the first form the specified packages must have been previously + Underneath, this command doesn't do much more than run \cb{b clean}. In + the first form the specified packages must have been previously configured with \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}. + Additional command line variables (, normally \cb{config.*}) can be - passed to the build system by either specifying them before the packages, - in which case they apply to the whole configuration, or after a specific - package, in which case they apply only to this package." + passed to the build system. Such variables apply to all the specified + packages but can also be specified to only apply to specific packages + using the argument grouping mechanism (see \l{bpkg-argument-grouping(1)} + for details)." } class pkg_clean_options: configuration_options diff --git a/bpkg/pkg-clean.hxx b/bpkg/pkg-clean.hxx index bfea24e..1a930e6 100644 --- a/bpkg/pkg-clean.hxx +++ b/bpkg/pkg-clean.hxx @@ -14,7 +14,7 @@ namespace bpkg { inline int - pkg_clean (const pkg_clean_options& o, cli::scanner& args) + pkg_clean (const pkg_clean_options& o, cli::group_scanner& args) { return pkg_command ("clean", o, diff --git a/bpkg/pkg-command.cxx b/bpkg/pkg-command.cxx index 6b82c29..c66c8da 100644 --- a/bpkg/pkg-command.cxx +++ b/bpkg/pkg-command.cxx @@ -129,32 +129,67 @@ namespace bpkg bool recursive, bool immediate, bool all, - cli::scanner& args) + cli::group_scanner& args) { tracer trace ("pkg_command"); const dir_path& c (o.directory ()); l4 ([&]{trace << "configuration: " << c;}); - // First read the common variables. + // First sort arguments into the package names and variables. // - // @@ TODO: redo using argument groups. - // - auto read_vars = [&args](strings& v) + strings cvars; + bool sep (false); // Seen '--'. + + struct pkg_arg + { + package_name name; + strings vars; + }; + vector pkg_args; + + while (args.more ()) { - for (; args.more (); args.next ()) + string a (args.next ()); + + // If we see the "--" separator, then we are done parsing common + // variables. + // + if (!sep && a == "--") { - string a (args.peek ()); + sep = true; + continue; + } - if (a.find ('=') == string::npos) - break; + if (!sep && a.find ('=') != string::npos) + { + // Make sure this is not a (misspelled) package name with an option + // group. + // + if (args.group ().more ()) + fail << "unexpected options group for variable '" << a << "'"; - v.push_back (move (a)); + cvars.push_back (move (a)); } - }; + else + { + package_name n (parse_package_name (a, false /* allow_version */)); - strings cvars; - read_vars (cvars); + // Read package-specific variables. + // + strings vars; + for (cli::scanner& ag (args.group ()); ag.more (); ) + { + string a (ag.next ()); + if (a.find ('=') == string::npos) + fail << "unexpected group argument '" << a << "'"; + + vars.push_back (move (a)); + } + + pkg_args.push_back (pkg_arg {move (n), move (vars)}); + } + } // Check that options and arguments are consistent. // @@ -168,10 +203,10 @@ namespace bpkg dr << fail << "both --immediate|-i and --recursive|-r specified"; else if (all) { - if (args.more ()) + if (!pkg_args.empty ()) dr << fail << "both --all|-a and package argument specified"; } - else if (!args.more ()) + else if (pkg_args.empty ()) dr << fail << "package name argument expected"; if (!dr.empty ()) @@ -221,32 +256,24 @@ namespace bpkg } else { - while (args.more ()) + for (auto& a: pkg_args) { - package_name n (parse_package_name (args.next (), - false /* allow_version */)); - - shared_ptr p (db.find (n)); + shared_ptr p (db.find (a.name)); if (p == nullptr) - fail << "package " << n << " does not exist in configuration " - << c; + fail << "package " << a.name << " does not exist in " + << "configuration " << c; if (p->state != package_state::configured) - fail << "package " << n << " is " << p->state << + fail << "package " << a.name << " is " << p->state << info << "expected it to be configured"; if (p->substate == package_substate::system) - fail << "cannot " << cmd << " system package " << n; + fail << "cannot " << cmd << " system package " << a.name; l4 ([&]{trace << *p;}); - // Read package-specific variables. - // - strings vars; - read_vars (vars); - - add (p, move (vars)); + add (p, move (a.vars)); } } diff --git a/bpkg/pkg-command.hxx b/bpkg/pkg-command.hxx index 9b56142..8991263 100644 --- a/bpkg/pkg-command.hxx +++ b/bpkg/pkg-command.hxx @@ -28,7 +28,7 @@ namespace bpkg bool recursive, bool immediate, bool all, - cli::scanner& args); + cli::group_scanner& args); struct pkg_command_vars { diff --git a/bpkg/pkg-configure.cli b/bpkg/pkg-configure.cli index fd4453d..bc7c3de 100644 --- a/bpkg/pkg-configure.cli +++ b/bpkg/pkg-configure.cli @@ -25,8 +25,8 @@ namespace bpkg A source code package inherits the common \cb{build2} configuration values that were specified when creating the configuration - (\l{bpkg-cfg-create(1)}). Additional, package-specific configuration - variables can be specified before the package name. + (\l{bpkg-cfg-create(1)}). Additional package-specific configuration + variables can be passed to \cb{pkg-configure} (). A system package is specified using the \c{\b{sys:}[/]} syntax. If the package version () is not specified, then it is diff --git a/bpkg/pkg-configure.cxx b/bpkg/pkg-configure.cxx index 6db60d4..d63b010 100644 --- a/bpkg/pkg-configure.cxx +++ b/bpkg/pkg-configure.cxx @@ -238,12 +238,21 @@ namespace bpkg // string n; strings vars; + bool sep (false); // Seen '--'. while (args.more ()) { string a (args.next ()); - if (a.find ('=') != string::npos) + // If we see the "--" separator, then we are done parsing variables. + // + if (!sep && a == "--") + { + sep = true; + continue; + } + + if (!sep && a.find ('=') != string::npos) vars.push_back (move (a)); else if (n.empty ()) n = move (a); diff --git a/bpkg/pkg-install.cli b/bpkg/pkg-install.cli index a44522e..2b31763 100644 --- a/bpkg/pkg-install.cli +++ b/bpkg/pkg-install.cli @@ -15,7 +15,7 @@ namespace bpkg "\h|SYNOPSIS| - \c{\b{bpkg pkg-install}|\b{install} [] [] ( [])...\n + \c{\b{bpkg pkg-install}|\b{install} [] [] ...\n \b{bpkg pkg-install}|\b{install} [] [] \b{--all}|\b{-a}} \h|DESCRIPTION| @@ -25,20 +25,21 @@ namespace bpkg Additionally, immediate or all dependencies of these packages can be also installed by specifying the \c{\b{--immediate}|\b{-i}} or \c{\b{--recursive}|\b{-r}} options, respectively. Underneath, this - command doesn't do much more than run \cb{b install}. + command doesn't do much more than run \cb{b install}. In the first form + the specified packages must have been previously configured with + \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}. - In the first form the specified packages must have been previously - configured with \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}. Additional command line variables (, normally \cb{config.*}) can be - passed to the build system by either specifying them before the packages, - in which case they apply to the whole configuration, or after a specific - package, in which case they apply only to this package. In particular, - this mechanism can be used to specify the installation directory, for - example: + passed to the build system. Such variables apply to all the specified + packages but can also be specified to only apply to specific packages + using the argument grouping mechanism (see \l{bpkg-argument-grouping(1)} + for details). In particular, this mechanism can be used to specify the + installation directory, for example: \ bpkg install config.install.root=/usr/local \ - config.install.sudo=sudo libfoo libbar + config.install.sudo=sudo \ + libfoo libbar \ Alternatively, the installation directory can be specified once when diff --git a/bpkg/pkg-install.hxx b/bpkg/pkg-install.hxx index f2969e8..99031ea 100644 --- a/bpkg/pkg-install.hxx +++ b/bpkg/pkg-install.hxx @@ -15,7 +15,7 @@ namespace bpkg { inline int - pkg_install (const pkg_install_options& o, cli::scanner& args) + pkg_install (const pkg_install_options& o, cli::group_scanner& args) { return pkg_command ("install", o, diff --git a/bpkg/pkg-test.cli b/bpkg/pkg-test.cli index 885996c..6593c4d 100644 --- a/bpkg/pkg-test.cli +++ b/bpkg/pkg-test.cli @@ -15,7 +15,7 @@ namespace bpkg "\h|SYNOPSIS| - \c{\b{bpkg pkg-test}|\b{test} [] [] ( [])...\n + \c{\b{bpkg pkg-test}|\b{test} [] [] ...\n \b{bpkg pkg-test}|\b{test} [] [] \b{--all}|\b{-a}} \h|DESCRIPTION| @@ -25,14 +25,15 @@ namespace bpkg Additionally, immediate or all dependencies of these packages can also be tested by specifying the \c{\b{--immediate}|\b{-i}} or \c{\b{--recursive}|\b{-r}} options, respectively. Underneath, this - command doesn't do much more than run \cb{b test}. + command doesn't do much more than run \cb{b test}. In the first form the + specified packages must have been previously configured with + \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}. - In the first form the specified packages must have been previously - configured with \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}. Additional command line variables (, normally \cb{config.*}) can be - passed to the build system by either specifying them before the packages, - in which case they apply to the whole configuration, or after a specific - package, in which case they apply only to this package." + passed to the build system. Such variables apply to all the specified + packages but can also be specified to only apply to specific packages + using the argument grouping mechanism (see \l{bpkg-argument-grouping(1)} + for details)." } class pkg_test_options: configuration_options diff --git a/bpkg/pkg-test.hxx b/bpkg/pkg-test.hxx index 1b8b670..a5ad022 100644 --- a/bpkg/pkg-test.hxx +++ b/bpkg/pkg-test.hxx @@ -14,7 +14,7 @@ namespace bpkg { inline int - pkg_test (const pkg_test_options& o, cli::scanner& args) + pkg_test (const pkg_test_options& o, cli::group_scanner& args) { return pkg_command ("test", o, diff --git a/bpkg/pkg-uninstall.cli b/bpkg/pkg-uninstall.cli index 1ac2546..0ceaf57 100644 --- a/bpkg/pkg-uninstall.cli +++ b/bpkg/pkg-uninstall.cli @@ -15,7 +15,7 @@ namespace bpkg "\h|SYNOPSIS| - \c{\b{bpkg pkg-uninstall}|\b{uninstall} [] [] ( [])...\n + \c{\b{bpkg pkg-uninstall}|\b{uninstall} [] [] ...\n \b{bpkg pkg-uninstall}|\b{uninstall} [] [] \b{--all}|\b{-a}} \h|DESCRIPTION| @@ -26,15 +26,15 @@ namespace bpkg these specified packages can be also uninstalled by specifying the \c{\b{--immediate}|\b{-i}} or \c{\b{--recursive}|\b{-r}} options, respectively. Underneath, this command doesn't do much more than run - \cb{b uninstall}. + \cb{b uninstall}. In the first form the specified packages must have been + previously configured with \l{bpkg-pkg-build(1)} or + \l{bpkg-pkg-configure(1)}. - In the first form the specified packages must have been previously - configured with \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}. Additional command line variables (, normally \cb{config.*}) can be - passed to the build system by either specifying them before the packages, - in which case they apply to the whole configuration, or after a specific - package, in which case they apply only to this package. See - \l{bpkg-pkg-install(1)} for some examples." + passed to the build system. Such variables apply to all the specified + packages but can also be specified to only apply to specific packages + using the argument grouping mechanism (see \l{bpkg-argument-grouping(1)} + for details). See \l{bpkg-pkg-install(1)} for some examples." } class pkg_uninstall_options: configuration_options diff --git a/bpkg/pkg-uninstall.hxx b/bpkg/pkg-uninstall.hxx index 30bd52d..6079143 100644 --- a/bpkg/pkg-uninstall.hxx +++ b/bpkg/pkg-uninstall.hxx @@ -15,7 +15,7 @@ namespace bpkg { inline int - pkg_uninstall (const pkg_uninstall_options& o, cli::scanner& args) + pkg_uninstall (const pkg_uninstall_options& o, cli::group_scanner& args) { return pkg_command ("uninstall", o, "" /* cmd_variant */, diff --git a/bpkg/pkg-update.cli b/bpkg/pkg-update.cli index a77b473..86e0e45 100644 --- a/bpkg/pkg-update.cli +++ b/bpkg/pkg-update.cli @@ -15,7 +15,7 @@ namespace bpkg "\h|SYNOPSIS| - \c{\b{bpkg pkg-update}|\b{update} [] [] ( [])...\n + \c{\b{bpkg pkg-update}|\b{update} [] [] ...\n \b{bpkg pkg-update}|\b{update} [] [] \b{--all}|\b{-a}} \h|DESCRIPTION| @@ -24,14 +24,15 @@ namespace bpkg form) or all the held packages (the second form, see \l{bpkg-pkg-status(1)}). Underneath, this command doesn't do much more than run \cb{b update} (or one of its \c{update-for-*} variants; see - \cb{--for|-f}). + \cb{--for|-f}). In the first form the specified packages must have been + previously configured with \l{bpkg-pkg-build(1)} or + \l{bpkg-pkg-configure(1)}. - In the first form the specified packages must have been previously - configured with \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}. Additional command line variables (, normally \cb{config.*}) can be - passed to the build system by either specifying them before the packages, - in which case they apply to the whole configuration, or after a specific - package, in which case they apply only to this package." + passed to the build system. Such variables apply to all the specified + packages but can also be specified to only apply to specific packages + using the argument grouping mechanism (see \l{bpkg-argument-grouping(1)} + for details)." } class pkg_update_options: configuration_options diff --git a/bpkg/pkg-update.hxx b/bpkg/pkg-update.hxx index 01c5e58..13d6ae9 100644 --- a/bpkg/pkg-update.hxx +++ b/bpkg/pkg-update.hxx @@ -15,7 +15,7 @@ namespace bpkg { inline int - pkg_update (const pkg_update_options& o, cli::scanner& args) + pkg_update (const pkg_update_options& o, cli::group_scanner& args) { return pkg_command ("update", o, diff --git a/bpkg/utility.hxx b/bpkg/utility.hxx index c0c361f..accfa99 100644 --- a/bpkg/utility.hxx +++ b/bpkg/utility.hxx @@ -7,6 +7,7 @@ #include // make_shared() #include // to_string() +#include // strcmp(), strchr() #include // move(), forward(), declval(), make_pair() #include // assert() #include // make_move_iterator() @@ -32,6 +33,9 @@ namespace bpkg using std::make_move_iterator; using std::to_string; + using std::strcmp; + using std::strchr; + // // using butl::casecmp; -- cgit v1.1