##// END OF EJS Templates
rust-hg-cpython: add an `HgProgressBar` util...
Raphaël Gomès -
r52935:92e23ba2 default
parent child Browse files
Show More
@@ -231,6 +231,19 dependencies = [
231 ]
231 ]
232
232
233 [[package]]
233 [[package]]
234 name = "console"
235 version = "0.15.8"
236 source = "registry+https://github.com/rust-lang/crates.io-index"
237 checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
238 dependencies = [
239 "encode_unicode",
240 "lazy_static",
241 "libc",
242 "unicode-width",
243 "windows-sys 0.52.0",
244 ]
245
246 [[package]]
234 name = "convert_case"
247 name = "convert_case"
235 version = "0.4.0"
248 version = "0.4.0"
236 source = "registry+https://github.com/rust-lang/crates.io-index"
249 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -451,6 +464,12 source = "registry+https://github.com/ru
451 checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
464 checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
452
465
453 [[package]]
466 [[package]]
467 name = "encode_unicode"
468 version = "0.3.6"
469 source = "registry+https://github.com/rust-lang/crates.io-index"
470 checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
471
472 [[package]]
454 name = "env_logger"
473 name = "env_logger"
455 version = "0.9.3"
474 version = "0.9.3"
456 source = "registry+https://github.com/rust-lang/crates.io-index"
475 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -609,6 +628,7 dependencies = [
609 "hashbrown 0.13.1",
628 "hashbrown 0.13.1",
610 "home",
629 "home",
611 "im-rc",
630 "im-rc",
631 "indicatif",
612 "itertools",
632 "itertools",
613 "lazy_static",
633 "lazy_static",
614 "libc",
634 "libc",
@@ -711,6 +731,19 dependencies = [
711 ]
731 ]
712
732
713 [[package]]
733 [[package]]
734 name = "indicatif"
735 version = "0.17.8"
736 source = "registry+https://github.com/rust-lang/crates.io-index"
737 checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3"
738 dependencies = [
739 "console",
740 "instant",
741 "number_prefix",
742 "portable-atomic",
743 "unicode-width",
744 ]
745
746 [[package]]
714 name = "instant"
747 name = "instant"
715 version = "0.1.12"
748 version = "0.1.12"
716 source = "registry+https://github.com/rust-lang/crates.io-index"
749 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -890,6 +923,12 dependencies = [
890 ]
923 ]
891
924
892 [[package]]
925 [[package]]
926 name = "number_prefix"
927 version = "0.4.0"
928 source = "registry+https://github.com/rust-lang/crates.io-index"
929 checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
930
931 [[package]]
893 name = "once_cell"
932 name = "once_cell"
894 version = "1.16.0"
933 version = "1.16.0"
895 source = "registry+https://github.com/rust-lang/crates.io-index"
934 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -938,6 +977,12 source = "registry+https://github.com/ru
938 checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
977 checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
939
978
940 [[package]]
979 [[package]]
980 name = "portable-atomic"
981 version = "1.9.0"
982 source = "registry+https://github.com/rust-lang/crates.io-index"
983 checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2"
984
985 [[package]]
941 name = "ppv-lite86"
986 name = "ppv-lite86"
942 version = "0.2.17"
987 version = "0.2.17"
943 source = "registry+https://github.com/rust-lang/crates.io-index"
988 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1646,6 +1691,15 dependencies = [
1646
1691
1647 [[package]]
1692 [[package]]
1648 name = "windows-sys"
1693 name = "windows-sys"
1694 version = "0.52.0"
1695 source = "registry+https://github.com/rust-lang/crates.io-index"
1696 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
1697 dependencies = [
1698 "windows-targets 0.52.6",
1699 ]
1700
1701 [[package]]
1702 name = "windows-sys"
1649 version = "0.59.0"
1703 version = "0.59.0"
1650 source = "registry+https://github.com/rust-lang/crates.io-index"
1704 source = "registry+https://github.com/rust-lang/crates.io-index"
1651 checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
1705 checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
@@ -16,6 +16,7 derive_more = "0.99.17"
16 hashbrown = { version = "0.13.1", features = ["rayon"] }
16 hashbrown = { version = "0.13.1", features = ["rayon"] }
17 home = "0.5.4"
17 home = "0.5.4"
18 im-rc = "15.1.0"
18 im-rc = "15.1.0"
19 indicatif = "0.17.8"
19 itertools = "0.10.5"
20 itertools = "0.10.5"
20 lazy_static = "1.4.0"
21 lazy_static = "1.4.0"
21 libc = "0.2.137"
22 libc = "0.2.137"
@@ -1,5 +1,12
1 //! Progress-bar related things
1 //! Progress-bar related things
2
2
3 use std::{
4 sync::atomic::{AtomicBool, Ordering},
5 time::Duration,
6 };
7
8 use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
9
3 /// A generic determinate progress bar trait
10 /// A generic determinate progress bar trait
4 pub trait Progress: Send + Sync + 'static {
11 pub trait Progress: Send + Sync + 'static {
5 /// Set the current position and optionally the total
12 /// Set the current position and optionally the total
@@ -9,3 +16,77 pub trait Progress: Send + Sync + 'stati
9 /// Declare that progress is over and the progress bar should be deleted
16 /// Declare that progress is over and the progress bar should be deleted
10 fn complete(self);
17 fn complete(self);
11 }
18 }
19
20 const PROGRESS_DELAY: Duration = Duration::from_secs(1);
21
22 /// A generic (determinate) progress bar. Stays hidden until [`PROGRESS_DELAY`]
23 /// to prevent flickering a progress bar for super fast operations.
24 pub struct HgProgressBar {
25 progress: ProgressBar,
26 has_been_shown: AtomicBool,
27 }
28
29 impl HgProgressBar {
30 // TODO pass config to check progress.disable/assume-tty/delay/etc.
31 /// Return a new progress bar with `topic` as the prefix.
32 /// The progress and total are both set to 0, and it is hidden until the
33 /// next call to `update` given that more than a second has elapsed.
34 pub fn new(topic: &str) -> Self {
35 let template =
36 format!("{} {{wide_bar}} {{pos}}/{{len}} {{eta}} ", topic);
37 let style = ProgressStyle::with_template(&template).unwrap();
38 let progress_bar = ProgressBar::new(0).with_style(style);
39 // Hide the progress bar and only show it if we've elapsed more
40 // than a second
41 progress_bar.set_draw_target(ProgressDrawTarget::hidden());
42 Self {
43 progress: progress_bar,
44 has_been_shown: false.into(),
45 }
46 }
47
48 /// Called whenever the progress changes to determine whether to start
49 /// showing the progress bar
50 fn maybe_show(&self) {
51 if self.progress.is_hidden()
52 && self.progress.elapsed() > PROGRESS_DELAY
53 {
54 // Catch a race condition whereby we check if it's hidden, then
55 // set the draw target from another thread, then do it again from
56 // this thread, which results in multiple progress bar lines being
57 // left drawn.
58 let has_been_shown =
59 self.has_been_shown.fetch_or(true, Ordering::Relaxed);
60 if !has_been_shown {
61 // Here we are certain that we're the only thread that has
62 // set `has_been_shown` and we can change the draw target
63 self.progress.set_draw_target(ProgressDrawTarget::stderr());
64 self.progress.tick();
65 }
66 }
67 }
68 }
69
70 impl Progress for HgProgressBar {
71 fn update(&self, pos: u64, total: Option<u64>) {
72 self.progress.update(|state| {
73 state.set_pos(pos);
74 if let Some(t) = total {
75 state.set_len(t)
76 }
77 });
78 self.maybe_show();
79 }
80
81 fn increment(&self, step: u64, total: Option<u64>) {
82 self.progress.inc(step);
83 if let Some(t) = total {
84 self.progress.set_length(t)
85 }
86 self.maybe_show();
87 }
88
89 fn complete(self) {
90 self.progress.finish_and_clear();
91 }
92 }
General Comments 0
You need to be logged in to leave comments. Login now