Skip to content

Commit b08efcc

Browse files
feat: phase-aware Ctrl-C message (setup/tests vs teardown)
During setup/tests: 'Interrupted - running teardown... (press Ctrl-C again to force quit)' During teardown: 'Interrupted during teardown (press Ctrl-C again to force quit)' Uses an IN_TEARDOWN atomic flag set around teardown execution.
1 parent bfc08e6 commit b08efcc

2 files changed

Lines changed: 20 additions & 5 deletions

File tree

crates/cctr/src/main.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use cctr::discover::discover_suites;
33
use cctr::output::Output;
44
use cctr::parse_file;
55
use cctr::runner::{
6-
is_interrupted, run_from_stdin, run_suite, set_interrupted, ProgressEvent, SuiteResult,
6+
is_in_teardown, is_interrupted, run_from_stdin, run_suite, set_interrupted, ProgressEvent,
7+
SuiteResult,
78
};
89
use cctr::update::update_corpus_file;
910
use clap::Parser;
@@ -31,10 +32,17 @@ fn main() -> anyhow::Result<()> {
3132
let _ = writeln!(std::io::stderr(), "\nForce quit");
3233
std::process::exit(130);
3334
}
34-
let _ = writeln!(
35-
std::io::stderr(),
36-
"\nInterrupted - cleaning up... (press Ctrl-C again to force quit)"
37-
);
35+
if is_in_teardown() {
36+
let _ = writeln!(
37+
std::io::stderr(),
38+
"\nInterrupted during teardown (press Ctrl-C again to force quit)"
39+
);
40+
} else {
41+
let _ = writeln!(
42+
std::io::stderr(),
43+
"\nInterrupted - running teardown... (press Ctrl-C again to force quit)"
44+
);
45+
}
3846
set_interrupted();
3947
}) {
4048
eprintln!("Warning: Could not set signal handler: {}", e);

crates/cctr/src/runner.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use tempfile::TempDir;
1313
/// Global flag to indicate the process has been interrupted (SIGINT/SIGTERM)
1414
/// When set, running suites will skip remaining tests but still run teardown
1515
static INTERRUPTED: AtomicBool = AtomicBool::new(false);
16+
static IN_TEARDOWN: AtomicBool = AtomicBool::new(false);
1617

1718
/// Set the interrupted flag - called from signal handler
1819
pub fn set_interrupted() {
@@ -24,6 +25,10 @@ pub fn is_interrupted() -> bool {
2425
INTERRUPTED.load(Ordering::SeqCst)
2526
}
2627

28+
pub fn is_in_teardown() -> bool {
29+
IN_TEARDOWN.load(Ordering::SeqCst)
30+
}
31+
2732
/// Cached bash path - computed once per invocation
2833
static BASH_PATH: OnceLock<String> = OnceLock::new();
2934

@@ -816,6 +821,7 @@ fn run_teardown_if_exists(
816821
file_results: &mut Vec<FileResult>,
817822
) {
818823
if suite.has_teardown {
824+
IN_TEARDOWN.store(true, Ordering::SeqCst);
819825
let teardown_file = suite.path.join("_teardown.txt");
820826
let file_result = run_corpus_file(
821827
&teardown_file,
@@ -828,6 +834,7 @@ fn run_teardown_if_exists(
828834
true, // CRITICAL: Teardown must ALWAYS run, even if interrupted
829835
);
830836
file_results.push(file_result);
837+
IN_TEARDOWN.store(false, Ordering::SeqCst);
831838
}
832839
}
833840

0 commit comments

Comments
 (0)