console-rs / indicatif

A command line progress reporting library for Rust
MIT License
4.43k stars 243 forks source link

Second ProgressBar can't be cleared if set_position before added to MultiProgress #502

Open zhangkaizhao opened 1 year ago

zhangkaizhao commented 1 year ago

I have no idea if this is a bug. Tested with indicatif == 0.17.2.

The good one which can be cleared when set_position after added to MultiProgress:

use indicatif::{MultiProgress, ProgressBar, ProgressStyle};

fn main() {
    let mp = MultiProgress::new();
    let pb = ProgressBar::new(0);
    let style = ProgressStyle::with_template("{msg}").unwrap();
    pb.set_style(style);
    mp.add(pb.clone());

    let pb2 = ProgressBar::new(100);
    let style2 = ProgressStyle::with_template("{bar}").unwrap();
    pb2.set_style(style2);
    mp.add(pb2.clone());
    pb2.set_position(0);
    pb2.finish_and_clear();

    pb.set_message("Good!");
    pb.finish();
}

Output:

Good!

The bad one which can't be cleared when set_position before added to MultiProgress:

use indicatif::{MultiProgress, ProgressBar, ProgressStyle};

fn main() {
    let mp = MultiProgress::new();
    let pb = ProgressBar::new(0);
    let style = ProgressStyle::with_template("{msg}").unwrap();
    pb.set_style(style);
    mp.add(pb.clone());

    let pb2 = ProgressBar::new(100);
    let style2 = ProgressStyle::with_template("{bar}").unwrap();
    pb2.set_style(style2);
    pb2.set_position(0);
    mp.add(pb2.clone());
    pb2.finish_and_clear();

    pb.set_message("Bad!");
    pb.finish();
}

Output:

░░░░░░░░░░░░░░░░░░░░
Bad!
chris-laplante commented 1 year ago

The problem here is that we cannot make any guarantees about what happens when you add a ProgressBar to a MultiProgress after that ProgressBar has already been drawn. In other words, MultiProgress assumes that ProgressBars that have been added to it have never been drawn before. So I am inclined to close this as "not a bug".

djc commented 1 year ago

In other words, MultiProgress assumes that ProgressBars that have been added to it have never been drawn before.

Hmm, I'm not sure this is all that obvious? Why is this a necessary requirement? And how does it influence this particular behavior?