console-rs / indicatif

A command line progress reporting library for Rust
MIT License
4.21k stars 238 forks source link

Finished progress bars are not preserved in `MultiProgress::println` #614

Closed Mottl closed 6 months ago

Mottl commented 6 months ago

MultiProgress::println doesn't redraw finished progress bars:

use std::time::Duration;
use indicatif::{MultiProgress, ProgressBar};

fn main() {
    eprintln!("Finished progress bars are preserved:");
    let multi = MultiProgress::new();
    for _ in 0..3 {
        let pg = multi.add(ProgressBar::new(5));
        for _ in 0..5 {
            std::thread::sleep(Duration::from_millis(100));
            pg.inc(1);
        }
        pg.finish();
    }

    eprintln!("\n\nFinished progress bars are not preserved");
    let multi = MultiProgress::new();
    for _ in 0..3 {
        let pg = multi.add(ProgressBar::new(5));
        for _ in 0..5 {
            std::thread::sleep(Duration::from_millis(100));
            pg.inc(1);
            multi.println("message").unwrap();
        }
        pg.finish();
    }
}
djc commented 6 months ago

Have you tried setting the preferred behavior using ProgressBar::with_finish()?

Mottl commented 6 months ago

Yes, the same behavior

chris-laplante commented 6 months ago

The ProgressBars are going out of scope so MultiProgress is forgetting about them. You need to clone them and keep them from getting dropped:

use std::time::Duration;
use indicatif::{MultiProgress, ProgressBar};

fn main() {
    eprintln!("Finished progress bars are preserved:");
    let multi = MultiProgress::new();
    for _ in 0..3 {
        let pg = multi.add(ProgressBar::new(5));
        for _ in 0..5 {
            std::thread::sleep(Duration::from_millis(100));
            pg.inc(1);
        }
        pg.finish();
    }

    eprintln!("\n\nFinished progress bars are not preserved");
    let mut keep = vec![];
    let multi = MultiProgress::new();
    for _ in 0..3 {
        let pg = multi.add(ProgressBar::new(5));
        keep.push(pg.clone());
        for _ in 0..5 {
            std::thread::sleep(Duration::from_millis(100));
            pg.inc(1);
            multi.println("message").unwrap();
        }
        pg.finish();
    }
}
chris-laplante commented 6 months ago

Related #595

Mottl commented 6 months ago

Thanks a lot, Chris 👍️️️️️️ Probably, we could add this to FAQ or in docs.

chris-laplante commented 6 months ago

Thanks a lot, Chris 👍️️️️️️ Probably, we could add this to FAQ or in docs.

You're welcome! And yes absolutely, that's what #595 is about :)