aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/b.cxx12
-rw-r--r--build2/config/operation.cxx13
-rw-r--r--build2/diagnostics.hxx16
-rw-r--r--build2/dist/operation.cxx65
-rw-r--r--build2/operation.cxx17
-rw-r--r--build2/operation.hxx17
6 files changed, 103 insertions, 37 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index 945d375..ad54922 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -1255,10 +1255,10 @@ main (int argc, char* argv[])
uint16_t diag (ops.structured_result () ? 0 : 1);
if (mif->match != nullptr)
- mif->match (mparams, a, tgs, diag);
+ mif->match (mparams, a, tgs, diag, true /* progress */);
if (mif->execute != nullptr && !ops.match_only ())
- mif->execute (mparams, a, tgs, diag);
+ mif->execute (mparams, a, tgs, diag, true /* progress */);
}
if (mif->operation_post != nullptr)
@@ -1279,10 +1279,10 @@ main (int argc, char* argv[])
uint16_t diag (ops.structured_result () ? 0 : 2);
if (mif->match != nullptr)
- mif->match (mparams, a, tgs, diag);
+ mif->match (mparams, a, tgs, diag, true /* progress */);
if (mif->execute != nullptr && !ops.match_only ())
- mif->execute (mparams, a, tgs, diag);
+ mif->execute (mparams, a, tgs, diag, true /* progress */);
}
if (post_oid != 0)
@@ -1304,10 +1304,10 @@ main (int argc, char* argv[])
uint16_t diag (ops.structured_result () ? 0 : 1);
if (mif->match != nullptr)
- mif->match (mparams, a, tgs, diag);
+ mif->match (mparams, a, tgs, diag, true /* progress */);
if (mif->execute != nullptr && !ops.match_only ())
- mif->execute (mparams, a, tgs, diag);
+ mif->execute (mparams, a, tgs, diag, true /* progress */);
}
if (mif->operation_post != nullptr)
diff --git a/build2/config/operation.cxx b/build2/config/operation.cxx
index a284f65..65592c5 100644
--- a/build2/config/operation.cxx
+++ b/build2/config/operation.cxx
@@ -348,13 +348,14 @@ namespace build2
}
static void
- configure_match (const values&, action, action_targets&, uint16_t)
+ configure_match (const values&, action, action_targets&, uint16_t, bool)
{
// Don't match anything -- see execute ().
}
static void
- configure_execute (const values&, action a, action_targets& ts, uint16_t)
+ configure_execute (const values&, action a, action_targets& ts,
+ uint16_t, bool)
{
// Match rules to configure every operation supported by each
// project. Note that we are not calling operation_pre/post()
@@ -497,7 +498,7 @@ namespace build2
}
static void
- disfigure_match (const values&, action, action_targets&, uint16_t)
+ disfigure_match (const values&, action, action_targets&, uint16_t, bool)
{
}
@@ -595,10 +596,8 @@ namespace build2
}
static void
- disfigure_execute (const values&,
- action a,
- action_targets& ts,
- uint16_t diag)
+ disfigure_execute (const values&, action a, action_targets& ts,
+ uint16_t diag, bool)
{
tracer trace ("disfigure_execute");
diff --git a/build2/diagnostics.hxx b/build2/diagnostics.hxx
index b9757d6..5ec2ef0 100644
--- a/build2/diagnostics.hxx
+++ b/build2/diagnostics.hxx
@@ -143,6 +143,22 @@ namespace build2
os.iword (stream_verb_index) = static_cast<long> (v.value_) + 1;
}
+ // Progress reporting.
+ //
+ using butl::diag_progress;
+ using butl::diag_progress_lock;
+
+ // Return true if progress is to be shown. The max_verb argument is the
+ // maximum verbosity level that this type of progress should be shown by
+ // default.
+ //
+ inline bool
+ show_progress (uint16_t max_verb)
+ {
+ return ops.progress () ||
+ (stderr_term && verb >= 1 && verb <= max_verb && !ops.no_progress ());
+ }
+
// Diagnostic facility, base infrastructure.
//
using butl::diag_stream_lock;
diff --git a/build2/dist/operation.cxx b/build2/dist/operation.cxx
index dfba163..c8cc60d 100644
--- a/build2/dist/operation.cxx
+++ b/build2/dist/operation.cxx
@@ -54,7 +54,8 @@ namespace build2
}
static void
- dist_execute (const values&, action, action_targets& ts, uint16_t)
+ dist_execute (const values&, action, action_targets& ts,
+ uint16_t, bool prog)
{
tracer trace ("dist_execute");
@@ -128,7 +129,8 @@ namespace build2
// Skip aliases (e.g., update-for-install). In fact, one can argue
// the default update should be sufficient since it is assumed to
// update all prerequisites and we no longer support ad hoc stuff
- // like test.input.
+ // like test.input. Though here we are using the dist meta-operation,
+ // not perform.
//
if (oif->id != id)
continue;
@@ -142,13 +144,17 @@ namespace build2
const operation_info* poif (rs->operations[pid]);
set_current_oif (*poif, oif);
action a (dist_id, poif->id, oif->id);
- match (params, a, ts, 1 /* diag (failures only) */);
+ match (params, a, ts,
+ 1 /* diag (failures only) */,
+ false /* progress */);
}
}
set_current_oif (*oif);
action a (dist_id, oif->id);
- match (params, a, ts, 1 /* diag (failures only) */);
+ match (params, a, ts,
+ 1 /* diag (failures only) */,
+ false /* progress */);
if (oif->post != nullptr)
{
@@ -157,7 +163,9 @@ namespace build2
const operation_info* poif (rs->operations[pid]);
set_current_oif (*poif, oif);
action a (dist_id, poif->id, oif->id);
- match (params, a, ts, 1 /* diag (failures only) */);
+ match (params, a, ts,
+ 1 /* diag (failures only) */,
+ false /* progress */);
}
}
}
@@ -214,6 +222,9 @@ namespace build2
// Collect the files. We want to take the snapshot of targets since
// updating some of them may result in more targets being entered.
//
+ // Note that we are not showing progress here (e.g., "N targets to
+ // distribute") since it will be useless (too fast).
+ //
action_targets files;
const variable& dist_var (var_pool["dist"]);
@@ -279,8 +290,13 @@ namespace build2
action a (perform_id, update_id);
- mo_perform.match (params, a, files, 1 /* diag (failures only) */);
- mo_perform.execute (params, a, files, 1 /* diag (failures only) */);
+ mo_perform.match (params, a, files,
+ 1 /* diag (failures only) */,
+ prog /* progress */);
+
+ mo_perform.execute (params, a, files,
+ 1 /* diag (failures only) */,
+ prog /* progress */);
if (mo_perform.operation_post != nullptr)
mo_perform.operation_post (params, update_id);
@@ -293,8 +309,6 @@ namespace build2
// Clean up the target directory.
//
- // @@ Not for incremental dist?
- //
if (build2::rmdir_r (td) == rmdir_status::not_empty)
fail << "unable to clean target directory " << td;
@@ -304,9 +318,12 @@ namespace build2
//
module& mod (*rs->modules.lookup<module> (module::name));
- for (const action_target& at: files)
+ prog = prog && show_progress (1 /* max_verb */);
+ size_t prog_percent (0);
+
+ for (size_t i (0), n (files.size ()); i != n; ++i)
{
- const file& t (*at.as_target ().is_a<file> ());
+ const file& t (*files[i].as_target ().is_a<file> ());
// Figure out where this file is inside the target directory.
//
@@ -365,6 +382,32 @@ namespace build2
if (path_match (pat.leaf ().string (), t.path ().leaf ().string ()))
cb.function (r, *srs, cb.data);
}
+
+ if (prog)
+ {
+ // Note that this is not merely an optimization since if stderr is
+ // not a terminal, we print real lines for progress.
+ //
+ size_t p ((i * 100) / n);
+
+ if (prog_percent != p)
+ {
+ prog_percent = p;
+
+ diag_progress_lock pl;
+ diag_progress = ' ';
+ diag_progress += to_string (prog_percent);
+ diag_progress += "% of targets distributed";
+ }
+ }
+ }
+
+ // Clear the progress if shown.
+ //
+ if (prog)
+ {
+ diag_progress_lock pl;
+ diag_progress.clear ();
}
// Archive if requested.
diff --git a/build2/operation.cxx b/build2/operation.cxx
index eaacc6d..dabebcc 100644
--- a/build2/operation.cxx
+++ b/build2/operation.cxx
@@ -112,7 +112,7 @@ namespace build2
}
void
- match (const values&, action a, action_targets& ts, uint16_t diag)
+ match (const values&, action a, action_targets& ts, uint16_t diag, bool prog)
{
tracer trace ("match");
@@ -126,8 +126,8 @@ namespace build2
//
string what; // Note: must outlive monitor_guard.
scheduler::monitor_guard mg;
- if (ops.progress () ||
- (stderr_term && verb >= 1 && verb <= 2 && !ops.no_progress ()))
+
+ if (prog && show_progress (2 /* max_verb */))
{
size_t incr (stderr_term ? 1 : 10); // Scale depending on output type.
@@ -240,7 +240,8 @@ namespace build2
}
void
- execute (const values&, action a, action_targets& ts, uint16_t diag)
+ execute (const values&, action a, action_targets& ts,
+ uint16_t diag, bool prog)
{
tracer trace ("execute");
@@ -265,12 +266,10 @@ namespace build2
string what; // Note: must outlive monitor_guard.
scheduler::monitor_guard mg;
- if (ops.progress () || (stderr_term && verb == 1 && !ops.no_progress ()))
+ if (prog && show_progress (1 /* max_verb */))
{
size_t init (target_count.load (memory_order_relaxed));
- size_t incr (init / 100); // 1%.
- if (incr == 0)
- incr = 1;
+ size_t incr (init > 100 ? init / 100 : 1); // 1%.
if (init != incr)
{
@@ -476,7 +475,7 @@ namespace build2
}
static void
- info_execute (const values&, action, action_targets& ts, uint16_t)
+ info_execute (const values&, action, action_targets& ts, uint16_t, bool)
{
for (size_t i (0); i != ts.size (); ++i)
{
diff --git a/build2/operation.hxx b/build2/operation.hxx
index 27f2356..fd8ca0c 100644
--- a/build2/operation.hxx
+++ b/build2/operation.hxx
@@ -293,8 +293,15 @@ namespace build2
// 1 - failures only (for pre-operations).
// 2 - all (for normal operations).
//
- void (*match) (const values&, action, action_targets&, uint16_t diag);
- void (*execute) (const values&, action, action_targets&, uint16_t diag);
+ // The false progress argument can be used to suppress progress. If it is
+ // true, then whether the progress is shown is meta operation-specific (in
+ // other words, you can suppress it but not force it).
+ //
+ void (*match) (const values&, action, action_targets&,
+ uint16_t diag, bool progress);
+
+ void (*execute) (const values&, action, action_targets&,
+ uint16_t diag, bool progress);
// Start of operation and meta-operation batches.
//
@@ -333,14 +340,16 @@ namespace build2
action_targets&);
void
- match (const values&, action, action_targets&, uint16_t diag);
+ match (const values&, action, action_targets&,
+ uint16_t diag, bool prog);
// Execute the action on the list of targets. This is the default
// implementation that does just that while issuing appropriate
// diagnostics (unless quiet).
//
void
- execute (const values&, action, const action_targets&, uint16_t diag);
+ execute (const values&, action, const action_targets&,
+ uint16_t diag, bool prog);
extern const meta_operation_info mo_noop;
extern const meta_operation_info mo_perform;