From a38876e1bcb94b6452f2c820e20883580e47cfe4 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 25 Jan 2016 15:41:42 +0200 Subject: Add support for passing config vars to pkg-{build,clean,install,uninstall} --- bpkg/pkg-clean.cli | 15 +++++++---- bpkg/pkg-command | 9 ++++++- bpkg/pkg-command.cxx | 73 ++++++++++++++++++++++++++++++++++++++++---------- bpkg/pkg-install.cli | 24 +++++++++++------ bpkg/pkg-uninstall.cli | 12 ++++++--- bpkg/pkg-update.cli | 15 +++++++---- bpkg/utility | 3 ++- bpkg/utility.cxx | 8 ++++-- 8 files changed, 120 insertions(+), 39 deletions(-) diff --git a/bpkg/pkg-clean.cli b/bpkg/pkg-clean.cli index ffad75a..1161b13 100644 --- a/bpkg/pkg-clean.cli +++ b/bpkg/pkg-clean.cli @@ -11,17 +11,22 @@ include ; namespace bpkg { { - " ", + " ", "\h|SYNOPSIS| - \c{\b{bpkg pkg-clean}|\b{clean} [] ...} + \c{\b{bpkg pkg-clean}|\b{clean} [] [] ( [])...} \h|DESCRIPTION| - The \cb{pkg-clean} command cleans the previously configured - (via \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}) package. - Underneath, this command doesn't do much more than run \cb{b clean}." + The \cb{pkg-clean} command cleans the previously configured (via + \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}) package. Underneath, + this command doesn't do much more than run \cb{b clean}. + + 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 all of them, or after a specific package, in + which case they apply only to this package." } class pkg_clean_options: configuration_options diff --git a/bpkg/pkg-command b/bpkg/pkg-command index 60d0396..334a97e 100644 --- a/bpkg/pkg-command +++ b/bpkg/pkg-command @@ -20,6 +20,12 @@ namespace bpkg const configuration_options&, cli::scanner& args); + struct pkg_command_vars + { + shared_ptr pkg; + strings vars; + }; + void pkg_command (const string& cmd, const dir_path& configuration, @@ -30,7 +36,8 @@ namespace bpkg pkg_command (const string& cmd, const dir_path& configuration, const common_options&, - const vector>&); + const strings& common_vars, + const vector&); } #endif // BPKG_PKG_COMMAND diff --git a/bpkg/pkg-command.cxx b/bpkg/pkg-command.cxx index 60afb08..356d578 100644 --- a/bpkg/pkg-command.cxx +++ b/bpkg/pkg-command.cxx @@ -44,18 +44,40 @@ namespace bpkg pkg_command (const string& cmd, const dir_path& c, const common_options& o, - const vector>& ps) + const strings& cvars, + const vector& ps) { tracer trace ("pkg_command"); level4 ([&]{trace << "command: " << cmd;}); - // Form the buildspec. + // This one is a bit tricky: we can only update all the packages at once if + // they don't have any package-specific variables. But let's try to handle + // this with the same logic (being clever again). // - string bspec (cmd + "("); + string bspec; - for (const shared_ptr& p: ps) + auto run = [&trace, &o, &cvars, &bspec](const strings& vars = strings ()) + { + if (!bspec.empty ()) + { + bspec += ')'; + level4 ([&]{trace << "buildspec: " << bspec;}); + run_b (o, bspec, false, cvars, vars); + bspec.clear (); + } + }; + + for (const pkg_command_vars& pv: ps) { + if (!pv.vars.empty ()) + run (); // Run previously collected packages. + + if (bspec.empty ()) + bspec = cmd + '('; + + const shared_ptr& p (pv.pkg); + assert (p->state == package_state::configured); assert (p->out_root); // Should be present since configured. @@ -66,13 +88,12 @@ namespace bpkg bspec += ' '; bspec += out_root.string (); bspec += '/'; - } - - bspec += ')'; - level4 ([&]{trace << "buildspec: " << bspec;}); + if (!pv.vars.empty ()) + run (pv.vars); // Run this package. + } - run_b (o, bspec); + run (); } int @@ -85,11 +106,29 @@ namespace bpkg const dir_path& c (o.directory ()); level4 ([&]{trace << "configuration: " << c;}); + // First read the common variables. + // + auto read_vars = [&args](strings& v) + { + for (; args.more (); args.next ()) + { + string a (args.peek ()); + + if (a.find ('=') == string::npos) + break; + + v.push_back (move (a)); + } + }; + + strings cvars; + read_vars (cvars); + if (!args.more ()) fail << "package name argument expected" << info << "run 'bpkg help pkg-" << cmd << "' for more information"; - vector> ps; + vector ps; { database db (open (c, trace)); transaction t (db.begin ()); @@ -107,19 +146,25 @@ namespace bpkg info << "expected it to be configured"; level4 ([&]{trace << p->name << " " << p->version;}); - ps.push_back (move (p)); + + // Read package-specific variables. + // + strings vars; + read_vars (vars); + + ps.push_back (pkg_command_vars {move (p), move (vars)}); } t.commit (); } - pkg_command (cmd, c, o, ps); + pkg_command (cmd, c, o, cvars, ps); if (verb) { - for (const shared_ptr& p: ps) + for (const pkg_command_vars& pv: ps) text << cmd << (cmd.back () != 'e' ? "ed " : "d ") - << p->name << " " << p->version; + << pv.pkg->name << " " << pv.pkg->version; } return 0; diff --git a/bpkg/pkg-install.cli b/bpkg/pkg-install.cli index 3c700a0..24ccc43 100644 --- a/bpkg/pkg-install.cli +++ b/bpkg/pkg-install.cli @@ -11,22 +11,30 @@ include ; namespace bpkg { { - " ", + " ", "\h|SYNOPSIS| - \c{\b{bpkg pkg-install}|\b{install} [] ...} + \c{\b{bpkg pkg-install}|\b{install} [] [] ( [])...} \h|DESCRIPTION| The \cb{pkg-install} command installs one or more packages. Underneath, - this command doesn't do much more than run \cb{b install}. The - installation directory can be specified when creating the configuration - (\l{bpkg-cfg-create(1)}) with the \cb{config.install.root} configuration - variable." + this command doesn't do much more than run \cb{b install}. - // @@ Would be nice to be able to specify the root in the command. - // Probably an option to specify additional configuration vars. + 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 all of them, or after a specific package, in + which case they apply only to this package. Specifically, this mechanism + can be used to specify the installation directory, for example: + + \ + bpkg install config.install.root=/usr/local \ + config.install.root.sudo=sudo libfoo libbar + \ + + Alternatively, the installation directory can be specified once when + creating the configuration (\l{bpkg-cfg-create(1)})." } class pkg_install_options: configuration_options diff --git a/bpkg/pkg-uninstall.cli b/bpkg/pkg-uninstall.cli index 89f9dc0..ba7f55a 100644 --- a/bpkg/pkg-uninstall.cli +++ b/bpkg/pkg-uninstall.cli @@ -11,17 +11,23 @@ include ; namespace bpkg { { - " ", + " ", "\h|SYNOPSIS| - \c{\b{bpkg pkg-uninstall}|\b{uninstall} [] ...} + \c{\b{bpkg pkg-uninstall}|\b{uninstall} [] [] ( [])...} \h|DESCRIPTION| The \cb{pkg-uninstall} command uninstalls one or more packages that were previously installed with \l{bpkg-pkg-install(1)}. Underneath, this - command doesn't do much more than run \cb{b uninstall}." + command doesn't do much more than run \cb{b uninstall}. + + 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 all of them, or after a specific package, in + which case they apply only to this package. See \l{bpkg-pkg-install(1)} + for some examples." } class pkg_uninstall_options: configuration_options diff --git a/bpkg/pkg-update.cli b/bpkg/pkg-update.cli index cce17b0..6a387be 100644 --- a/bpkg/pkg-update.cli +++ b/bpkg/pkg-update.cli @@ -11,17 +11,22 @@ include ; namespace bpkg { { - " ", + " ", "\h|SYNOPSIS| - \c{\b{bpkg pkg-update}|\b{update} [] ...} + \c{\b{bpkg pkg-update}|\b{update} [] [] ( [])...} \h|DESCRIPTION| - The \cb{pkg-update} command updates the previously configured - (via \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}) package. - Underneath, this command doesn't do much more than run \cb{b update}." + The \cb{pkg-update} command updates the previously configured (via + \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}) package. Underneath, + this command doesn't do much more than run \cb{b update}. + + 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 all of them, or after a specific package, in + which case they apply only to this package." } class pkg_update_options: configuration_options diff --git a/bpkg/utility b/bpkg/utility index bd6f393..9aa2dba 100644 --- a/bpkg/utility +++ b/bpkg/utility @@ -74,7 +74,8 @@ namespace bpkg run_b (const common_options&, const string& buildspec, bool quiet = false, - const strings& vars = strings ()); + const strings& vars1 = strings (), + const strings& vars2 = strings ()); // Call a function if there is an exception. // diff --git a/bpkg/utility.cxx b/bpkg/utility.cxx index e8f8574..556bc88 100644 --- a/bpkg/utility.cxx +++ b/bpkg/utility.cxx @@ -195,7 +195,8 @@ namespace bpkg run_b (const common_options& co, const string& bspec, bool quiet, - const strings& vars) + const strings& vars1, + const strings& vars2) { cstrings args {co.build ().string ().c_str ()}; @@ -222,7 +223,10 @@ namespace bpkg // Add config vars. // - for (const string& v: vars) + for (const string& v: vars1) + args.push_back (v.c_str ()); + + for (const string& v: vars2) args.push_back (v.c_str ()); // Add buildspec. -- cgit v1.1