console-rs / indicatif Goto Github PK
View Code? Open in Web Editor NEWA command line progress reporting library for Rust
License: MIT License
A command line progress reporting library for Rust
License: MIT License
This looks pretty amazing. Am I use this?
I like it colorful, so I'd like to have the option, to do a progressbar similiar to this one: https://github.com/tripped/progressbar
bar.progress_chars("||-"));
works great!
bar.progress_chars("||"));
panics with error:
thread '<unnamed>' panicked at 'attempt to calculate the remainder with a divisor of zero', /home/cedwards/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:246:32
It's my first time using Rayon and Indicatif so apologies if this is a naive question. I'm trying to use Rayon to iterate over a set of files. Code is like this:
let mp = MultiProgress::new();
// Long calculation is running. Bars are created but do not paint.
let total_bytes: u64 = config.input_files.par_iter()
.map(|f| process_log_file(&mp, f))
.sum();
// This appears first.
println!("Rayon iteration complete");
// Then the bars appear (and update themselves 0..100%) when we get to here.
// But by this point we are done!
mp.join().unwrap();
Inside process_log_file
I am creating a new ProgressBar
, adding it to mp, incrementing it and eventually calling finish
.
As the comments say, the problem is that nothing appears until Rayon's par_iter has actually finished doing work. You have lots of examples of using thread::spawn
and a tokio example, but I couldn't see anything like this.
Is there a fix I can make or is it impossible at the moment?
For reference, the current code in complete form is at https://github.com/PhilipDaniels/log-file-processor/blob/f-rewrite/src/main.rs
Thanks for any advice you can offer.
I have found that the last print is not done when I am using the progress bar. Here is a minimum working case of this behavior. When we remove the progress bar incrementation it works again (the last print is visible).
extern crate indicatif;
use indicatif::ProgressBar;
fn main() {
let n_data = 1_000;
let pb = ProgressBar::new(n_data as u64);
for _ in 0..n_data {
pb.inc(1);
}
println!("Visible");
println!("Not visible");
}
Is there some option to correct it ?
The https://github.com/TheNeikos/spinner library has support for multichar spinners, like https://matthiasbeyer.github.io/imag/spinner/static.DANCING_KIRBY.html, but it does not have support for multiple bars/spinners. Is there any way to switch the tick_chars
method to support strings, or maybe add a method called .tick_strings
that takes a vec of strings?
Calling set_message
or set_prefix
before set_style
causes the style passed to set_style
to not take effect for the first draw. Perhaps set_style
should also call update_and_draw
? Otherwise it would be nice to document somewhere that the user should either call set_style
before any other function or use tick
to force a redraw after changing the style.
I'm reusing a progress bar in a similar fashion to the one described in #49. When I advance to the next step I reset the position to 0, update length to the appropriate value and reset_eta()
. My problem is that the progress bar does not update until it's position is greater than or equal to the length of the bar from the previous step. I believe this is happening because of this line if new_pos >= state.draw_next
.
Issue is pretty simple, I'm getting the following compilation error on Windows. I have the latest rustc
and am getting the error on both nightly
and stable
.
error: no method named `as_raw_handle` found for type `{integer}` in the current scope
--> [cargo installation directory]\indicatif-0.3.1\src\term\windows.rs:19:28
|
19 | GetConsoleMode(out.as_raw_handle(), &mut out) != 0
| ^^^^^^^^^^^^^
error: aborting due to previous error
error: Could not compile `indicatif`.
Spawned off from rustwasm/wasm-pack#284 (comment), but on the current master in an MSYS terminal you get:
$ cargo run --example log
...
Finished dev [unoptimized + debuginfo] target(s) in 30.03s
Running `target\debug\examples\log.exe`
[+] finished #0
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100
[+] finished #1
█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/100
[+] finished #2
██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/100
[+] finished #3
███░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 3/100
[+] finished #4
███░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4/100
[+] finished #5
████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 5/100
[+] finished #6
█████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6/100
[+] finished #7
██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 7/100
[+] finished #8
██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8/100
[+] finished #9
███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 9/100
[+] finished #10
████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 10/100
[+] finished #11
████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 11/100
[+] finished #12
█████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 12/100
We got a report of a panic in the wasm-pack
issue tracker that seems to be some bad string slicing in indicatif::utils::pad_str
:
Relevant portion of the stack trace:
6: 0x561b9a7eab33 - std::panicking::rust_panic_with_hook::h0e12cb2fc86d00fa
at libstd/panicking.rs:481
7: 0x561b9a7ea699 - std::panicking::continue_panic_fmt::h141671b29fe0e27d
at libstd/panicking.rs:391
8: 0x561b9a7ea595 - rust_begin_unwind
at libstd/panicking.rs:326
9: 0x561b9a83f6cb - core::panicking::panic_fmt::h429a06507aba9228
at libcore/panicking.rs:77
10: 0x561b9a8417df - core::str::slice_error_fail::he7f58755ae0832f9
at libcore/str/mod.rs:0
11: 0x561b9a630967 - core::str::traits::<impl core::slice::SliceIndex<str> for core::ops::range::RangeTo<usize>>::index::{{closure}}::h0e5e8ea169b43852
12: 0x561b9a630f6f - indicatif::utils::pad_str::h2463675fdede442d
13: 0x561b9a626cab - indicatif::progress::draw_state::h53128cfecbded1e8
14: 0x561b9a626434 - indicatif::progress::ProgressBar::set_message::hcd6d894753c95d95
It should be possible to easily render progress bars when working with iterators.
Eg:
let pb = ProgressBar::new(length);
for item in pb.wrap_iter(something.iter()) {
...
}
Would be roughly similar to this:
let pb = ProgressBar::new(length);
for item in something.iter() {
...
pb.inc(1);
}
This would work well with #6.
I didn't find anything in the API to handle resuming some kind of progress and get an accurate ETA.
My use case is equivalent to resuming a 12h long download after 10% has been already downloaded.
Right now I just recreate a progress bar and set_position
to the amount of data that has already been downloaded. The ETA displayed is then strongly biased because from indicatif
point of view, 10% were downloaded in a few seconds.
I'm confused because ProgressDrawTarget::to_term
takes Term
by-value.
Request for a convenient feature of having a percent
key added to the ProgressStyle
template.
The value of this percent
key would be the result of bytes
/ total_bytes
This is really helpful when showing progress as a percentage .e.g. 50%
ProgressBar
and MultiProgress
both share the common refresh rate mechanism (via set_draw_target
). But since the rate limiting occurs at the final draw stage, MultiProgress
gets much more slower than ProgressBar
alone when there are more than thousands of state updates.
In my naive benchmark, which makes one ProgressBar
, optionally adds it to MultiProgress
, and runs 1,000,000 inc(1)
calls:
MultiProgress
it took 9.6 seconds (104,000 calls/s);MultiProgress
it took 69.2 seconds (14,400 calls/s).I expect that along with the MPSC Sender
the refresh rate should be shared across ProgressBar
s.
Running the following sample code in ms windows 10 and msys2, power shell don't produce the outputs of finish_with_message function:
use std::thread;
use std::time::Duration;
use indicatif::ProgressBar;
fn main() {
let pb = indicatif::ProgressBar::new(100);
for _i in 0..100 {
pb.inc(1);
thread::sleep(Duration::from_millis(500));
}
pb.finish_with_message("done");
}
For me, using MultiProgress results in tons of flickering as the update step clears all the bars and redraws. Maybe this is because I'm using the program through ssh, but it's annoying.
I tried changing the call to term.clear_last_lines
to term.move_cursor_up
and it's way way better. Is there a reason not to do this?
I'm imagining there could be problems if the number of bars doesn't stay constant, so maybe it would have to be an option.
Hello,
My program updates bar quite heavy and I found that it cause MultiProgressBar looks quite bad - it flickers all the time.
I run examples from the crate and see the same problem for multibar and finebars.
Did check examples in windows console, but I see the same problem with my program on linux+putty.
I suppose it could be connected to #18
Regards,
I'm using a single progress bar to show the progress of a series of steps, by resetting progress and length whenever advancing to the next step. It seems like that confuses the ETA, though. It ends up way overestimating (~minutes rather than ~seconds).
If you specify more progress bars than rows in your terminal window then it prints all the progress bars as new lines - it doesn't erase them properly.
I guess ideally it would maintain an internal buffer of what the output should be and only try to print the visible lines. When the terminal is resized it could reveal more lines.
This commit: 7a13000 has made it so that unless there's a change to the current value, no update will happen. This means that, unless I also want to increase the value:
An immediate fix would be to make ProgressState.draw_delta and ProgressState.draw_next default to 0 instead of 1, so that all updates are applied immediately by default, and let the draw delta behavior be opt-in for those who need performance.
A better fix would be to apply this draw delta logic only to .inc() calls, but I can't see an easy way to do that. Alternatively, keep another counter that gets updated every time .update_and_draw() is called, and track that against draw_delta.
If you have an idea for how to approach this I can work on a pull request if you'd like.
There is for some reason no documentation, of which color options are available.
I briefly tried out the library and was disappointed by the default progress bar. It'd be nice if the GIFs were linked to an example of the progress bar that it's showing.
It seems that the default implementation draws to stderr, but whether the output is colorized is dependent on whether stdout is a tty, so if you do something like foo > log
, you get progress bars, but they're uncolored.
I'm not sure if there's a reasonable fix here without a lot of rearchitecting: it seems to me that console needs to be in charge of printing a styled string, to be able to know whether it should be colorized or not.
If set_message()
is too long and "squeezes" the progress bar too much, it panics with attempt to subtract with overflow'
.
Minimal example:
extern crate indicatif;
use indicatif::ProgressBar;
fn main() {
let pb = ProgressBar::new(100);
pb.set_style(
indicatif::ProgressStyle::default_bar()
.template("{wide_bar:.cyan/blue} {pos:>6}/{len:6} {msg}"),
);
for i in 0..100 {
pb.inc(1);
pb.set_message(&format!(
"*********************************************************************************************************************************"
));
std::thread::sleep_ms(10);
}
pb.finish();
}
Backtrace:
-> echo $COLUMNS && cargo run
143
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/tind`
██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/100
thread 'main' panicked at 'attempt to subtract with overflow', /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:309:37
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at libstd/sys_common/backtrace.rs:59
at libstd/panicking.rs:380
3: std::panicking::default_hook
at libstd/panicking.rs:396
4: std::panicking::begin_panic
at libstd/panicking.rs:576
5: std::panicking::begin_panic
at libstd/panicking.rs:537
6: std::panicking::try::do_call
at libstd/panicking.rs:521
7: std::panicking::try::do_call
at libstd/panicking.rs:497
8: <core::ops::range::Range<Idx> as core::fmt::Debug>::fmt
at libcore/panicking.rs:71
9: <core::ops::range::Range<Idx> as core::fmt::Debug>::fmt
at libcore/panicking.rs:51
10: indicatif::progress::ProgressStyle::format_state
at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:309
11: indicatif::progress::draw_state
at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:666
12: indicatif::progress::ProgressBar::draw
at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:652
13: indicatif::progress::ProgressBar::update_and_draw
at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:648
14: indicatif::progress::ProgressBar::inc::{{closure}}
at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:573
15: tind::main
at src/main.rs:12
16: std::rt::lang_start::{{closure}}
at /Users/travis/build/rust-lang/rust/src/libstd/rt.rs:74
17: std::panicking::try::do_call
at libstd/rt.rs:59
at libstd/panicking.rs:479
18: panic_unwind::dwarf::eh::read_encoded_pointer
at libpanic_unwind/lib.rs:102
19: rust_panic
at libstd/panicking.rs:458
at libstd/panic.rs:358
at libstd/rt.rs:58
20: std::rt::lang_start
at /Users/travis/build/rust-lang/rust/src/libstd/rt.rs:74
Related to #45.
A new version was tagged 9 days ago. The version on crates.io hasn't been updated in 8 months.
extern crate indicatif;
use indicatif::ProgressBar;
fn main() {
let pb = ProgressBar::new(1);
pb.inc(2);
pb.finish();
}
thread 'main' panicked at 'attempt to subtract with overflow', src/progress.rs:220
stack backtrace:
0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at /checkout/src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at /checkout/src/libstd/sys_common/backtrace.rs:60
at /checkout/src/libstd/panicking.rs:355
3: std::panicking::default_hook
at /checkout/src/libstd/panicking.rs:371
4: std::panicking::rust_panic_with_hook
at /checkout/src/libstd/panicking.rs:549
5: std::panicking::begin_panic
at /checkout/src/libstd/panicking.rs:511
6: std::panicking::begin_panic_fmt
at /checkout/src/libstd/panicking.rs:495
7: rust_begin_unwind
at /checkout/src/libstd/panicking.rs:471
8: core::panicking::panic_fmt
at /checkout/src/libcore/panicking.rs:69
9: core::panicking::panic
at /checkout/src/libcore/panicking.rs:49
10: indicatif::progress::ProgressStyle::format_bar
at ./src/progress.rs:220
11: indicatif::progress::ProgressStyle::format_state
at ./src/progress.rs:269
12: indicatif::progress::ProgressBar::draw
at ./src/progress.rs:539
13: indicatif::progress::ProgressBar::update_and_draw
at ./src/progress.rs:526
14: indicatif::progress::ProgressBar::set_position
at ./src/progress.rs:445
15: single::main
at ./examples/single.rs:6
16: std::panicking::try::do_call
at /checkout/src/libstd/panicking.rs:454
17: __rust_maybe_catch_panic
at /checkout/src/libpanic_unwind/lib.rs:98
18: std::rt::lang_start
at /checkout/src/libstd/panicking.rs:433
at /checkout/src/libstd/panic.rs:361
at /checkout/src/libstd/rt.rs:57
19: main
20: __libc_start_main
21: _start
After reading the docs I was expecting that one could create a spinner ProgressBar, set enable_steady_tick(200)
on it and it would be automatically ticked and rendered every 200 ms.
But when I tried that the spinner is not updating or re-drawn automatically, unless I also call either ticker
set_message` on the progress bar manually, which sort of defeats the point of it.
This can be reproduced in the cargowrap.rs
example by simply commenting out the pb.set_message
and pb.tick
calls. Doing that will cause the spinner to be stuck.
Or am I misunderstanding how enable_steady_tick
is intended to work?
If I set a template that is too large for the terminal window, the inc()
call panics.
Minimal example:
extern crate indicatif;
use indicatif::ProgressBar;
fn main() {
let pb = ProgressBar::new(100);
pb.set_style(indicatif::ProgressStyle::default_bar()
.template("{wide_bar:.cyan/blue} {pos:>6}/{len:6} ************************************************************************************************************************************************************************************"));
for i in 0..100 {
pb.inc(1);
std::thread::sleep_ms(10);
}
pb.finish();
}
Backtrace:
-> echo $COLUMNS && cargo run
143
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/tind`
thread 'main' panicked at 'attempt to subtract with overflow', /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:309:37
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at libstd/sys_common/backtrace.rs:59
at libstd/panicking.rs:380
3: std::panicking::default_hook
at libstd/panicking.rs:396
4: std::panicking::begin_panic
at libstd/panicking.rs:576
5: std::panicking::begin_panic
at libstd/panicking.rs:537
6: std::panicking::try::do_call
at libstd/panicking.rs:521
7: std::panicking::try::do_call
at libstd/panicking.rs:497
8: <core::ops::range::Range<Idx> as core::fmt::Debug>::fmt
at libcore/panicking.rs:71
9: <core::ops::range::Range<Idx> as core::fmt::Debug>::fmt
at libcore/panicking.rs:51
10: indicatif::progress::ProgressStyle::format_state
at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:309
11: indicatif::progress::draw_state
at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:666
12: indicatif::progress::ProgressBar::draw
at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:652
13: indicatif::progress::ProgressBar::update_and_draw
at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:648
14: indicatif::progress::ProgressState::eta
at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:534
15: tind::main
at src/main.rs:9
16: std::rt::lang_start::{{closure}}
at /Users/travis/build/rust-lang/rust/src/libstd/rt.rs:74
17: std::panicking::try::do_call
at libstd/rt.rs:59
at libstd/panicking.rs:479
18: panic_unwind::dwarf::eh::read_encoded_pointer
at libpanic_unwind/lib.rs:102
19: rust_panic
at libstd/panicking.rs:458
at libstd/panic.rs:358
at libstd/rt.rs:58
20: std::rt::lang_start
at /Users/travis/build/rust-lang/rust/src/libstd/rt.rs:74
21: tind::main
Note that the above panic happens for a terminal window of width 143 columns.
MultiProgress
seems to conflate support for displaying and update multiple progress bars concurrently and support for updating progress bars from multiple threads. It would be nice to isolate these so that a single thread performing multiple tasks can effectively use MultiProgress
. Inter-thread communication could perhaps even be left up to the user.
Currently messages with println!()
are overwritten by the next progress bar tick. It would be awesome to have something like pb.log("hello")
and have hello printed with the next tick above the bars.
Minimal example:
let bar = ProgressBar::new(100);
bar.set_style(
indicatif::ProgressStyle::default_bar()
.template("[{bar:60}] [{percent}%] {msg}")
.progress_chars("=> "),
);
for i in 0..10 {
std::thread::sleep_ms(1000);
bar.set_message(&i.to_string());
bar.set_position(i * 10);
}
The progress bar looks like
[======> ] [10%] 2
Note the percent and message are out of sync. If I add enable_steady_tick
to the progress bar they sync up, but if I do
for i in 0..10 {
std::thread::sleep_ms(1000);
bar.set_message(&i.to_string());
bar.set_position(i * 10);
bar.tick();
}
I get the same issue. If I add some delay between the calls like
for i in 0..10 {
std::thread::sleep_ms(900);
bar.set_message(&i.to_string());
std::thread::sleep_ms(100);
bar.set_position(i * 10);
}
it works fine apart from the 100ms delay when the percent and message are out of sync
Edit: After looking at the code it looks like this is due to the refresh rate cap set by ProgressDrawTarget
, and is intended behaviour. I have created a PR to hopefully make this more obvious to new users of the library.
Currently, the Estimate::time_per_step
returns Duration
. This limits the precision and range that time per step can represent – Duration
always stores multiples of nanosecods. Moreover, if your step takes less than nanosecond, time per step would be 0, and the ETA would be always 00:00:00. This is how I discovered the bug.
TLDR: Here is list of speeds that indicatif currently supports: :)
…, ¼GB/s, ⅓GB/s, ½GB/s, 1GB/s, ∞YB/s.
Hi,
I'm coming from tqdm in Python and one of my favourite features there is that it shows the current iteration rate, e.g. [229.00it/s]:
76%|████████████████████████████ | 7568/10000 [00:33<00:10, 229.00it/s]
This is particularly useful if you're watching a process where a slow-down or uptake in iterations can indicate an issue.
I would be great to have something similar in indicatif, so I just wanted to open this issue to start discussing.
From a quick skim over both projects we'd obviously need a formatter in https://github.com/mitsuhiko/indicatif/blob/master/src/style.rs#L116.
It'd also need slightly advanced tracking of iteration times, see avg_time
here: https://github.com/tqdm/tqdm/blob/master/tqdm/_tqdm.py#L1011
The smoothing of recent iteration times is really useful, and often more interesting than just total time divided by iterations.
I could imagine the same being useful for e.g. the download example, in addition to seeing 71/220MB are done you'd also know you're getting 15MB/sec.
Edit: Looks like we already have https://github.com/mitsuhiko/indicatif/blob/master/src/utils.rs#L18, so this might be easier than expected.
Would be nice to have optional sub-second precision here.
ProgressBar::finish
should clear with a style default setting. This would also help Drop
automatically clear progress bars if wanted.
eg:
let style = ProgressStyle::new().clear_on_finish(true);
Then the progress bar will automatically disappear if someone calls finish()
on it.
It would be great if one can directly wrap files so it works with io::copy
and others.
See crossbeam-rs/crossbeam#180
Doing a std::thread::spawn
inside a crossbeam::scope(|s| s.spawn(|| std::thread::spawn(|| ...))
should be necessary.
The following gist contains two files, works.rs works properly, fails.rs produces no output.
https://gist.github.com/gnzlbg/09d7e546df2215bee83fc5fe02840292
It would be useful to be able to force a progress bar to be displayed even if the terminal is not attended.
My use case for this is for attended cluster jobs, where the output does get relayed to a terminal but it does so via a network pipe from the cluster node.
I seem to be unable to join a MultiProgress
containing hidden ProgressBar
s. I would have expected this to work, or alternatively to be able to figure out a workaround from the documentation.
#[test]
fn hangs() {
let m = MultiProgress::new();
let p = m.add(ProgressBar::new(1));
p.set_draw_target(ProgressDrawTarget::hidden());
p.finish_and_clear();
m.join_and_clear();
}
Might seem silly to have a progress bar with 0 size but it can come up in real world use cases. For example file system operations like copy with an empty file.
extern crate indicatif;
use indicatif::ProgressBar;
fn main() {
let pb = ProgressBar::new(0);
pb.finish();
}
Hello,
using rustc
1.32.0, ProgressBar rendering is broken when using opt-level=z
.
I get the raw template (only total_bytes
is actually templated):
{spinner:.green} [{elapsed_precise}] [{bar:30.cyan/blue}] {bytes}/207.49MB (4s)
instead of:
⠒ [00:00:01] [####>-------------------------] 27.67MB/207.49MB (6s)
Here is my code:
let pb = ProgressBar::new(size as u64);
pb.set_style(ProgressStyle::default_bar()
.template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})")
.progress_chars("#>-"));
pb.enable_steady_tick(200);
let mut progress = gpm::file::FileProgressWriter::new(
file,
size,
|p : usize, _t : usize| {
pb.set_position(p as u64);
}
);
lfs::resolve_lfs_link(
remote.parse().unwrap(),
Some(refspec.clone()),
&package_path,
&mut progress,
key,
passphrase,
).map_err(CommandError::IO)?;
pb.finish();
It works as expected when setting opt-level = "s"
or lto = false
.
You can easily reproduce the issue by adding:
[profile.release]
opt-level = "z"
lto = true
to Cargo.toml
and run cargo run --release --example download
.
When using an MSYS terminal on Windows I unfortunately get no output when using indicatif
which can be seen notably by executing the examples. Opening up a prompt and executing cargo run --example log
unfortunately produces no output :(
indicatif 0.9 used to show a good ETA estimate after the the first .inc(1)
update, but 0.10 seems to require around ten .inc(1)
calls until it shows the first ETA that is non-zero.
In my use case, a single "tick" can easily last multiple seconds, so this is easy to notice. Minimal example to reproduce:
extern crate indicatif;
use std::thread;
use std::time::Duration;
use indicatif::{ProgressBar, ProgressStyle};
fn main() {
let count = 15;
let pb = ProgressBar::new(count);
pb.set_style(
ProgressStyle::default_bar()
.template("{wide_bar} Elapsed: {elapsed_precise}, ETA: {eta_precise}")
);
for _ in 0..count {
thread::sleep(Duration::from_millis(1000));
pb.inc(1);
}
pb.finish_with_message("done");
}
After 9 seconds, it still shows:
███████████████████░░░░░░░░░░░░░ Elapsed: 00:00:09, ETA: 00:00:00
I observed that spinners do not spin while a child process runs that was spawned with std::process::Command
. Especially when they are in a multibar. I created a small example that shows the issue: https://github.com/migerh/indicatif-multibar
The use_multibar_with_timeout_for_finish() example shows that while the child process is running, the spinners in the multibar do not update. They start spinning as soon as the child process finishes, though.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.