Skip to content

Commit 766d123

Browse files
fables-talesclaude
andauthored
Fix --check mode to exit non-zero on syntax errors (#797)
* Fix --check mode to exit non-zero on syntax errors Previously, --check would exit with code 0 even when syntax errors were encountered in input files. This changes the check mode to track errors and exit with code 1 (SyntaxError) when any syntax errors occur. Also adds tests for --check with syntax errors for both file and stdin input. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Run rustfmt Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent d13c321 commit 766d123

File tree

2 files changed

+68
-13
lines changed

2 files changed

+68
-13
lines changed

src/main.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -343,18 +343,30 @@ fn main() {
343343
match opts {
344344
CommandlineOpts { check: true, .. } => {
345345
let text_diffs: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new()));
346-
347-
iterate_formatted(&opts, &|(file_path, before, after)| match after {
348-
None => {}
349-
Some(fmtted) => {
350-
let diff = TextDiff::from_lines(before, &fmtted);
351-
let path_string = file_path.to_str().unwrap();
352-
text_diffs.lock().unwrap().push(format!(
353-
"{}",
354-
diff.unified_diff().header(path_string, path_string)
355-
));
356-
}
357-
});
346+
let errors_count: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
347+
348+
iterate_input_files(
349+
&opts,
350+
&|(file_path, before)| match rubyfmt_string(&opts, before) {
351+
Ok(None) => {}
352+
Ok(Some(fmtted)) => {
353+
let diff = TextDiff::from_lines(before, &fmtted);
354+
let path_string = file_path.to_str().unwrap();
355+
text_diffs.lock().unwrap().push(format!(
356+
"{}",
357+
diff.unified_diff().header(path_string, path_string)
358+
));
359+
}
360+
Err(e) => {
361+
handle_rubyfmt_error(
362+
e,
363+
&file_path.display().to_string(),
364+
ErrorExit::NoExit,
365+
);
366+
*errors_count.lock().unwrap() += 1;
367+
}
368+
},
369+
);
358370

359371
let all_diffs = text_diffs.lock().unwrap();
360372

@@ -366,7 +378,10 @@ fn main() {
366378
diffs_reported += 1
367379
}
368380
}
369-
if diffs_reported > 0 {
381+
let errors = *errors_count.lock().unwrap();
382+
if errors > 0 {
383+
exit(rubyfmt::FormatError::SyntaxError as i32);
384+
} else if diffs_reported > 0 {
370385
exit(rubyfmt::FormatError::DiffDetected as i32);
371386
} else {
372387
exit(0)

tests/cli_interface_test.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,46 @@ fn format_input_file_without_changes() {
499499
assert_eq!("a(1, 2, 3)\n", read_to_string(file_one.path()).unwrap());
500500
}
501501

502+
#[test]
503+
fn test_check_flag_with_syntax_error() {
504+
let mut file = NamedTempFile::new().unwrap();
505+
// Use actually invalid Ruby syntax (incomplete def statement)
506+
writeln!(file, "def (").unwrap();
507+
508+
let output = Command::cargo_bin("rubyfmt-main")
509+
.unwrap()
510+
.arg(file.path())
511+
.arg("--check")
512+
.assert()
513+
.code(1)
514+
.failure();
515+
516+
let stderr = String::from_utf8_lossy(&output.get_output().stderr);
517+
assert!(
518+
stderr.contains("syntax error"),
519+
"Expected stderr to contain 'syntax error', got: {}",
520+
stderr
521+
);
522+
}
523+
524+
#[test]
525+
fn test_check_flag_stdin_with_syntax_error() {
526+
let output = Command::cargo_bin("rubyfmt-main")
527+
.unwrap()
528+
.arg("--check")
529+
.write_stdin("def (")
530+
.assert()
531+
.code(1)
532+
.failure();
533+
534+
let stderr = String::from_utf8_lossy(&output.get_output().stderr);
535+
assert!(
536+
stderr.contains("syntax error"),
537+
"Expected stderr to contain 'syntax error', got: {}",
538+
stderr
539+
);
540+
}
541+
502542
#[test]
503543
fn test_format_respects_opt_in_header() {
504544
let mut file_one = NamedTempFile::new().unwrap();

0 commit comments

Comments
 (0)