aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/algorithm.cxx49
-rw-r--r--libbuild2/algorithm.hxx9
-rw-r--r--libbuild2/config/operation.cxx18
-rw-r--r--libbuild2/context.cxx5
-rw-r--r--libbuild2/context.hxx69
-rw-r--r--libbuild2/dist/operation.cxx22
-rw-r--r--libbuild2/filesystem.cxx28
-rw-r--r--libbuild2/filesystem.hxx55
-rw-r--r--libbuild2/filesystem.ixx40
-rw-r--r--libbuild2/filesystem.txx9
-rw-r--r--libbuild2/install/rule.cxx24
-rw-r--r--libbuild2/operation.cxx4
-rw-r--r--libbuild2/test/rule.cxx36
-rw-r--r--libbuild2/test/script/runner.cxx27
-rw-r--r--libbuild2/utility.cxx3
-rw-r--r--libbuild2/utility.hxx3
-rw-r--r--libbuild2/version/init.cxx3
-rw-r--r--libbuild2/version/rule.cxx3
-rw-r--r--libbuild2/version/utility.cxx9
-rw-r--r--libbuild2/version/utility.hxx6
20 files changed, 250 insertions, 172 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index 8bc6ee1..2d2c940 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -1095,11 +1095,12 @@ namespace build2
if (!exists (d))
mkdir_p (d, 2 /* verbosity */);
- update_backlink (p, l, m);
+ update_backlink (f.ctx, p, l, m);
}
void
- update_backlink (const path& p, const path& l, bool changed, backlink_mode m)
+ update_backlink (context& ctx,
+ const path& p, const path& l, bool changed, backlink_mode m)
{
// As above but with a slightly different diagnostics.
@@ -1133,7 +1134,7 @@ namespace build2
if (!exists (d))
mkdir_p (d, 2 /* verbosity */);
- update_backlink (p, l, m);
+ update_backlink (ctx, p, l, m);
}
static inline void
@@ -1172,7 +1173,8 @@ namespace build2
}
void
- update_backlink (const path& p, const path& l, backlink_mode om)
+ update_backlink (context& ctx,
+ const path& p, const path& l, backlink_mode om)
{
using mode = backlink_mode;
@@ -1203,7 +1205,7 @@ namespace build2
{
// Normally will be there.
//
- if (!dry_run)
+ if (!ctx.dry_run)
try_rmbacklink (l, m);
// Skip (ad hoc) targets that don't exist.
@@ -1247,7 +1249,7 @@ namespace build2
path f (fr / de.path ());
path t (to / de.path ());
- update_backlink (f, t, mode::link);
+ update_backlink (ctx, f, t, mode::link);
}
}
else
@@ -1288,7 +1290,8 @@ namespace build2
}
void
- clean_backlink (const path& l, uint16_t v /*verbosity*/, backlink_mode m)
+ clean_backlink (context& ctx,
+ const path& l, uint16_t v /*verbosity*/, backlink_mode m)
{
// Like try_rmbacklink() but with diagnostics and error handling.
@@ -1300,9 +1303,9 @@ namespace build2
{
case mode::link:
case mode::symbolic:
- case mode::hard: rmsymlink (l, true /* directory */, v); break;
- case mode::copy: rmdir_r (path_cast<dir_path> (l), true, v); break;
- case mode::overwrite: break;
+ case mode::hard: rmsymlink (ctx, l, true /* directory */, v); break;
+ case mode::copy: rmdir_r (ctx, path_cast<dir_path> (l), true, v); break;
+ case mode::overwrite: break;
}
}
else
@@ -1314,8 +1317,8 @@ namespace build2
case mode::link:
case mode::symbolic:
case mode::hard:
- case mode::copy: rmfile (l, v); break;
- case mode::overwrite: break;
+ case mode::copy: rmfile (ctx, l, v); break;
+ case mode::overwrite: break;
}
}
}
@@ -1497,7 +1500,7 @@ namespace build2
ts == target_state::changed,
bl.mode);
else
- update_backlink (bl.target, bl.path, bl.mode);
+ update_backlink (t.ctx, bl.target, bl.path, bl.mode);
}
// Cancel removal.
@@ -1517,7 +1520,7 @@ namespace build2
//
backlink& bl (*i);
bl.cancel ();
- clean_backlink (bl.path, i == b ? 2 : 3 /* verbosity */, bl.mode);
+ clean_backlink (t.ctx, bl.path, i == b ? 2 : 3 /* verbosity */, bl.mode);
}
}
@@ -2038,9 +2041,9 @@ namespace build2
context& ctx (ft.ctx);
- auto clean_extra = [&er, &ed, &ep] (const file& f,
- const path* fp,
- const clean_extras& es)
+ auto clean_extra = [&er, &ed, &ep, &ctx] (const file& f,
+ const path* fp,
+ const clean_extras& es)
{
for (const char* e: es)
{
@@ -2080,7 +2083,7 @@ namespace build2
{
dir_path dp (path_cast<dir_path> (p));
- switch (build2::rmdir_r (dp, true, 3))
+ switch (rmdir_r (ctx, dp, true, 3))
{
case rmdir_status::success:
{
@@ -2099,7 +2102,7 @@ namespace build2
}
else
{
- if (rmfile (p, 3))
+ if (rmfile (ctx, p, 3))
r = target_state::changed;
}
@@ -2165,7 +2168,7 @@ namespace build2
}
else
{
- target_state r (rmfile (*mp, 3)
+ target_state r (rmfile (ctx, *mp, 3)
? target_state::changed
: target_state::unchanged);
@@ -2261,6 +2264,8 @@ namespace build2
target_state
perform_clean_group_depdb (action a, const target& g)
{
+ context& ctx (g.ctx);
+
// The same twisted target state merging logic as in perform_clean_extra().
//
target_state er (target_state::unchanged);
@@ -2271,7 +2276,7 @@ namespace build2
{
ep = gv.members[0]->as<file> ().path () + ".d";
- if (rmfile (ep, 3))
+ if (rmfile (ctx, ep, 3))
er = target_state::changed;
}
@@ -2279,7 +2284,7 @@ namespace build2
if (tr != target_state::changed && er == target_state::changed)
{
- if (verb > (g.ctx.current_diag_noise ? 0 : 1) && verb < 3)
+ if (verb > (ctx.current_diag_noise ? 0 : 1) && verb < 3)
text << "rm " << ep;
}
diff --git a/libbuild2/algorithm.hxx b/libbuild2/algorithm.hxx
index d772469..cda464b 100644
--- a/libbuild2/algorithm.hxx
+++ b/libbuild2/algorithm.hxx
@@ -761,18 +761,21 @@ namespace build2
backlink_mode = backlink_mode::link);
LIBBUILD2_SYMEXPORT void
- update_backlink (const path& target,
+ update_backlink (context&,
+ const path& target,
const path& link,
bool changed,
backlink_mode = backlink_mode::link);
LIBBUILD2_SYMEXPORT void
- update_backlink (const path& target,
+ update_backlink (context&,
+ const path& target,
const path& link,
backlink_mode = backlink_mode::link);
LIBBUILD2_SYMEXPORT void
- clean_backlink (const path& link,
+ clean_backlink (context&,
+ const path& link,
uint16_t verbosity,
backlink_mode = backlink_mode::link);
}
diff --git a/libbuild2/config/operation.cxx b/libbuild2/config/operation.cxx
index c5ff580..264eb93 100644
--- a/libbuild2/config/operation.cxx
+++ b/libbuild2/config/operation.cxx
@@ -635,7 +635,7 @@ namespace build2
!d.empty ();
d = d.directory ())
{
- rmdir_status s (rmdir (out_root / d, 2));
+ rmdir_status s (rmdir (ctx, out_root / d, 2));
if (s == rmdir_status::not_empty)
break; // No use trying do remove parent ones.
@@ -653,21 +653,21 @@ namespace build2
{
l5 ([&]{trace << "completely disfiguring " << out_root;});
- r = rmfile (config_file (rs)) || r;
+ r = rmfile (ctx, config_file (rs)) || r;
if (out_root != src_root)
{
- r = rmfile (out_root / rs.root_extra->src_root_file, 2) || r;
+ r = rmfile (ctx, out_root / rs.root_extra->src_root_file, 2) || r;
// Clean up the directories.
//
// Note: try to remove the root/ hooks directory if it is empty.
//
- r = rmdir (out_root / rs.root_extra->root_dir, 2) || r;
- r = rmdir (out_root / rs.root_extra->bootstrap_dir, 2) || r;
- r = rmdir (out_root / rs.root_extra->build_dir, 2) || r;
+ r = rmdir (ctx, out_root / rs.root_extra->root_dir, 2) || r;
+ r = rmdir (ctx, out_root / rs.root_extra->bootstrap_dir, 2) || r;
+ r = rmdir (ctx, out_root / rs.root_extra->build_dir, 2) || r;
- switch (rmdir (out_root))
+ switch (rmdir (ctx, out_root))
{
case rmdir_status::not_empty:
{
@@ -731,8 +731,8 @@ namespace build2
// Remove the out-root.build file and try to remove the bootstrap/
// directory if it is empty.
//
- r = rmfile (src_root / rs.root_extra->out_root_file) || r;
- r = rmdir (src_root / rs.root_extra->bootstrap_dir, 2) || r;
+ r = rmfile (ctx, src_root / rs.root_extra->out_root_file) || r;
+ r = rmdir (ctx, src_root / rs.root_extra->bootstrap_dir, 2) || r;
return r;
}
diff --git a/libbuild2/context.cxx b/libbuild2/context.cxx
index 1b1b9f6..c454123 100644
--- a/libbuild2/context.cxx
+++ b/libbuild2/context.cxx
@@ -50,9 +50,10 @@ namespace build2
};
context::
- context (scheduler& s, const strings& cmd_vars, bool kg)
+ context (scheduler& s, const strings& cmd_vars, bool dr, bool kg)
: data_ (new data (*this)),
sched (s),
+ dry_run_option (dr),
keep_going (kg),
phase_mutex (phase),
scopes (data_->scopes),
@@ -852,8 +853,6 @@ namespace build2
//text << this_thread::get_id () << " phase restore " << n << " " << o;
}
- bool dry_run = false;
-
void (*config_save_variable) (scope&, const variable&, uint64_t);
const string& (*config_preprocess_create) (context&,
diff --git a/libbuild2/context.hxx b/libbuild2/context.hxx
index dbf2329..5060773 100644
--- a/libbuild2/context.hxx
+++ b/libbuild2/context.hxx
@@ -110,6 +110,41 @@ namespace build2
public:
scheduler& sched;
+ // Dry run flag (see --dry-run|-n).
+ //
+ // This flag is set (based on dry_run_option) only for the final execute
+ // phase (as opposed to those that interrupt match) by the perform meta
+ // operation's execute() callback.
+ //
+ // Note that for this mode to function properly we have to use fake
+ // mtimes. Specifically, a rule that pretends to update a target must set
+ // its mtime to system_clock::now() and everyone else must use this cached
+ // value. In other words, there should be no mtime re-query from the
+ // filesystem. The same is required for "logical clean" (i.e., dry-run
+ // 'clean update' in order to see all the command lines).
+ //
+ // At first, it may seem like we should also "dry-run" changes to depdb.
+ // But that would be both problematic (some rules update it in apply()
+ // during the match phase) and wasteful (why discard information). Also,
+ // depdb may serve as an input to some commands (for example, to provide
+ // C++ module mapping) which means that without updating it the commands
+ // we print might not be runnable (think of the compilation database).
+ //
+ // One thing we need to be careful about if we are updating depdb is to
+ // not render the target up-to-date. But in this case the depdb file will
+ // be older than the target which in our model is treated as an
+ // interrupted update (see depdb for details).
+ //
+ // Note also that sometimes it makes sense to do a bit more than
+ // absolutely necessary or to discard information in order to keep the
+ // rule logic sane. And some rules may choose to ignore this flag
+ // altogether. In this case, however, the rule should be careful not to
+ // rely on functions (notably from filesystem) that respect this flag in
+ // order not to end up with a job half done.
+ //
+ bool dry_run = false;
+ bool dry_run_option;
+
// Keep going flag.
//
// Note that setting it to false is not of much help unless we are running
@@ -336,6 +371,7 @@ namespace build2
explicit
context (scheduler&,
const strings& cmd_vars = {},
+ bool dry_run = false,
bool keep_going = true);
// Set current meta-operation and operation.
@@ -481,39 +517,6 @@ namespace build2
bool phase;
};
- // Dry run flag (see --dry-run|-n).
- //
- // This flag is set only for the final execute phase (as opposed to those
- // that interrupt match) by the perform meta operation's execute() callback.
- //
- // Note that for this mode to function properly we have to use fake mtimes.
- // Specifically, a rule that pretends to update a target must set its mtime
- // to system_clock::now() and everyone else must use this cached value. In
- // other words, there should be no mtime re-query from the filesystem. The
- // same is required for "logical clean" (i.e., dry-run 'clean update' in
- // order to see all the command lines).
- //
- // At first, it may seem like we should also "dry-run" changes to depdb. But
- // that would be both problematic (some rules update it in apply() during
- // the match phase) and wasteful (why discard information). Also, depdb may
- // serve as an input to some commands (for example, to provide C++ module
- // mapping) which means that without updating it the commands we print might
- // not be runnable (think of the compilation database).
- //
- // One thing we need to be careful about if we are updating depdb is to not
- // render the target up-to-date. But in this case the depdb file will be
- // older than the target which in our model is treated as an interrupted
- // update (see depdb for details).
- //
- // Note also that sometimes it makes sense to do a bit more than absolutely
- // necessary or to discard information in order to keep the rule logic sane.
- // And some rules may choose to ignore this flag altogether. In this case,
- // however, the rule should be careful not to rely on functions (notably
- // from filesystem) that respect this flag in order not to end up with a
- // job half done.
- //
- LIBBUILD2_SYMEXPORT extern bool dry_run;
-
// Config module entry points.
//
LIBBUILD2_SYMEXPORT extern void (*config_save_variable) (
diff --git a/libbuild2/dist/operation.cxx b/libbuild2/dist/operation.cxx
index 2367329..ad2ee7f 100644
--- a/libbuild2/dist/operation.cxx
+++ b/libbuild2/dist/operation.cxx
@@ -44,7 +44,8 @@ namespace build2
// Return the archive file path.
//
static path
- archive (const dir_path& root,
+ archive (context& ctx,
+ const dir_path& root,
const string& pkg,
const dir_path& dir,
const string& ext);
@@ -54,7 +55,8 @@ namespace build2
// Return the checksum file path.
//
static path
- checksum (const path& arc, const dir_path& dir, const string& ext);
+ checksum (context&,
+ const path& arc, const dir_path& dir, const string& ext);
static operation_id
dist_operation_pre (const values&, operation_id o)
@@ -336,7 +338,7 @@ namespace build2
// Clean up the target directory.
//
- if (build2::rmdir_r (td, true, 2) == rmdir_status::not_empty)
+ if (rmdir_r (ctx, td, true, 2) == rmdir_status::not_empty)
fail << "unable to clean target directory " << td;
auto_rmdir rm_td (td); // Clean it up if things go bad.
@@ -469,14 +471,14 @@ namespace build2
for (const path& p: cast<paths> (as))
{
auto ap (split (p, dist_root, "dist.archives"));
- path a (archive (dist_root, dist_package, ap.first, ap.second));
+ path a (archive (ctx, dist_root, dist_package, ap.first, ap.second));
if (cs)
{
for (const path& p: cast<paths> (cs))
{
auto cp (split (p, ap.first, "dist.checksums"));
- checksum (a, cp.first, cp.second);
+ checksum (ctx, a, cp.first, cp.second);
}
}
}
@@ -543,7 +545,8 @@ namespace build2
}
static path
- archive (const dir_path& root,
+ archive (context& ctx,
+ const dir_path& root,
const string& pkg,
const dir_path& dir,
const string& e)
@@ -554,7 +557,7 @@ namespace build2
//
path ap (dir / an);
if (exists (ap, false))
- rmfile (ap);
+ rmfile (ctx, ap);
// Use zip for .zip archives. Also recognize and handle a few well-known
// tar.xx cases (in case tar doesn't support -a or has other issues like
@@ -715,7 +718,8 @@ namespace build2
}
static path
- checksum (const path& ap, const dir_path& dir, const string& e)
+ checksum (context& ctx,
+ const path& ap, const dir_path& dir, const string& e)
{
path an (ap.leaf ());
dir_path ad (ap.directory ());
@@ -726,7 +730,7 @@ namespace build2
//
path cp (dir / cn);
if (exists (cp, false))
- rmfile (cp);
+ rmfile (ctx, cp);
auto_rmfile c_rm; // Note: must come first.
auto_fd c_fd;
diff --git a/libbuild2/filesystem.cxx b/libbuild2/filesystem.cxx
index 83408fa..1cbaa58 100644
--- a/libbuild2/filesystem.cxx
+++ b/libbuild2/filesystem.cxx
@@ -13,12 +13,12 @@ using namespace butl;
namespace build2
{
void
- touch (const path& p, bool create, uint16_t v)
+ touch (context& ctx, const path& p, bool create, uint16_t v)
{
if (verb >= v)
text << "touch " << p;
- if (dry_run)
+ if (ctx.dry_run)
return;
try
@@ -104,7 +104,7 @@ namespace build2
}
fs_status<rmfile_status>
- rmsymlink (const path& p, bool d, uint16_t v)
+ rmsymlink (context& ctx, const path& p, bool d, uint16_t v)
{
auto print = [&p, v] ()
{
@@ -116,7 +116,7 @@ namespace build2
try
{
- rs = dry_run
+ rs = ctx.dry_run
? (butl::entry_exists (p)
? rmfile_status::success
: rmfile_status::not_exist)
@@ -135,7 +135,7 @@ namespace build2
}
fs_status<butl::rmdir_status>
- rmdir_r (const dir_path& d, bool dir, uint16_t v)
+ rmdir_r (context& ctx, const dir_path& d, bool dir, uint16_t v)
{
using namespace butl;
@@ -148,7 +148,7 @@ namespace build2
if (verb >= v)
text << "rmdir -r " << d;
- if (!dry_run)
+ if (!ctx.dry_run)
{
try
{
@@ -216,7 +216,10 @@ namespace build2
}
fs_status<mkdir_status>
- mkdir_buildignore (const dir_path& d, const path& n, uint16_t verbosity)
+ mkdir_buildignore (context& ctx,
+ const dir_path& d,
+ const path& n,
+ uint16_t verbosity)
{
fs_status<mkdir_status> r (mkdir (d, verbosity));
@@ -225,7 +228,7 @@ namespace build2
//
path p (d / n);
if (r || !exists (p))
- touch (p, true /* create */, verbosity);
+ touch (ctx, p, true /* create */, verbosity);
return r;
}
@@ -253,7 +256,10 @@ namespace build2
}
fs_status<rmdir_status>
- rmdir_buildignore (const dir_path& d, const path& n, uint16_t verbosity)
+ rmdir_buildignore (context& ctx,
+ const dir_path& d,
+ const path& n,
+ uint16_t verbosity)
{
// We should remove the .buildignore file only if the subsequent rmdir()
// will succeed. In other words if the directory stays after the function
@@ -263,12 +269,12 @@ namespace build2
//
path p (d / n);
if (exists (p) && empty_buildignore (d, n) && !work.sub (d))
- rmfile (p, verbosity);
+ rmfile (ctx, p, verbosity);
// Note that in case of a system error the directory is likely to stay with
// the .buildignore file already removed. Trying to restore it feels like
// an overkill here.
//
- return rmdir (d, verbosity);
+ return rmdir (ctx, d, verbosity);
}
}
diff --git a/libbuild2/filesystem.hxx b/libbuild2/filesystem.hxx
index 6dca528..e7b3094 100644
--- a/libbuild2/filesystem.hxx
+++ b/libbuild2/filesystem.hxx
@@ -10,6 +10,8 @@
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
+#include <libbuild2/context.hxx>
+
#include <libbuild2/export.hxx>
// Higher-level filesystem utilities built on top of <libbutl/filesystem.mxx>.
@@ -43,7 +45,7 @@ namespace build2
// create it and fail otherwise.
//
LIBBUILD2_SYMEXPORT void
- touch (const path&, bool create, uint16_t verbosity = 1);
+ touch (context&, const path&, bool create, uint16_t verbosity = 1);
// Return the modification time for an existing regular file and
// timestamp_nonexistent otherwise. Print the diagnostics and fail on system
@@ -88,22 +90,19 @@ namespace build2
fs_status<rmfile_status>
rmfile (const path&, const T& target, uint16_t verbosity = 1);
- inline fs_status<rmfile_status>
- rmfile (const path& f, int verbosity = 1) // Literal overload (int).
- {
- return rmfile (f, f, static_cast<uint16_t> (verbosity));
- }
+ fs_status<rmfile_status>
+ rmfile (context&, const path&, uint16_t verbosity = 1);
- inline fs_status<rmfile_status>
- rmfile (const path& f, uint16_t verbosity) // Overload (verb_never).
- {
- return rmfile (f, f, verbosity);
- }
+ fs_status<rmfile_status>
+ rmfile (const path&, int = 1) = delete;
+
+ fs_status<rmfile_status>
+ rmfile (const path&, uint16_t) = delete;
// Similar to rmfile() but for symlinks.
//
LIBBUILD2_SYMEXPORT fs_status<rmfile_status>
- rmsymlink (const path&, bool dir, uint16_t verbosity);
+ rmsymlink (context&, const path&, bool dir, uint16_t verbosity);
// Similar to rmfile() but for directories (note: not -r).
//
@@ -113,27 +112,26 @@ namespace build2
fs_status<rmdir_status>
rmdir (const dir_path&, const T& target, uint16_t verbosity = 1);
- inline fs_status<rmdir_status>
- rmdir (const dir_path& d, int verbosity = 1) // Literal overload (int).
- {
- return rmdir (d, d, static_cast<uint16_t> (verbosity));
- }
+ fs_status<rmdir_status>
+ rmdir (context&, const dir_path&, uint16_t verbosity = 1);
- inline fs_status<rmdir_status>
- rmdir (const dir_path& d, uint16_t verbosity) // Overload (verb_never).
- {
- return rmdir (d, d, verbosity);
- }
+ fs_status<rmdir_status>
+ rmdir (const dir_path&, int = 1) = delete;
+
+ fs_status<rmdir_status>
+ rmdir (const dir_path&, uint16_t) = delete;
// Remove the directory recursively (unless dry-run) and print the standard
// diagnostics starting from the specified verbosity level. Note that this
// function returns not_empty if we try to remove a working directory. If
// the dir argument is false, then the directory itself is not removed.
//
- // @@ Collides (via ADL) with butl::rmdir_r(), which sucks.
- //
LIBBUILD2_SYMEXPORT fs_status<rmdir_status>
- rmdir_r (const dir_path&, bool dir = true, uint16_t verbosity = 1);
+ rmdir_r (context& ctx,
+ const dir_path&, bool dir = true, uint16_t verbosity = 1);
+
+ fs_status<rmdir_status>
+ rmdir_r (const dir_path&, bool = true, uint16_t = 1) = delete;
// Check for a file, directory or filesystem entry existence. Print the
// diagnostics and fail on system error, unless ignore_error is true.
@@ -163,7 +161,8 @@ namespace build2
// Create a directory containing an empty .buildignore file.
//
LIBBUILD2_SYMEXPORT fs_status<mkdir_status>
- mkdir_buildignore (const dir_path&, const path&, uint16_t verbosity = 1);
+ mkdir_buildignore (context&,
+ const dir_path&, const path&, uint16_t verbosity = 1);
// Return true if the directory is empty or only contains the .buildignore
// file. Fail if the directory doesn't exist.
@@ -174,9 +173,11 @@ namespace build2
// Remove a directory if it is empty or only contains the .buildignore file.
//
LIBBUILD2_SYMEXPORT fs_status<rmdir_status>
- rmdir_buildignore (const dir_path&, const path&, uint16_t verbosity = 1);
+ rmdir_buildignore (context&,
+ const dir_path&, const path&, uint16_t verbosity = 1);
}
+#include <libbuild2/filesystem.ixx>
#include <libbuild2/filesystem.txx>
#endif // LIBBUILD2_FILESYSTEM_HXX
diff --git a/libbuild2/filesystem.ixx b/libbuild2/filesystem.ixx
new file mode 100644
index 0000000..6dab3ad
--- /dev/null
+++ b/libbuild2/filesystem.ixx
@@ -0,0 +1,40 @@
+// file : libbuild2/filesystem.ixx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+namespace build2
+{
+ template <typename T>
+ fs_status<butl::rmfile_status>
+ rmfile (context&, const path&, const T&, uint16_t);
+
+ template <typename T>
+ inline fs_status<rmfile_status>
+ rmfile (const path& f, const T& t, uint16_t v)
+ {
+ return rmfile (t.ctx, f, t, v);
+ }
+
+ inline fs_status<rmfile_status>
+ rmfile (context& ctx, const path& f, uint16_t v)
+ {
+ return rmfile (ctx, f, f, v);
+ }
+
+ template <typename T>
+ fs_status<rmdir_status>
+ rmdir (context&, const dir_path&, const T&, uint16_t);
+
+ template <typename T>
+ inline fs_status<rmdir_status>
+ rmdir (const dir_path& d, const T& t, uint16_t v)
+ {
+ return rmdir (t.ctx, d, t, v);
+ }
+
+ inline fs_status<rmdir_status>
+ rmdir (context& ctx, const dir_path& d, uint16_t v)
+ {
+ return rmdir (ctx, d, d, v);
+ }
+}
diff --git a/libbuild2/filesystem.txx b/libbuild2/filesystem.txx
index 057975a..e3cdef3 100644
--- a/libbuild2/filesystem.txx
+++ b/libbuild2/filesystem.txx
@@ -4,14 +4,13 @@
#include <type_traits> // is_base_of
-#include <libbuild2/context.hxx> // dry_run
#include <libbuild2/diagnostics.hxx>
namespace build2
{
template <typename T>
fs_status<butl::rmfile_status>
- rmfile (const path& f, const T& t, uint16_t v)
+ rmfile (context& ctx, const path& f, const T& t, uint16_t v)
{
using namespace butl;
@@ -34,7 +33,7 @@ namespace build2
try
{
- rs = dry_run
+ rs = ctx.dry_run
? file_exists (f) ? rmfile_status::success : rmfile_status::not_exist
: try_rmfile (f);
}
@@ -52,7 +51,7 @@ namespace build2
template <typename T>
fs_status<butl::rmdir_status>
- rmdir (const dir_path& d, const T& t, uint16_t v)
+ rmdir (context& ctx, const dir_path& d, const T& t, uint16_t v)
{
using namespace butl;
@@ -75,7 +74,7 @@ namespace build2
rmdir_status rs;
try
{
- rs = dry_run
+ rs = ctx.dry_run
? dir_exists (d) ? rmdir_status::success : rmdir_status::not_exist
: !(w = work.sub (d)) ? try_rmdir (d) : rmdir_status::not_empty;
}
diff --git a/libbuild2/install/rule.cxx b/libbuild2/install/rule.cxx
index 478aadd..7cee10e 100644
--- a/libbuild2/install/rule.cxx
+++ b/libbuild2/install/rule.cxx
@@ -698,6 +698,8 @@ namespace build2
const dir_path& d,
bool verbose = true)
{
+ context& ctx (rs.ctx);
+
// Here is the problem: if this is a dry-run, then we will keep showing
// the same directory creation commands over and over again (because we
// don't actually create them). There are two alternative ways to solve
@@ -708,7 +710,7 @@ namespace build2
// with uninstall since the directories won't be empty (because we don't
// actually uninstall any files).
//
- if (dry_run)
+ if (ctx.dry_run)
return;
dir_path chd (chroot_path (rs, d));
@@ -741,7 +743,7 @@ namespace build2
cstrings args;
string reld (
- cast<string> (rs.ctx.global_scope["build.host.class"]) == "windows"
+ cast<string> (ctx.global_scope["build.host.class"]) == "windows"
? msys_path (chd)
: relative (chd).string ());
@@ -780,12 +782,14 @@ namespace build2
const path& f,
bool verbose)
{
+ context& ctx (rs.ctx);
+
path relf (relative (f));
dir_path chd (chroot_path (rs, base.dir));
string reld (
- cast<string> (rs.ctx.global_scope["build.host.class"]) == "windows"
+ cast<string> (ctx.global_scope["build.host.class"]) == "windows"
? msys_path (chd)
: relative (chd).string ());
@@ -818,7 +822,7 @@ namespace build2
else if (verb && verbose)
text << "install " << t;
- if (!dry_run)
+ if (!ctx.dry_run)
run (pp, args);
}
@@ -829,6 +833,8 @@ namespace build2
const path& link,
uint16_t verbosity)
{
+ context& ctx (rs.ctx);
+
path rell (relative (chroot_path (rs, base.dir)));
rell /= link;
@@ -859,7 +865,7 @@ namespace build2
text << "install " << rell << " -> " << target;
}
- if (!dry_run)
+ if (!ctx.dry_run)
run (pp, args);
#else
// The -f part.
@@ -877,7 +883,7 @@ namespace build2
text << "install " << rell << " -> " << target;
}
- if (!dry_run)
+ if (!ctx.dry_run)
try
{
// We have to go the roundabout way by adding directory to the target
@@ -1014,7 +1020,7 @@ namespace build2
{
// See install_d() for the rationale.
//
- if (dry_run)
+ if (rs.ctx.dry_run)
return false;
dir_path chd (chroot_path (rs, d));
@@ -1150,7 +1156,7 @@ namespace build2
if (verb >= verbosity && verb >= 2)
text << "rm " << relf;
- if (!dry_run)
+ if (!rs.ctx.dry_run)
{
try
{
@@ -1179,7 +1185,7 @@ namespace build2
if (verb >= verbosity && verb >= 2)
print_process (args);
- if (!dry_run)
+ if (!rs.ctx.dry_run)
run (pp, args);
}
diff --git a/libbuild2/operation.cxx b/libbuild2/operation.cxx
index ac1c159..080123e 100644
--- a/libbuild2/operation.cxx
+++ b/libbuild2/operation.cxx
@@ -283,7 +283,7 @@ namespace build2
// Set the dry-run flag.
//
- dry_run = dry_run_option;
+ ctx.dry_run = ctx.dry_run_option;
// Setup progress reporting if requested.
//
@@ -356,7 +356,7 @@ namespace build2
// Clear the dry-run flag.
//
- dry_run = false;
+ ctx.dry_run = false;
// Clear the progress if present.
//
diff --git a/libbuild2/test/rule.cxx b/libbuild2/test/rule.cxx
index bd412f5..c0ece26 100644
--- a/libbuild2/test/rule.cxx
+++ b/libbuild2/test/rule.cxx
@@ -438,7 +438,7 @@ namespace build2
if (cast_false<bool> (rs.vars[ctx.var_forwarded]))
{
bl = bs.src_path () / wd.leaf (bs.out_path ());
- clean_backlink (bl, verb_never);
+ clean_backlink (ctx, bl, verb_never);
}
// If this is a (potentially) multi-testscript test, then create (and
@@ -479,7 +479,7 @@ namespace build2
// Remove the directory itself not to confuse the runner which tries
// to detect when tests stomp on each others feet.
//
- build2::rmdir_r (wd, true, 2);
+ rmdir_r (ctx, wd, true, 2);
}
// Delay actually creating the directory in case all the tests are
@@ -491,7 +491,7 @@ namespace build2
//
wait_guard wg;
- if (!dry_run)
+ if (!ctx.dry_run)
wg = wait_guard (ctx, ctx.count_busy (), t[a].task_count);
// Result vector.
@@ -516,11 +516,11 @@ namespace build2
// don't clean the existing one), we are going to ignore it for
// dry-run.
//
- if (!dry_run)
+ if (!ctx.dry_run)
{
if (mk)
{
- mkdir_buildignore (wd, buildignore_file, 2);
+ mkdir_buildignore (ctx, wd, buildignore_file, 2);
mk = false;
}
}
@@ -534,9 +534,11 @@ namespace build2
dr << ' ' << t;
}
- res.push_back (dry_run ? scope_state::passed : scope_state::unknown);
+ res.push_back (ctx.dry_run
+ ? scope_state::passed
+ : scope_state::unknown);
- if (!dry_run)
+ if (!ctx.dry_run)
{
scope_state& r (res.back ());
@@ -567,7 +569,7 @@ namespace build2
}
}
- if (!dry_run)
+ if (!ctx.dry_run)
wg.wait ();
// Re-examine.
@@ -588,7 +590,7 @@ namespace build2
// Cleanup.
//
- if (!dry_run)
+ if (!ctx.dry_run)
{
if (!bad && !one && !mk && after == output_after::clean)
{
@@ -596,7 +598,7 @@ namespace build2
fail << "working directory " << wd << " is not empty at the "
<< "end of the test";
- rmdir_buildignore (wd, buildignore_file, 2);
+ rmdir_buildignore (ctx, wd, buildignore_file, 2);
}
}
@@ -605,8 +607,10 @@ namespace build2
// If we dry-run then presumably all tests passed and we shouldn't
// have anything left unless we are keeping the output.
//
- if (!bl.empty () && (dry_run ? after == output_after::keep : exists (wd)))
- update_backlink (wd, bl, true /* changed */);
+ if (!bl.empty () && (ctx.dry_run
+ ? after == output_after::keep
+ : exists (wd)))
+ update_backlink (ctx, wd, bl, true /* changed */);
if (bad)
throw failed ();
@@ -679,6 +683,8 @@ namespace build2
target_state rule::
perform_test (action a, const target& tt, size_t pass_n) const
{
+ context& ctx (tt.ctx);
+
// First pass through.
//
if (pass_n != 0)
@@ -779,7 +785,7 @@ namespace build2
cat = process (process_exit (0)); // Successfully exited.
- if (!dry_run)
+ if (!ctx.dry_run)
{
try
{
@@ -800,7 +806,7 @@ namespace build2
// If dry-run, the target may not exist.
//
- process_path pp (!dry_run
+ process_path pp (!ctx.dry_run
? run_search (p, true /* init */)
: try_run_search (p, true));
args.push_back (pp.empty () ? p.string ().c_str () : pp.recall_string ());
@@ -865,7 +871,7 @@ namespace build2
else if (verb)
text << "test " << tt;
- if (!dry_run)
+ if (!ctx.dry_run)
{
diag_record dr;
if (!run_test (tt,
diff --git a/libbuild2/test/script/runner.cxx b/libbuild2/test/script/runner.cxx
index c27ad39..53f6741 100644
--- a/libbuild2/test/script/runner.cxx
+++ b/libbuild2/test/script/runner.cxx
@@ -699,6 +699,8 @@ namespace build2
void default_runner::
enter (scope& sp, const location&)
{
+ context& ctx (sp.root.target_scope.ctx);
+
auto df = make_diag_frame (
[&sp](const diag_record& dr)
{
@@ -723,6 +725,7 @@ namespace build2
fs_status<mkdir_status> r (
sp.parent == nullptr
? mkdir_buildignore (
+ ctx,
sp.wd_path,
sp.root.target_scope.root_scope ()->root_extra->buildignore_file,
2)
@@ -744,6 +747,8 @@ namespace build2
void default_runner::
leave (scope& sp, const location& ll)
{
+ context& ctx (sp.root.target_scope.ctx);
+
auto df = make_diag_frame (
[&sp](const diag_record& dr)
{
@@ -766,7 +771,7 @@ namespace build2
{
// Remove the file if exists. Fail otherwise.
//
- if (rmfile (p, 3) == rmfile_status::not_exist)
+ if (rmfile (ctx, p, 3) == rmfile_status::not_exist)
fail (ll) << "registered for cleanup special file " << p
<< " does not exist";
}
@@ -800,9 +805,8 @@ namespace build2
{
bool removed (false);
- auto rm = [&cp, recursive, &removed, &sp, &ll] (path&& pe,
- const string&,
- bool interm)
+ auto rm = [&cp, recursive, &removed, &sp, &ll, &ctx]
+ (path&& pe, const string&, bool interm)
{
if (!interm)
{
@@ -819,7 +823,7 @@ namespace build2
if (!recursive)
{
- rmdir_status r (rmdir (d, 3));
+ rmdir_status r (rmdir (ctx, d, 3));
if (r != rmdir_status::not_empty)
return true;
@@ -839,9 +843,7 @@ namespace build2
// Cast to uint16_t to avoid ambiguity with
// libbutl::rmdir_r().
//
- rmdir_status r (rmdir_r (d,
- d != sp.wd_path,
- static_cast<uint16_t> (3)));
+ rmdir_status r (rmdir_r (ctx, d, d != sp.wd_path, 3));
if (r != rmdir_status::not_empty)
return true;
@@ -854,7 +856,7 @@ namespace build2
}
}
else
- rmfile (pe, 3);
+ rmfile (ctx, pe, 3);
}
return true;
@@ -921,13 +923,14 @@ namespace build2
//
rmdir_status r (
recursive
- ? rmdir_r (d, !wd, static_cast <uint16_t> (v))
+ ? rmdir_r (ctx, d, !wd, static_cast <uint16_t> (v))
: (wd && sp.parent == nullptr
? rmdir_buildignore (
+ ctx,
d,
sp.root.target_scope.root_scope ()->root_extra->buildignore_file,
v)
- : rmdir (d, v)));
+ : rmdir (ctx, d, v)));
if (r == rmdir_status::success ||
(r == rmdir_status::not_exist && t == cleanup_type::maybe))
@@ -948,7 +951,7 @@ namespace build2
// Remove the file if exists. Fail otherwise. Removal of
// non-existing file is not an error for 'maybe' cleanup type.
//
- if (rmfile (p, 3) == rmfile_status::not_exist &&
+ if (rmfile (ctx, p, 3) == rmfile_status::not_exist &&
t == cleanup_type::always)
fail (ll) << "registered for cleanup file " << p
<< " does not exist";
diff --git a/libbuild2/utility.cxx b/libbuild2/utility.cxx
index d08cb31..ba50c5a 100644
--- a/libbuild2/utility.cxx
+++ b/libbuild2/utility.cxx
@@ -81,7 +81,6 @@ namespace build2
: (to_string (build_version.major ()) + '.' +
to_string (build_version.minor ())));
- bool dry_run_option;
optional<bool> mtime_check_option;
optional<path> config_sub;
@@ -495,7 +494,6 @@ namespace build2
void
init (void (*t) (bool),
const char* a0,
- bool dr,
optional<bool> mc,
optional<path> cs,
optional<path> cg)
@@ -504,7 +502,6 @@ namespace build2
argv0 = process::path_search (a0, true);
- dry_run_option = dr;
mtime_check_option = mc;
config_sub = move (cs);
diff --git a/libbuild2/utility.hxx b/libbuild2/utility.hxx
index b5e842d..f7a437e 100644
--- a/libbuild2/utility.hxx
+++ b/libbuild2/utility.hxx
@@ -124,7 +124,6 @@ namespace build2
LIBBUILD2_SYMEXPORT void
init (void (*terminate) (bool),
const char* argv0,
- bool dry_run = false,
optional<bool> mtime_check = nullopt,
optional<path> config_sub = nullopt,
optional<path> config_guess = nullopt);
@@ -143,8 +142,6 @@ namespace build2
LIBBUILD2_SYMEXPORT extern const standard_version build_version;
LIBBUILD2_SYMEXPORT extern const string build_version_interface;
- LIBBUILD2_SYMEXPORT extern bool dry_run_option; // --dry-run
-
// --[no-]mtime-check
//
LIBBUILD2_SYMEXPORT extern optional<bool> mtime_check_option;
diff --git a/libbuild2/version/init.cxx b/libbuild2/version/init.cxx
index 1c123bf..123dc65 100644
--- a/libbuild2/version/init.cxx
+++ b/libbuild2/version/init.cxx
@@ -374,7 +374,8 @@ namespace build2
//
try
{
- auto_rmfile t (fixup_manifest (f,
+ auto_rmfile t (fixup_manifest (rs.ctx,
+ f,
path::temp_path ("manifest"),
m.version));
diff --git a/libbuild2/version/rule.cxx b/libbuild2/version/rule.cxx
index 37e6b0f..fe999b3 100644
--- a/libbuild2/version/rule.cxx
+++ b/libbuild2/version/rule.cxx
@@ -328,7 +328,8 @@ namespace build2
// the out tree. Somehow the latter feels more appropriate (even though
// if we crash in between, we won't clean it up).
//
- return fixup_manifest (p, rs.out_path () / "manifest.t", m.version);
+ return fixup_manifest (
+ t.ctx, p, rs.out_path () / "manifest.t", m.version);
}
}
}
diff --git a/libbuild2/version/utility.cxx b/libbuild2/version/utility.cxx
index 70daab1..0669da7 100644
--- a/libbuild2/version/utility.cxx
+++ b/libbuild2/version/utility.cxx
@@ -17,11 +17,14 @@ namespace build2
namespace version
{
auto_rmfile
- fixup_manifest (const path& in, path out, const standard_version& v)
+ fixup_manifest (context& ctx,
+ const path& in,
+ path out,
+ const standard_version& v)
{
- auto_rmfile r (move (out), !dry_run /* active */);
+ auto_rmfile r (move (out), !ctx.dry_run /* active */);
- if (!dry_run)
+ if (!ctx.dry_run)
{
try
{
diff --git a/libbuild2/version/utility.hxx b/libbuild2/version/utility.hxx
index 16e8c78..170488d 100644
--- a/libbuild2/version/utility.hxx
+++ b/libbuild2/version/utility.hxx
@@ -8,6 +8,7 @@
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
+#include <libbuild2/context.hxx>
#include <libbuild2/filesystem.hxx>
namespace build2
@@ -18,7 +19,10 @@ namespace build2
// not preserve comments. Probably acceptable for snapshots.
//
auto_rmfile
- fixup_manifest (const path& in, path out, const standard_version&);
+ fixup_manifest (context&,
+ const path& in,
+ path out,
+ const standard_version&);
}
}