diff --git a/Cargo.lock b/Cargo.lock index e437542..dd0bd67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -348,6 +348,19 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -450,6 +463,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -490,8 +509,10 @@ dependencies = [ "cargo_metadata", "clap", "clap_complete", + "indicatif", "inferno", "opener", + "scopeguard", "shlex", "signal-hook", ] @@ -706,6 +727,19 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + [[package]] name = "inferno" version = "0.11.19" @@ -736,6 +770,15 @@ dependencies = [ "smallvec", ] +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + [[package]] name = "ipnet" version = "2.9.0" @@ -768,6 +811,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.153" @@ -895,6 +944,12 @@ dependencies = [ "itoa", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.30.4" @@ -994,6 +1049,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + [[package]] name = "powerfmt" version = "0.2.0" @@ -1538,6 +1599,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index a44cb02..1b786c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,10 @@ anyhow = "1.0.43" cargo_metadata = "0.18" clap = { version = "4.0.11", features = ["derive"] } clap_complete = "4.0.2" +indicatif = "0.17.8" inferno = { version = "0.11.0", default_features = false, features = ["multithreaded", "nameattr"] } opener = "0.7.1" +scopeguard = "1.2.0" shlex = "1.1.0" [target.'cfg(unix)'.dependencies] diff --git a/src/lib.rs b/src/lib.rs index 58b0d03..e72c340 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,10 @@ pub enum Workload { #[cfg(target_os = "linux")] mod arch { + use indicatif::{ProgressBar, ProgressStyle}; + use scopeguard; + use std::time::Duration; + use super::*; pub const SPAWN_ERROR: &str = "could not spawn perf"; @@ -116,6 +120,20 @@ mod arch { command.arg(perf_output); } + // perf script can take a long time to run. Notify the user that it is running + // by using a spinner. Ensure that the spinner gets cleaned up regardless of how + // this function exits by using a scopeguard. + let spinner = ProgressBar::new_spinner().with_prefix("Running perf script"); + spinner.set_style( + ProgressStyle::with_template("{prefix} [{elapsed}]: {spinner:.green}") + .unwrap() + .tick_strings(&[".", "..", "...", " ..", " .", "", "✓"]), + ); + spinner.enable_steady_tick(Duration::from_millis(500)); + let _guard = scopeguard::guard(spinner, |spinner| { + spinner.finish(); + }); + let output = command.output().context("unable to call perf script")?; if !output.status.success() { anyhow::bail!(format!(