1- use std:: io:: { self , BufWriter , Write } ;
1+ use std:: io:: { self , stdout , BufWriter , Write } ;
22use std:: process:: { ExitCode , Termination } ;
33
44use anyhow:: Result ;
@@ -39,6 +39,15 @@ pub fn main() -> ExitStatus {
3939 // the configuration it is help to chain errors ("resolving configuration failed" ->
4040 // "failed to read file: subdir/pyproject.toml")
4141 for cause in error. chain ( ) {
42+ // Exit "gracefully" on broken pipe errors.
43+ //
44+ // See: https://github.com/BurntSushi/ripgrep/blob/bf63fe8f258afc09bae6caa48f0ae35eaf115005/crates/core/main.rs#L47C1-L61C14
45+ if let Some ( ioerr) = cause. downcast_ref :: < io:: Error > ( ) {
46+ if ioerr. kind ( ) == io:: ErrorKind :: BrokenPipe {
47+ return ExitStatus :: Success ;
48+ }
49+ }
50+
4251 writeln ! ( stderr, " {} {cause}" , "Cause:" . bold( ) ) . ok ( ) ;
4352 }
4453
@@ -121,7 +130,7 @@ fn run_check(args: CheckCommand) -> anyhow::Result<ExitStatus> {
121130 let exit_status = if watch {
122131 main_loop. watch ( & mut db) ?
123132 } else {
124- main_loop. run ( & mut db)
133+ main_loop. run ( & mut db) ?
125134 } ;
126135
127136 tracing:: trace!( "Counts for entire CLI run:\n {}" , countme:: get_all( ) ) ;
@@ -181,7 +190,7 @@ impl MainLoop {
181190 )
182191 }
183192
184- fn watch ( mut self , db : & mut ProjectDatabase ) -> anyhow :: Result < ExitStatus > {
193+ fn watch ( mut self , db : & mut ProjectDatabase ) -> Result < ExitStatus > {
185194 tracing:: debug!( "Starting watch mode" ) ;
186195 let sender = self . sender . clone ( ) ;
187196 let watcher = watch:: directory_watcher ( move |event| {
@@ -190,12 +199,12 @@ impl MainLoop {
190199
191200 self . watcher = Some ( ProjectWatcher :: new ( watcher, db) ) ;
192201
193- self . run ( db) ;
202+ self . run ( db) ? ;
194203
195204 Ok ( ExitStatus :: Success )
196205 }
197206
198- fn run ( mut self , db : & mut ProjectDatabase ) -> ExitStatus {
207+ fn run ( mut self , db : & mut ProjectDatabase ) -> Result < ExitStatus > {
199208 self . sender . send ( MainLoopMessage :: CheckWorkspace ) . unwrap ( ) ;
200209
201210 let result = self . main_loop ( db) ;
@@ -205,7 +214,7 @@ impl MainLoop {
205214 result
206215 }
207216
208- fn main_loop ( & mut self , db : & mut ProjectDatabase ) -> ExitStatus {
217+ fn main_loop ( & mut self , db : & mut ProjectDatabase ) -> Result < ExitStatus > {
209218 // Schedule the first check.
210219 tracing:: debug!( "Starting main loop" ) ;
211220
@@ -248,9 +257,9 @@ impl MainLoop {
248257 . any ( |diagnostic| diagnostic. severity ( ) >= min_error_severity) ;
249258
250259 if check_revision == revision {
251- # [ allow ( clippy :: print_stdout ) ]
260+ let mut stdout = stdout ( ) . lock ( ) ;
252261 for diagnostic in result {
253- println ! ( "{}" , diagnostic. display( db, & display_config) ) ;
262+ writeln ! ( stdout , "{}" , diagnostic. display( db, & display_config) ) ? ;
254263 }
255264 } else {
256265 tracing:: debug!(
@@ -259,11 +268,11 @@ impl MainLoop {
259268 }
260269
261270 if self . watcher . is_none ( ) {
262- return if failed {
271+ return Ok ( if failed {
263272 ExitStatus :: Failure
264273 } else {
265274 ExitStatus :: Success
266- } ;
275+ } ) ;
267276 }
268277
269278 tracing:: trace!( "Counts after last check:\n {}" , countme:: get_all( ) ) ;
@@ -283,14 +292,14 @@ impl MainLoop {
283292 // TODO: Don't use Salsa internal APIs
284293 // [Zulip-Thread](https://salsa.zulipchat.com/#narrow/stream/333573-salsa-3.2E0/topic/Expose.20an.20API.20to.20cancel.20other.20queries)
285294 let _ = db. zalsa_mut ( ) ;
286- return ExitStatus :: Success ;
295+ return Ok ( ExitStatus :: Success ) ;
287296 }
288297 }
289298
290299 tracing:: debug!( "Waiting for next main loop message." ) ;
291300 }
292301
293- ExitStatus :: Success
302+ Ok ( ExitStatus :: Success )
294303 }
295304}
296305
0 commit comments