123 lines
3.7 KiB
Rust
123 lines
3.7 KiB
Rust
|
use std::sync::{mpsc, Arc, Mutex};
|
||
|
use std::thread;
|
||
|
use std::time::{Duration, Instant};
|
||
|
|
||
|
use console::{Style, Term};
|
||
|
use indicatif::{HumanDuration, ProgressBar, ProgressStyle};
|
||
|
use rand::Rng;
|
||
|
|
||
|
static CRATES: &[(&str, &str)] = &[
|
||
|
("console", "v0.14.1"),
|
||
|
("lazy_static", "v1.4.0"),
|
||
|
("libc", "v0.2.93"),
|
||
|
("regex", "v1.4.6"),
|
||
|
("regex-syntax", "v0.6.23"),
|
||
|
("terminal_size", "v0.1.16"),
|
||
|
("libc", "v0.2.93"),
|
||
|
("unicode-width", "v0.1.8"),
|
||
|
("lazy_static", "v1.4.0"),
|
||
|
("number_prefix", "v0.4.0"),
|
||
|
("regex", "v1.4.6"),
|
||
|
("rand", "v0.8.3"),
|
||
|
("getrandom", "v0.2.2"),
|
||
|
("cfg-if", "v1.0.0"),
|
||
|
("libc", "v0.2.93"),
|
||
|
("rand_chacha", "v0.3.0"),
|
||
|
("ppv-lite86", "v0.2.10"),
|
||
|
("rand_core", "v0.6.2"),
|
||
|
("getrandom", "v0.2.2"),
|
||
|
("rand_core", "v0.6.2"),
|
||
|
("tokio", "v1.5.0"),
|
||
|
("bytes", "v1.0.1"),
|
||
|
("pin-project-lite", "v0.2.6"),
|
||
|
("slab", "v0.4.3"),
|
||
|
("indicatif", "v0.15.0"),
|
||
|
];
|
||
|
|
||
|
fn main() {
|
||
|
// number of cpus
|
||
|
const NUM_CPUS: usize = 4;
|
||
|
let start = Instant::now();
|
||
|
|
||
|
// mimic cargo progress bar although it behaves a bit different
|
||
|
let pb = ProgressBar::new(CRATES.len() as u64);
|
||
|
pb.set_style(
|
||
|
ProgressStyle::with_template(
|
||
|
// note that bar size is fixed unlike cargo which is dynamic
|
||
|
// and also the truncation in cargo uses trailers (`...`)
|
||
|
if Term::stdout().size().1 > 80 {
|
||
|
"{prefix:>12.cyan.bold} [{bar:57}] {pos}/{len} {wide_msg}"
|
||
|
} else {
|
||
|
"{prefix:>12.cyan.bold} [{bar:57}] {pos}/{len}"
|
||
|
},
|
||
|
)
|
||
|
.unwrap()
|
||
|
.progress_chars("=> "),
|
||
|
);
|
||
|
pb.set_prefix("Building");
|
||
|
|
||
|
// process in another thread
|
||
|
// crates to be iterated but not exactly a tree
|
||
|
let crates = Arc::new(Mutex::new(CRATES.iter()));
|
||
|
let (tx, rx) = mpsc::channel();
|
||
|
for n in 0..NUM_CPUS {
|
||
|
let tx = tx.clone();
|
||
|
let crates = crates.clone();
|
||
|
thread::spawn(move || {
|
||
|
let mut rng = rand::thread_rng();
|
||
|
loop {
|
||
|
let krate = crates.lock().unwrap().next();
|
||
|
// notify main thread if n thread is processing a crate
|
||
|
tx.send((n, krate)).unwrap();
|
||
|
if let Some(krate) = krate {
|
||
|
thread::sleep(Duration::from_millis(
|
||
|
// last compile and linking is always slow, let's mimic that
|
||
|
if CRATES.last() == Some(krate) {
|
||
|
rng.gen_range(1_000..2_000)
|
||
|
} else {
|
||
|
rng.gen_range(250..1_000)
|
||
|
},
|
||
|
));
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
// drop tx to stop waiting
|
||
|
drop(tx);
|
||
|
|
||
|
let green_bold = Style::new().green().bold();
|
||
|
|
||
|
// do progress drawing in main thread
|
||
|
let mut processing = [None; NUM_CPUS];
|
||
|
while let Ok((n, krate)) = rx.recv() {
|
||
|
processing[n] = krate;
|
||
|
let crates: Vec<&str> = processing
|
||
|
.iter()
|
||
|
.filter_map(|t| t.copied().map(|(name, _)| name))
|
||
|
.collect();
|
||
|
pb.set_message(crates.join(", "));
|
||
|
if let Some((name, version)) = krate {
|
||
|
// crate is being built
|
||
|
let line = format!(
|
||
|
"{:>12} {} {}",
|
||
|
green_bold.apply_to("Compiling"),
|
||
|
name,
|
||
|
version
|
||
|
);
|
||
|
pb.println(line);
|
||
|
|
||
|
pb.inc(1);
|
||
|
}
|
||
|
}
|
||
|
pb.finish_and_clear();
|
||
|
|
||
|
// compilation is finished
|
||
|
println!(
|
||
|
"{:>12} dev [unoptimized + debuginfo] target(s) in {}",
|
||
|
green_bold.apply_to("Finished"),
|
||
|
HumanDuration(start.elapsed())
|
||
|
);
|
||
|
}
|