5
5
#![ warn( rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros) ]
6
6
7
7
use std:: {
8
+ ffi:: OsString ,
8
9
fmt, io,
10
+ path:: PathBuf ,
9
11
process:: { ChildStderr , ChildStdout , Command , Stdio } ,
10
12
time:: Duration ,
11
13
} ;
@@ -168,7 +170,7 @@ struct FlycheckActor {
168
170
/// doesn't provide a way to read sub-process output without blocking, so we
169
171
/// have to wrap sub-processes output handling in a thread and pass messages
170
172
/// back over a channel.
171
- cargo_handle : Option < CargoHandle > ,
173
+ command_handle : Option < CommandHandle > ,
172
174
}
173
175
174
176
enum Event {
@@ -184,15 +186,15 @@ impl FlycheckActor {
184
186
workspace_root : AbsPathBuf ,
185
187
) -> FlycheckActor {
186
188
tracing:: info!( %id, ?workspace_root, "Spawning flycheck" ) ;
187
- FlycheckActor { id, sender, config, root : workspace_root, cargo_handle : None }
189
+ FlycheckActor { id, sender, config, root : workspace_root, command_handle : None }
188
190
}
189
191
190
192
fn report_progress ( & self , progress : Progress ) {
191
193
self . send ( Message :: Progress { id : self . id , progress } ) ;
192
194
}
193
195
194
196
fn next_event ( & self , inbox : & Receiver < StateChange > ) -> Option < Event > {
195
- let check_chan = self . cargo_handle . as_ref ( ) . map ( |cargo| & cargo. receiver ) ;
197
+ let check_chan = self . command_handle . as_ref ( ) . map ( |cargo| & cargo. receiver ) ;
196
198
if let Ok ( msg) = inbox. try_recv ( ) {
197
199
// give restarts a preference so check outputs don't block a restart or stop
198
200
return Some ( Event :: RequestStateChange ( msg) ) ;
@@ -221,21 +223,19 @@ impl FlycheckActor {
221
223
}
222
224
223
225
let command = self . check_command ( ) ;
226
+ let formatted_command = format ! ( "{:?}" , command) ;
227
+
224
228
tracing:: debug!( ?command, "will restart flycheck" ) ;
225
- match CargoHandle :: spawn ( command) {
226
- Ok ( cargo_handle) => {
227
- tracing:: debug!(
228
- command = ?self . check_command( ) ,
229
- "did restart flycheck"
230
- ) ;
231
- self . cargo_handle = Some ( cargo_handle) ;
229
+ match CommandHandle :: spawn ( command) {
230
+ Ok ( command_handle) => {
231
+ tracing:: debug!( command = formatted_command, "did restart flycheck" ) ;
232
+ self . command_handle = Some ( command_handle) ;
232
233
self . report_progress ( Progress :: DidStart ) ;
233
234
}
234
235
Err ( error) => {
235
236
self . report_progress ( Progress :: DidFailToRestart ( format ! (
236
- "Failed to run the following command: {:?} error={}" ,
237
- self . check_command( ) ,
238
- error
237
+ "Failed to run the following command: {} error={}" ,
238
+ formatted_command, error
239
239
) ) ) ;
240
240
}
241
241
}
@@ -244,12 +244,14 @@ impl FlycheckActor {
244
244
tracing:: debug!( flycheck_id = self . id, "flycheck finished" ) ;
245
245
246
246
// Watcher finished
247
- let cargo_handle = self . cargo_handle . take ( ) . unwrap ( ) ;
248
- let res = cargo_handle. join ( ) ;
247
+ let command_handle = self . command_handle . take ( ) . unwrap ( ) ;
248
+ let formatted_handle = format ! ( "{:?}" , command_handle) ;
249
+
250
+ let res = command_handle. join ( ) ;
249
251
if res. is_err ( ) {
250
252
tracing:: error!(
251
- "Flycheck failed to run the following command: {:? }" ,
252
- self . check_command ( )
253
+ "Flycheck failed to run the following command: {}" ,
254
+ formatted_handle
253
255
) ;
254
256
}
255
257
self . report_progress ( Progress :: DidFinish ( res) ) ;
@@ -284,12 +286,12 @@ impl FlycheckActor {
284
286
}
285
287
286
288
fn cancel_check_process ( & mut self ) {
287
- if let Some ( cargo_handle ) = self . cargo_handle . take ( ) {
289
+ if let Some ( command_handle ) = self . command_handle . take ( ) {
288
290
tracing:: debug!(
289
- command = ?self . check_command ( ) ,
291
+ command = ?command_handle ,
290
292
"did cancel flycheck"
291
293
) ;
292
- cargo_handle . cancel ( ) ;
294
+ command_handle . cancel ( ) ;
293
295
self . report_progress ( Progress :: DidCancel ) ;
294
296
}
295
297
}
@@ -391,19 +393,36 @@ impl Drop for JodGroupChild {
391
393
}
392
394
393
395
/// A handle to a cargo process used for fly-checking.
394
- struct CargoHandle {
396
+ struct CommandHandle {
395
397
/// The handle to the actual cargo process. As we cannot cancel directly from with
396
398
/// a read syscall dropping and therefore terminating the process is our best option.
397
399
child : JodGroupChild ,
398
400
thread : stdx:: thread:: JoinHandle < io:: Result < ( bool , String ) > > ,
399
401
receiver : Receiver < CargoMessage > ,
402
+ program : OsString ,
403
+ arguments : Vec < OsString > ,
404
+ current_dir : Option < PathBuf > ,
400
405
}
401
406
402
- impl CargoHandle {
403
- fn spawn ( mut command : Command ) -> std:: io:: Result < CargoHandle > {
407
+ impl fmt:: Debug for CommandHandle {
408
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
409
+ f. debug_struct ( "CommandHandle" )
410
+ . field ( "program" , & self . program )
411
+ . field ( "arguments" , & self . arguments )
412
+ . field ( "current_dir" , & self . current_dir )
413
+ . finish ( )
414
+ }
415
+ }
416
+
417
+ impl CommandHandle {
418
+ fn spawn ( mut command : Command ) -> std:: io:: Result < CommandHandle > {
404
419
command. stdout ( Stdio :: piped ( ) ) . stderr ( Stdio :: piped ( ) ) . stdin ( Stdio :: null ( ) ) ;
405
420
let mut child = command. group_spawn ( ) . map ( JodGroupChild ) ?;
406
421
422
+ let program = command. get_program ( ) . into ( ) ;
423
+ let arguments = command. get_args ( ) . map ( |arg| arg. into ( ) ) . collect :: < Vec < OsString > > ( ) ;
424
+ let current_dir = command. get_current_dir ( ) . map ( |arg| arg. to_path_buf ( ) ) ;
425
+
407
426
let stdout = child. 0 . inner ( ) . stdout . take ( ) . unwrap ( ) ;
408
427
let stderr = child. 0 . inner ( ) . stderr . take ( ) . unwrap ( ) ;
409
428
@@ -413,7 +432,7 @@ impl CargoHandle {
413
432
. name ( "CargoHandle" . to_owned ( ) )
414
433
. spawn ( move || actor. run ( ) )
415
434
. expect ( "failed to spawn thread" ) ;
416
- Ok ( CargoHandle { child, thread, receiver } )
435
+ Ok ( CommandHandle { program , arguments , current_dir , child, thread, receiver } )
417
436
}
418
437
419
438
fn cancel ( mut self ) {
0 commit comments