diff options
-rw-r--r-- | bdep/bdep.cxx | 12 | ||||
-rw-r--r-- | bdep/buildfile | 6 | ||||
-rw-r--r-- | bdep/init.cli | 3 | ||||
-rw-r--r-- | bdep/init.cxx | 25 | ||||
-rw-r--r-- | bdep/init.hxx | 5 | ||||
-rw-r--r-- | bdep/new.cxx | 4 | ||||
-rw-r--r-- | bdep/new.hxx | 2 | ||||
-rw-r--r-- | bdep/sync.cli | 12 | ||||
-rw-r--r-- | bdep/sync.cxx | 33 | ||||
-rw-r--r-- | bdep/sync.hxx | 6 | ||||
-rw-r--r-- | bdep/utility.cxx | 19 | ||||
-rw-r--r-- | bdep/utility.hxx | 19 |
12 files changed, 112 insertions, 34 deletions
diff --git a/bdep/bdep.cxx b/bdep/bdep.cxx index 82a4259..f25bed3 100644 --- a/bdep/bdep.cxx +++ b/bdep/bdep.cxx @@ -61,7 +61,7 @@ cfg_name (...) template <typename O> static O -init (const common_options& co, cli::scanner& scan, strings& args) +init (const common_options& co, cli::group_scanner& scan, strings& args) { O o; static_cast<common_options&> (o) = co; @@ -100,7 +100,9 @@ init (const common_options& co, cli::scanner& scan, strings& args) // Fall through. } - args.push_back (scan.next ()); + // Copy over the argument including the group. + // + scan_argument (args, scan); } // Global initializations. @@ -159,7 +161,8 @@ try << system_error (errno, generic_category ()); // Sanitize. #endif - argv_file_scanner scan (argc, argv, "--options-file"); + argv_file_scanner argv_scan (argc, argv, "--options-file"); + group_scanner scan (argv_scan); // First parse common options and --version/--help. // @@ -177,7 +180,8 @@ try } strings argsv; // To be filled by parse() above. - vector_scanner args (argsv); + vector_scanner vect_args (argsv); + group_scanner args (vect_args); const common_options& co (o); diff --git a/bdep/buildfile b/bdep/buildfile index 1a4fd60..0fb8e8c 100644 --- a/bdep/buildfile +++ b/bdep/buildfile @@ -74,9 +74,9 @@ if $cli.configured cli.options += -I $src_root --include-with-brackets --include-prefix bdep \ --guard-prefix BDEP --cxx-prologue "#include <bdep/types-parsers.hxx>" \ --cli-namespace bdep::cli --generate-vector-scanner --generate-file-scanner \ ---keep-separator --generate-specifier --generate-modifier --generate-parse \ ---page-usage 'bdep::print_$name$_' --ansi-color --include-base-last \ ---suppress-undocumented --option-length 23 +--generate-group-scanner --keep-separator --generate-specifier --generate-modifier \ +--generate-parse --page-usage 'bdep::print_$name$_' --ansi-color \ +--include-base-last --suppress-undocumented --option-length 23 cli.cxx{common-options}: cli.options += --short-usage --long-usage # Both. cli.cxx{bdep-options}: cli.options += --short-usage diff --git a/bdep/init.cli b/bdep/init.cli index 0f0e882..c410d7d 100644 --- a/bdep/init.cli +++ b/bdep/init.cli @@ -43,7 +43,8 @@ namespace bdep is assumed. If no configuration is specified, then the default configuration is assumed. See \l{bdep-projects-configs(1)} for details on specifying projects and configurations. Optional <pkg-args> are the - additional arguments to the underlying \l{bpkg-pkg-build(1)} command. + additional dependency packages and/or configuration variables to pass + to the underlying \l{bpkg-pkg-build(1)} command. The second form (\cb{--empty} is specified) initializes an empty project database that can later be used to first add build configurations diff --git a/bdep/init.cxx b/bdep/init.cxx index 603a567..1c885eb 100644 --- a/bdep/init.cxx +++ b/bdep/init.cxx @@ -60,7 +60,8 @@ namespace bdep const dir_path& prj, database& db, const configurations& cfgs, - const package_locations& pkgs) + const package_locations& pkgs, + const strings& pkg_args) { // We do each configuration in a separate transaction so that our state // reflects the bpkg configuration as closely as possible. @@ -117,12 +118,12 @@ namespace bdep db.update (c); t.commit (); - cmd_sync (o, prj, c, false /* implicit */); + cmd_sync (o, prj, c, pkg_args, false /* implicit */); } } int - cmd_init (const cmd_init_options& o, cli::scanner& args) + cmd_init (const cmd_init_options& o, cli::group_scanner& args) { tracer trace ("init"); @@ -192,15 +193,12 @@ namespace bdep args, ca, cc)); - - // Fall through. } - - // If this is the default mode, then find the configurations the user - // wants us to use. - // - if (cfgs.empty ()) + else { + // If this is the default mode, then find the configurations the user + // wants us to use. + // transaction t (db.begin ()); cfgs = find_configurations (prj, t, o); t.commit (); @@ -209,7 +207,12 @@ namespace bdep // Initialize each package in each configuration. // - cmd_init (o, prj, db, cfgs, pp.packages); + cmd_init (o, + prj, + db, + cfgs, + pp.packages, + scan_arguments (args) /* pkg_args */); return 0; } diff --git a/bdep/init.hxx b/bdep/init.hxx index 1ac46c1..484b336 100644 --- a/bdep/init.hxx +++ b/bdep/init.hxx @@ -33,10 +33,11 @@ namespace bdep const dir_path& prj, database&, const configurations&, - const package_locations&); + const package_locations&, + const strings& pkg_args); int - cmd_init (const cmd_init_options&, cli::scanner& args); + cmd_init (const cmd_init_options&, cli::group_scanner& args); } #endif // BDEP_INIT_HXX diff --git a/bdep/new.cxx b/bdep/new.cxx index 7589dca..62fc41e 100644 --- a/bdep/new.cxx +++ b/bdep/new.cxx @@ -20,7 +20,7 @@ namespace bdep using vcs = cmd_new_vcs; int - cmd_new (const cmd_new_options& o, cli::scanner& args) + cmd_new (const cmd_new_options& o, cli::group_scanner& args) { tracer trace ("new"); @@ -941,7 +941,7 @@ namespace bdep package_locations pkgs {{n, dir_path ()}}; // project == package - cmd_init (o, prj, db, cfgs, pkgs); + cmd_init (o, prj, db, cfgs, pkgs, scan_arguments (args) /* pkg_args */); } return 0; diff --git a/bdep/new.hxx b/bdep/new.hxx index a9afbe8..536feab 100644 --- a/bdep/new.hxx +++ b/bdep/new.hxx @@ -13,7 +13,7 @@ namespace bdep { int - cmd_new (const cmd_new_options&, cli::scanner& args); + cmd_new (const cmd_new_options&, cli::group_scanner& args); } #endif // BDEP_NEW_HXX diff --git a/bdep/sync.cli b/bdep/sync.cli index dde86a2..9aa142b 100644 --- a/bdep/sync.cli +++ b/bdep/sync.cli @@ -15,11 +15,12 @@ namespace bdep <prj-spec> <prj-dir> <pkg-spec> <pkg-dir> <cfg-spec> <cfg-name> <cfg-dir> - <dep-spec> <pkg> <ver>", + <dep-spec> <pkg> <ver> + <pkg-args> <pkg> <cfg-var>", "\h|SYNOPSIS| - \c{\b{bdep sync} [<options>] [<pkg-spec>] [<cfg-spec>]\n + \c{\b{bdep sync} [<options>] [<pkg-spec>] [<cfg-spec>] [<pkg-args>]\n \b{bdep sync} [<options>] [<pkg-spec>] [<cfg-spec>] \ \b{--upgrade}|\b{-u} | \b{--patch}|\b{-p}\n \b{bdep sync} [<options>] [<pkg-spec>] [<cfg-spec>] [\b{--upgrade}|\b{-u} | \b{--patch}|\b{-p}]\n \ \ \ \ \ \ \ \ \ \ <dep-spec>... @@ -28,7 +29,8 @@ namespace bdep \c{<dep-spec> = <pkg>[\b{/}<ver>]\n <cfg-spec> = (\b{@}<cfg-name> | \b{--config}|\b{-c} <cfg-dir>)... | \b{--all}|\b{-a}\n <pkg-spec> = (\b{--directory}|\b{-d} <pkg-dir>)... | <prj-spec>\n - <prj-spec> = \b{--directory}|\b{-d} <prj-dir>} + <prj-spec> = \b{--directory}|\b{-d} <prj-dir>\n + <pkg-args> = (<pkg> | <cfg-var>)...} \h|DESCRIPTION| @@ -40,7 +42,9 @@ namespace bdep directory is specified, then the current working directory is assumed. If no configuration is specified, then the default configuration is assumed. See \l{bdep-projects-configs(1)} for details on specifying - projects and configurations. + projects and configurations. Optional <pkg-args> are the additional + dependency packages and/or configuration variables to pass to the + underlying \l{bpkg-pkg-build(1)} command. The second form (no arguments but either \cb{--upgrade} or \cb{--patch} is specified), in addition to the first form's functionality, also diff --git a/bdep/sync.cxx b/bdep/sync.cxx index e2e9caa..8ecae4f 100644 --- a/bdep/sync.cxx +++ b/bdep/sync.cxx @@ -6,6 +6,8 @@ #include <stdlib.h> // getenv() setenv()/_putenv() +#include <cstring> // strchr() + #include <bdep/database.hxx> #include <bdep/diagnostics.hxx> #include <bdep/project-odb.hxx> @@ -135,6 +137,7 @@ namespace bdep const dir_path& cfg, const dir_path& origin_prj, const shared_ptr<configuration>& origin_config, + const strings& pkg_args, bool implicit, bool fetch, bool yes, @@ -227,6 +230,10 @@ namespace bdep } } + // Finally, add pkg_args, if any. + // + args.insert (args.end (), pkg_args.begin (), pkg_args.end ()); + // We do a separate fetch instead of letting pkg-build do it. This way we // get better control of the diagnostics (no "fetching ..." for the // project itself). We also make sure that if the user specifies a @@ -402,6 +409,7 @@ namespace bdep cmd_sync (const common_options& co, const dir_path& prj, const shared_ptr<configuration>& c, + const strings& pkg_args, bool implicit, bool fetch, bool yes) @@ -410,6 +418,7 @@ namespace bdep c->path, prj, c, + pkg_args, implicit, fetch, yes, @@ -420,10 +429,13 @@ namespace bdep } int - cmd_sync (cmd_sync_options&& o, cli::scanner& args) + cmd_sync (cmd_sync_options&& o, cli::group_scanner& args) { tracer trace ("sync"); + // We have two pretty different upgrade modes: project package upgrade and + // dependency package upgrade (have non-pkg-args arguments). + // if (o.upgrade () && o.patch ()) fail << "both --upgrade|-u and --patch|-p specified"; @@ -440,11 +452,19 @@ namespace bdep fail << n << " requires explicit --upgrade|-u or --patch|-p"; } - // We have two pretty different upgrade modes: project package upgrade and - // dependency package upgrade (have arguments). + // Sort arguments (if any) into pkg-args and dep-spec: if the argument + // starts with '?' (dependency flag) or contains '=' (config variable), + // then we assume it is pkg-args. // + strings pkg_args; strings dep_pkgs; - for (; args.more (); dep_pkgs.push_back (args.next ())) ; + while (args.more ()) + { + const char* r (args.peek ()); + scan_argument ( + (*r == '?' || strchr (r, '=') != nullptr) ? pkg_args : dep_pkgs, + args); + } // --hook // @@ -641,6 +661,7 @@ namespace bdep cd, prj, c, + pkg_args, false /* implicit */, !fetch, o.recursive () || o.immediate () ? o.yes () : true, @@ -659,6 +680,7 @@ namespace bdep cd, prj, c, + pkg_args, false /* implicit */, !fetch, o.yes (), @@ -675,9 +697,10 @@ namespace bdep cd, prj, c, + pkg_args, o.implicit (), !fetch, - true /* yes */, + true /* yes */, nullopt /* upgrade */, nullopt /* recursive */, package_locations () /* prj_pkgs */, diff --git a/bdep/sync.hxx b/bdep/sync.hxx index 8edd4b4..0894c9b 100644 --- a/bdep/sync.hxx +++ b/bdep/sync.hxx @@ -13,6 +13,9 @@ namespace bdep { + // The optional pkg_args are the additional dependency packages and/or + // configuration variables to pass to bpkg-pkg-build (see bdep-init). + // // If fetch is false, don't perform a (shallow) fetch of the project // repository. If yes is false, then don't suppress bpkg prompts. // @@ -20,12 +23,13 @@ namespace bdep cmd_sync (const common_options&, const dir_path& prj, const shared_ptr<configuration>&, + const strings& pkg_args, bool implicit, bool fetch = true, bool yes = true); int - cmd_sync (cmd_sync_options&&, cli::scanner& args); + cmd_sync (cmd_sync_options&&, cli::group_scanner& args); } #endif // BDEP_SYNC_HXX diff --git a/bdep/utility.cxx b/bdep/utility.cxx index 15fb599..98b6279 100644 --- a/bdep/utility.cxx +++ b/bdep/utility.cxx @@ -133,4 +133,23 @@ namespace bdep ? co.build ().string ().c_str () : "b" BDEP_EXE_SUFFIX; } + + void + scan_argument (strings& r, cli::group_scanner& s) + { + // Copy over the argument including the group. + // + using scanner = cli::scanner; + using group_scanner = cli::group_scanner; + + r.push_back (group_scanner::escape (s.next ())); + + scanner& gs (s.group ()); + if (gs.more ()) + { + r.push_back ("+{"); + for (; gs.more (); r.push_back (group_scanner::escape (gs.next ()))) ; + r.push_back ("}"); + } + } } diff --git a/bdep/utility.hxx b/bdep/utility.hxx index dc9e589..da491c3 100644 --- a/bdep/utility.hxx +++ b/bdep/utility.hxx @@ -184,6 +184,25 @@ namespace bdep template <typename C> bool parse_command (cli::scanner& scan, C&); + + // Scan and return/append arguments preserving grouping. + // + void + scan_argument (strings&, cli::group_scanner&); + + inline void + scan_arguments (strings& r, cli::group_scanner& s) + { + for (; s.more (); scan_argument (r, s)) ; + } + + inline strings + scan_arguments (cli::group_scanner& s) + { + strings r; + scan_arguments (r, s); + return r; + } } #include <bdep/utility.txx> |