diff options
-rw-r--r-- | bpkg/pkg-build.cxx | 8 | ||||
-rw-r--r-- | bpkg/pkg-clean.hxx | 1 | ||||
-rw-r--r-- | bpkg/pkg-command.cxx | 44 | ||||
-rw-r--r-- | bpkg/pkg-command.hxx | 3 | ||||
-rw-r--r-- | bpkg/pkg-install.hxx | 1 | ||||
-rw-r--r-- | bpkg/pkg-test.cli | 8 | ||||
-rw-r--r-- | bpkg/pkg-test.hxx | 3 | ||||
-rw-r--r-- | bpkg/pkg-uninstall.hxx | 1 | ||||
-rw-r--r-- | bpkg/pkg-update.hxx | 1 | ||||
-rw-r--r-- | bpkg/utility.cxx | 20 | ||||
-rw-r--r-- | bpkg/utility.hxx | 6 | ||||
-rw-r--r-- | tests/pkg-test.testscript | 11 |
12 files changed, 90 insertions, 17 deletions
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index 7a2168c..6cb59d5 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -4504,7 +4504,9 @@ namespace bpkg if (!sp->system () && // System package doesn't need update. p.user_selection ()) - upkgs.push_back (pkg_command_vars {sp, strings ()}); + upkgs.push_back (pkg_command_vars {sp, + strings () /* vars */, + false /* cwd */}); } // Then add dependents. We do it as a separate step so that they are @@ -4517,7 +4519,9 @@ namespace bpkg assert (p.action); if (*p.action == build_package::adjust && p.reconfigure ()) - upkgs.push_back (pkg_command_vars {p.selected, strings ()}); + upkgs.push_back (pkg_command_vars {p.selected, + strings () /* vars */, + false /* cwd */}); } } diff --git a/bpkg/pkg-clean.hxx b/bpkg/pkg-clean.hxx index e7b7e13..f046060 100644 --- a/bpkg/pkg-clean.hxx +++ b/bpkg/pkg-clean.hxx @@ -22,6 +22,7 @@ namespace bpkg false /* recursive */, false /* immediate */, o.all (), + false /* package_cwd */, args); } } diff --git a/bpkg/pkg-command.cxx b/bpkg/pkg-command.cxx index 12b6a7a..8524a01 100644 --- a/bpkg/pkg-command.cxx +++ b/bpkg/pkg-command.cxx @@ -30,11 +30,9 @@ namespace bpkg l4 ([&]{trace << "command: " << cmd;}); // 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). - // - // @@ If the build system supported command line variable grouping, then - // we could always build at once. + // if they don't have any package-specific variables and don't require to + // change the current working directory to the package directory. But + // let's try to handle this with the same logic (being clever again). // string bspec; @@ -60,7 +58,7 @@ namespace bpkg for (const pkg_command_vars& pv: ps) { - if (!pv.vars.empty ()) + if (!pv.vars.empty () || pv.cwd) run (); // Run previously collected packages. if (bspec.empty ()) @@ -90,11 +88,25 @@ namespace bpkg // Use path representation to get canonical trailing slash. // bspec += '\''; - bspec += out_root.representation (); + bspec += (!pv.cwd ? out_root : current_dir).representation (); bspec += '\''; - if (!pv.vars.empty ()) - run (pv.vars); // Run this package. + if (!pv.vars.empty () || pv.cwd) + { + // Run this package, changing the current working directory to the + // package directory, if requested. Note that we do it this way + // instead of changing the working directory of the process for + // diagnostics. + // + auto owdg = make_guard ( + [owd = pv.cwd ? change_wd (out_root) : dir_path ()] () + { + if (!owd.empty ()) + change_wd (owd); + }); + + run (pv.vars); + } } run (); @@ -103,6 +115,7 @@ namespace bpkg static void collect_dependencies (const shared_ptr<selected_package>& p, bool recursive, + bool package_cwd, vector<pkg_command_vars>& ps) { for (const auto& pr: p->prerequisites) @@ -123,10 +136,12 @@ namespace bpkg { // Note: no package-specific variables (global ones still apply). // - ps.push_back (pkg_command_vars {d, strings () /* vars */}); + ps.push_back (pkg_command_vars {d, + strings () /* vars */, + package_cwd}); if (recursive) - collect_dependencies (d, recursive, ps); + collect_dependencies (d, recursive, package_cwd, ps); } } } @@ -138,6 +153,7 @@ namespace bpkg bool recursive, bool immediate, bool all, + bool package_cwd, cli::group_scanner& args) { tracer trace ("pkg_command"); @@ -232,16 +248,16 @@ namespace bpkg // session ses; - auto add = [&ps, recursive, immediate] ( + auto add = [&ps, recursive, immediate, package_cwd] ( const shared_ptr<selected_package>& p, strings vars) { - ps.push_back (pkg_command_vars {p, move (vars)}); + ps.push_back (pkg_command_vars {p, move (vars), package_cwd}); // Note that it can only be recursive or immediate but not both. // if (recursive || immediate) - collect_dependencies (p, recursive, ps); + collect_dependencies (p, recursive, package_cwd, ps); }; if (all) diff --git a/bpkg/pkg-command.hxx b/bpkg/pkg-command.hxx index b649491..b8c5e3f 100644 --- a/bpkg/pkg-command.hxx +++ b/bpkg/pkg-command.hxx @@ -28,12 +28,15 @@ namespace bpkg bool recursive, bool immediate, bool all, + bool package_cwd, cli::group_scanner& args); struct pkg_command_vars { shared_ptr<selected_package> pkg; strings vars; // Package-specific command line vars. + + bool cwd; // Change the working directory to the package directory. }; void diff --git a/bpkg/pkg-install.hxx b/bpkg/pkg-install.hxx index 4b504fe..6cc88e4 100644 --- a/bpkg/pkg-install.hxx +++ b/bpkg/pkg-install.hxx @@ -23,6 +23,7 @@ namespace bpkg o.recursive (), o.immediate (), o.all (), + false /* package_cwd */, args); } } diff --git a/bpkg/pkg-test.cli b/bpkg/pkg-test.cli index 6ccb8c1..939125f 100644 --- a/bpkg/pkg-test.cli +++ b/bpkg/pkg-test.cli @@ -54,6 +54,14 @@ namespace bpkg { "Also test all dependencies, recursively." } + + bool --package-cwd + { + "Change the current working directory to the package directory prior + to running tests. This may help ported third-party packages since + its not uncommon for tests to expect they are running form the project + root directory." + } }; " diff --git a/bpkg/pkg-test.hxx b/bpkg/pkg-test.hxx index 9ae53c8..59d0e59 100644 --- a/bpkg/pkg-test.hxx +++ b/bpkg/pkg-test.hxx @@ -18,10 +18,11 @@ namespace bpkg { return pkg_command ("test", o, - "", + "" /* cmd_variant */, o.recursive (), o.immediate (), o.all (), + o.package_cwd (), args); } } diff --git a/bpkg/pkg-uninstall.hxx b/bpkg/pkg-uninstall.hxx index 4542cc3..f6756b0 100644 --- a/bpkg/pkg-uninstall.hxx +++ b/bpkg/pkg-uninstall.hxx @@ -22,6 +22,7 @@ namespace bpkg o.recursive (), o.immediate (), o.all (), + false /* package_cwd */, args); } } diff --git a/bpkg/pkg-update.hxx b/bpkg/pkg-update.hxx index 6cd815d..abf7317 100644 --- a/bpkg/pkg-update.hxx +++ b/bpkg/pkg-update.hxx @@ -23,6 +23,7 @@ namespace bpkg false /* recursive */, false /* immediate */, o.all (), + false /* package_cwd */, args); } diff --git a/bpkg/utility.cxx b/bpkg/utility.cxx index 3cb9fb5..3529d83 100644 --- a/bpkg/utility.cxx +++ b/bpkg/utility.cxx @@ -262,6 +262,26 @@ namespace bpkg } } + dir_path + change_wd (const dir_path& d) + { + try + { + dir_path r (dir_path::current_directory ()); + + if (verb >= 3) + text << "cd " << d; // Prints trailing slash. + + dir_path::current_directory (d); + return r; + } + catch (const system_error& e) + { + fail << "unable to change current directory to " << d << ": " << e + << endf; + } + } + fdpipe open_pipe () { diff --git a/bpkg/utility.hxx b/bpkg/utility.hxx index 484b394..81aedf0 100644 --- a/bpkg/utility.hxx +++ b/bpkg/utility.hxx @@ -161,6 +161,12 @@ namespace bpkg void mv (const dir_path& from, const dir_path& to); + // Set (with diagnostics at verbosity level 3 or higher) the new and return + // the previous working directory. + // + dir_path + change_wd (const dir_path&); + // File descriptor streams. // fdpipe diff --git a/tests/pkg-test.testscript b/tests/pkg-test.testscript index 5224696..612d53f 100644 --- a/tests/pkg-test.testscript +++ b/tests/pkg-test.testscript @@ -117,3 +117,14 @@ test.options += --build-option -s tested libfix/0.0.1 EOE } + +: package-cwd +: +{ + $clone_cfg; + + $* libbaz --recursive --package-cwd -v 2>>/~%EOE% + %(.+ test\('\./'\)|info: .+ has nothing to test)%{6} + %tested .+%{3} + EOE +} |