@@ -85,8 +85,9 @@ impl FlycheckHandle {
85
85
sender : Box < dyn Fn ( Message ) + Send > ,
86
86
config : FlycheckConfig ,
87
87
workspace_root : AbsPathBuf ,
88
+ project_file : AbsPathBuf ,
88
89
) -> FlycheckHandle {
89
- let actor = FlycheckActor :: new ( id, sender, config, workspace_root) ;
90
+ let actor = FlycheckActor :: new ( id, sender, config, workspace_root, project_file ) ;
90
91
let ( sender, receiver) = unbounded :: < Restart > ( ) ;
91
92
let thread = jod_thread:: Builder :: new ( )
92
93
. name ( "Flycheck" . to_owned ( ) )
@@ -96,8 +97,8 @@ impl FlycheckHandle {
96
97
}
97
98
98
99
/// Schedule a re-start of the cargo check worker.
99
- pub fn restart ( & self ) {
100
- self . sender . send ( Restart :: Yes ) . unwrap ( ) ;
100
+ pub fn restart ( & self , saved_file : Option < AbsPathBuf > ) {
101
+ self . sender . send ( Restart :: Yes { saved_file } ) . unwrap ( ) ;
101
102
}
102
103
103
104
/// Stop this cargo check worker.
@@ -148,7 +149,7 @@ pub enum Progress {
148
149
}
149
150
150
151
enum Restart {
151
- Yes ,
152
+ Yes { saved_file : Option < AbsPathBuf > } ,
152
153
No ,
153
154
}
154
155
@@ -161,12 +162,14 @@ struct FlycheckActor {
161
162
/// Either the workspace root of the workspace we are flychecking,
162
163
/// or the project root of the project.
163
164
root : AbsPathBuf ,
165
+ /// The Cargo.toml or rust-project.json file of the project.
166
+ project_file : AbsPathBuf ,
164
167
/// CargoHandle exists to wrap around the communication needed to be able to
165
168
/// run `cargo check` without blocking. Currently the Rust standard library
166
169
/// doesn't provide a way to read sub-process output without blocking, so we
167
170
/// have to wrap sub-processes output handling in a thread and pass messages
168
171
/// back over a channel.
169
- cargo_handle : Option < CargoHandle > ,
172
+ cargo_handle : Option < ( CargoHandle , String ) > ,
170
173
}
171
174
172
175
enum Event {
@@ -180,17 +183,18 @@ impl FlycheckActor {
180
183
sender : Box < dyn Fn ( Message ) + Send > ,
181
184
config : FlycheckConfig ,
182
185
workspace_root : AbsPathBuf ,
186
+ project_file : AbsPathBuf ,
183
187
) -> FlycheckActor {
184
188
tracing:: info!( %id, ?workspace_root, "Spawning flycheck" ) ;
185
- FlycheckActor { id, sender, config, root : workspace_root, cargo_handle : None }
189
+ FlycheckActor { id, sender, config, root : workspace_root, project_file , cargo_handle : None }
186
190
}
187
191
188
192
fn report_progress ( & self , progress : Progress ) {
189
193
self . send ( Message :: Progress { id : self . id , progress } ) ;
190
194
}
191
195
192
196
fn next_event ( & self , inbox : & Receiver < Restart > ) -> Option < Event > {
193
- let check_chan = self . cargo_handle . as_ref ( ) . map ( |cargo| & cargo. receiver ) ;
197
+ let check_chan = self . cargo_handle . as_ref ( ) . map ( |( cargo, _ ) | & cargo. receiver ) ;
194
198
if let Ok ( msg) = inbox. try_recv ( ) {
195
199
// give restarts a preference so check outputs don't block a restart or stop
196
200
return Some ( Event :: Restart ( msg) ) ;
@@ -204,10 +208,8 @@ impl FlycheckActor {
204
208
fn run ( mut self , inbox : Receiver < Restart > ) {
205
209
' event: while let Some ( event) = self . next_event ( & inbox) {
206
210
match event {
207
- Event :: Restart ( Restart :: No ) => {
208
- self . cancel_check_process ( ) ;
209
- }
210
- Event :: Restart ( Restart :: Yes ) => {
211
+ Event :: Restart ( Restart :: No ) => self . cancel_check_process ( ) ,
212
+ Event :: Restart ( Restart :: Yes { saved_file } ) => {
211
213
// Cancel the previously spawned process
212
214
self . cancel_check_process ( ) ;
213
215
while let Ok ( restart) = inbox. recv_timeout ( Duration :: from_millis ( 50 ) ) {
@@ -217,22 +219,18 @@ impl FlycheckActor {
217
219
}
218
220
}
219
221
220
- let command = self . check_command ( ) ;
221
- tracing:: debug!( ?command, "will restart flycheck" ) ;
222
+ let command = self . check_command ( saved_file) ;
223
+ let command_string = format ! ( "{:?}" , command) ;
224
+ tracing:: debug!( ?command, "restarting flycheck" ) ;
222
225
match CargoHandle :: spawn ( command) {
223
226
Ok ( cargo_handle) => {
224
- tracing:: debug!(
225
- command = ?self . check_command( ) ,
226
- "did restart flycheck"
227
- ) ;
228
- self . cargo_handle = Some ( cargo_handle) ;
227
+ self . cargo_handle = Some ( ( cargo_handle, command_string) ) ;
229
228
self . report_progress ( Progress :: DidStart ) ;
230
229
}
231
230
Err ( error) => {
232
231
self . report_progress ( Progress :: DidFailToRestart ( format ! (
233
232
"Failed to run the following command: {:?} error={}" ,
234
- self . check_command( ) ,
235
- error
233
+ command_string, error
236
234
) ) ) ;
237
235
}
238
236
}
@@ -241,12 +239,12 @@ impl FlycheckActor {
241
239
tracing:: debug!( flycheck_id = self . id, "flycheck finished" ) ;
242
240
243
241
// Watcher finished
244
- let cargo_handle = self . cargo_handle . take ( ) . unwrap ( ) ;
242
+ let ( cargo_handle, cmd_string ) = self . cargo_handle . take ( ) . unwrap ( ) ;
245
243
let res = cargo_handle. join ( ) ;
246
244
if res. is_err ( ) {
247
245
tracing:: error!(
248
- "Flycheck failed to run the following command: {:?}" ,
249
- self . check_command ( )
246
+ command = cmd_string ,
247
+ "Flycheck failed to run the following command"
250
248
) ;
251
249
}
252
250
self . report_progress ( Progress :: DidFinish ( res) ) ;
@@ -271,18 +269,17 @@ impl FlycheckActor {
271
269
}
272
270
273
271
fn cancel_check_process ( & mut self ) {
274
- if let Some ( cargo_handle) = self . cargo_handle . take ( ) {
275
- tracing:: debug!(
276
- command = ?self . check_command( ) ,
277
- "did cancel flycheck"
278
- ) ;
272
+ if let Some ( ( cargo_handle, cmd_string) ) = self . cargo_handle . take ( ) {
273
+ tracing:: debug!( command = cmd_string, "did cancel flycheck" ) ;
279
274
cargo_handle. cancel ( ) ;
280
275
self . report_progress ( Progress :: DidCancel ) ;
281
276
}
282
277
}
283
278
284
- fn check_command ( & self ) -> Command {
285
- let ( mut cmd, args) = match & self . config {
279
+ fn check_command ( & self , _saved_file : Option < AbsPathBuf > ) -> Command {
280
+ // FIXME: Figure out the story for exposing the saved file to the custom flycheck command
281
+ // as it can be absent
282
+ match & self . config {
286
283
FlycheckConfig :: CargoCommand {
287
284
command,
288
285
target_triple,
@@ -297,7 +294,7 @@ impl FlycheckActor {
297
294
cmd. arg ( command) ;
298
295
cmd. current_dir ( & self . root ) ;
299
296
cmd. args ( & [ "--workspace" , "--message-format=json" , "--manifest-path" ] )
300
- . arg ( self . root . join ( "Cargo.toml" ) . as_os_str ( ) ) ;
297
+ . arg ( self . project_file . as_os_str ( ) ) ;
301
298
302
299
if let Some ( target) = target_triple {
303
300
cmd. args ( & [ "--target" , target. as_str ( ) ] ) ;
@@ -317,7 +314,8 @@ impl FlycheckActor {
317
314
}
318
315
}
319
316
cmd. envs ( extra_env) ;
320
- ( cmd, extra_args)
317
+ cmd. args ( extra_args) ;
318
+ cmd
321
319
}
322
320
FlycheckConfig :: CustomCommand {
323
321
command,
@@ -328,30 +326,24 @@ impl FlycheckActor {
328
326
} => {
329
327
let mut cmd = Command :: new ( command) ;
330
328
cmd. envs ( extra_env) ;
329
+ args. iter ( ) . for_each ( |arg| {
330
+ match invocation_strategy {
331
+ InvocationStrategy :: Once => cmd. arg ( arg) ,
332
+ InvocationStrategy :: PerWorkspace => cmd. arg ( arg. replace (
333
+ "$manifest_path" ,
334
+ & self . project_file . as_os_str ( ) . to_string_lossy ( ) ,
335
+ ) ) ,
336
+ } ;
337
+ } ) ;
331
338
332
339
match invocation_location {
333
- InvocationLocation :: Workspace => {
334
- match invocation_strategy {
335
- InvocationStrategy :: Once => {
336
- cmd. current_dir ( & self . root ) ;
337
- }
338
- InvocationStrategy :: PerWorkspace => {
339
- // FIXME: cmd.current_dir(&affected_workspace);
340
- cmd. current_dir ( & self . root ) ;
341
- }
342
- }
343
- }
344
- InvocationLocation :: Root ( root) => {
345
- cmd. current_dir ( root) ;
346
- }
347
- }
340
+ InvocationLocation :: Workspace => cmd. current_dir ( & self . root ) ,
341
+ InvocationLocation :: Root ( root) => cmd. current_dir ( root) ,
342
+ } ;
348
343
349
- ( cmd, args )
344
+ cmd
350
345
}
351
- } ;
352
-
353
- cmd. args ( args) ;
354
- cmd
346
+ }
355
347
}
356
348
357
349
fn send ( & self , check_task : Message ) {
0 commit comments