From 961ba86e5919d8556e9bb1012ba442e7ebe5070f Mon Sep 17 00:00:00 2001 From: nils <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 28 Mar 2023 14:36:32 +0200 Subject: [PATCH] ctrlc --- Cargo.lock | 89 +++++++++++++++++++++++++++++++++++--------- Cargo.toml | 1 + src/lib.rs | 12 ++++-- src/main.rs | 30 ++++++++++++++- src/processor/mod.rs | 17 ++++++++- tests/helper.rs | 7 +++- 6 files changed, 129 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 171b396..9b001ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,6 +31,7 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", + "ctrlc", "libc", "owo-colors", "prettyplease", @@ -96,6 +97,16 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "ctrlc" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639" +dependencies = [ + "nix", + "windows-sys 0.45.0", +] + [[package]] name = "errno" version = "0.2.8" @@ -166,7 +177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -178,7 +189,7 @@ dependencies = [ "hermit-abi 0.2.6", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -223,6 +234,18 @@ dependencies = [ "regex-automata", ] +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "static_assertions", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -378,7 +401,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -442,6 +465,12 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.10.0" @@ -642,43 +671,67 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.0" +name = "windows-sys" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" diff --git a/Cargo.toml b/Cargo.toml index 6e4ca6a..12c537b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ description = "A tool for minimizing rustc ICEs" [dependencies] anyhow = "1.0.65" clap = { version = "4.0.29", features = ["derive"] } +ctrlc = "3.2.5" owo-colors = "3.5.0" prettyplease = { path = "./prettyplease-forked", features = ["verbatim"]} proc-macro2 = { version = "1.0.48", features = ["span-locations"] } diff --git a/src/lib.rs b/src/lib.rs index ff31618..d36e2d4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,11 @@ #[macro_use] extern crate tracing; -use std::{path::PathBuf, str::FromStr}; +use std::{ + path::PathBuf, + str::FromStr, + sync::{atomic::AtomicBool, Arc}, +}; mod build; mod dylib_flag; @@ -94,7 +98,7 @@ pub struct Options { /// Do not touch the following files. #[arg(long)] - pub ignore_file: Vec + pub ignore_file: Vec, } #[derive(Debug, Clone)] @@ -119,7 +123,7 @@ impl FromStr for EnvVar { } } -pub fn minimize(options: Options) -> Result<()> { +pub fn minimize(options: Options, stop: Arc) -> Result<()> { for ignore_file in &options.ignore_file { if !ignore_file.try_exists()? { warn!("Ignored path {} does not exist", ignore_file.display()); @@ -128,7 +132,7 @@ pub fn minimize(options: Options) -> Result<()> { let build = build::Build::new(&options)?; - let mut minimizer = Minimizer::new_glob_dir(options, build)?; + let mut minimizer = Minimizer::new_glob_dir(options, build, stop)?; minimizer.run_passes([ passes::Privatize::default().boxed(), diff --git a/src/main.rs b/src/main.rs index 1410682..677a3f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,11 @@ +#[macro_use] +extern crate tracing; + +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; + use cargo_minimize::{Cargo, Parser}; use tracing::{error, Level}; @@ -6,7 +14,27 @@ fn main() { cargo_minimize::init_recommended_tracing_subscriber(Level::INFO); - if let Err(err) = cargo_minimize::minimize(options) { + let cancel = Arc::new(AtomicBool::new(false)); + let cancel2 = Arc::clone(&cancel); + + let mut ctrl_c_pressed = false; + let result = ctrlc::set_handler(move || { + // If ctrl c was pressed already, kill it now. + if ctrl_c_pressed { + warn!("Process killed"); + std::process::exit(130); + } + + warn!("Shutting down gracefully, press CTRL-C again to kill"); + cancel.store(true, Ordering::SeqCst); + ctrl_c_pressed = true; + }); + + if let Err(err) = result { + error!("Failed to install CTRL-C handler: {err}"); + } + + if let Err(err) = cargo_minimize::minimize(options, cancel2) { error!("An error occured:\n{err}"); } } diff --git a/src/processor/mod.rs b/src/processor/mod.rs index 40c1952..c438029 100644 --- a/src/processor/mod.rs +++ b/src/processor/mod.rs @@ -6,7 +6,9 @@ pub(crate) use self::files::SourceFile; use crate::{build::Build, processor::files::Changes, Options}; use anyhow::{bail, Context, Result}; use owo_colors::OwoColorize; -use std::{collections::HashSet, ffi::OsStr, fmt::Debug}; +use std::sync::atomic::Ordering; +use std::sync::Arc; +use std::{collections::HashSet, ffi::OsStr, fmt::Debug, sync::atomic::AtomicBool}; pub(crate) use self::checker::PassController; @@ -53,6 +55,7 @@ pub(crate) struct Minimizer { files: Vec, build: Build, options: Options, + cancel: Arc, } impl Minimizer { @@ -65,7 +68,11 @@ impl Minimizer { false } - pub(crate) fn new_glob_dir(options: Options, build: Build) -> Result { + pub(crate) fn new_glob_dir( + options: Options, + build: Build, + cancel: Arc, + ) -> Result { let path = &options.path; let walk = walkdir::WalkDir::new(path); @@ -111,6 +118,7 @@ impl Minimizer { files, build, options, + cancel, }) } @@ -216,6 +224,11 @@ impl Minimizer { } } + if self.cancel.load(Ordering::SeqCst) { + info!("Exiting early."); + std::process::exit(0); + } + if checker.is_finished() { break; } diff --git a/tests/helper.rs b/tests/helper.rs index d87a521..4be0378 100644 --- a/tests/helper.rs +++ b/tests/helper.rs @@ -1,4 +1,7 @@ -use std::{process::Command, sync::Mutex}; +use std::{ + process::Command, + sync::{atomic::AtomicBool, Mutex, Arc}, +}; use anyhow::{bail, Result}; use cargo_minimize::Options; @@ -51,7 +54,7 @@ pub fn run_test(code: &str, minimizes_to: &str, options: impl FnOnce(&mut Option opts.path = path; options(&mut opts); - cargo_minimize::minimize(opts)?; + cargo_minimize::minimize(opts, Arc::new(AtomicBool::new(false)))?; let minimized_main_rs = std::fs::read_to_string(main_rs)?;