aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/pkg-build.cxx8
-rw-r--r--bpkg/pkg-clean.hxx1
-rw-r--r--bpkg/pkg-command.cxx44
-rw-r--r--bpkg/pkg-command.hxx3
-rw-r--r--bpkg/pkg-install.hxx1
-rw-r--r--bpkg/pkg-test.cli8
-rw-r--r--bpkg/pkg-test.hxx3
-rw-r--r--bpkg/pkg-uninstall.hxx1
-rw-r--r--bpkg/pkg-update.hxx1
-rw-r--r--bpkg/utility.cxx20
-rw-r--r--bpkg/utility.hxx6
-rw-r--r--tests/pkg-test.testscript11
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
+}