@@ -85,8 +85,9 @@ impl FlycheckHandle {
8585 sender : Box < dyn Fn ( Message ) + Send > ,
8686 config : FlycheckConfig ,
8787 workspace_root : AbsPathBuf ,
88+ project_file : AbsPathBuf ,
8889 ) -> FlycheckHandle {
89- let actor = FlycheckActor :: new ( id, sender, config, workspace_root) ;
90+ let actor = FlycheckActor :: new ( id, sender, config, workspace_root, project_file ) ;
9091 let ( sender, receiver) = unbounded :: < Restart > ( ) ;
9192 let thread = jod_thread:: Builder :: new ( )
9293 . name ( "Flycheck" . to_owned ( ) )
@@ -96,8 +97,8 @@ impl FlycheckHandle {
9697 }
9798
9899 /// 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 ( ) ;
101102 }
102103
103104 /// Stop this cargo check worker.
@@ -148,7 +149,7 @@ pub enum Progress {
148149}
149150
150151enum Restart {
151- Yes ,
152+ Yes { saved_file : Option < AbsPathBuf > } ,
152153 No ,
153154}
154155
@@ -161,12 +162,14 @@ struct FlycheckActor {
161162 /// Either the workspace root of the workspace we are flychecking,
162163 /// or the project root of the project.
163164 root : AbsPathBuf ,
165+ /// The Cargo.toml or rust-project.json file of the project.
166+ project_file : AbsPathBuf ,
164167 /// CargoHandle exists to wrap around the communication needed to be able to
165168 /// run `cargo check` without blocking. Currently the Rust standard library
166169 /// doesn't provide a way to read sub-process output without blocking, so we
167170 /// have to wrap sub-processes output handling in a thread and pass messages
168171 /// back over a channel.
169- cargo_handle : Option < CargoHandle > ,
172+ cargo_handle : Option < ( CargoHandle , String ) > ,
170173}
171174
172175enum Event {
@@ -180,17 +183,18 @@ impl FlycheckActor {
180183 sender : Box < dyn Fn ( Message ) + Send > ,
181184 config : FlycheckConfig ,
182185 workspace_root : AbsPathBuf ,
186+ project_file : AbsPathBuf ,
183187 ) -> FlycheckActor {
184188 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 }
186190 }
187191
188192 fn report_progress ( & self , progress : Progress ) {
189193 self . send ( Message :: Progress { id : self . id , progress } ) ;
190194 }
191195
192196 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 ) ;
194198 if let Ok ( msg) = inbox. try_recv ( ) {
195199 // give restarts a preference so check outputs don't block a restart or stop
196200 return Some ( Event :: Restart ( msg) ) ;
@@ -204,10 +208,8 @@ impl FlycheckActor {
204208 fn run ( mut self , inbox : Receiver < Restart > ) {
205209 ' event: while let Some ( event) = self . next_event ( & inbox) {
206210 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 } ) => {
211213 // Cancel the previously spawned process
212214 self . cancel_check_process ( ) ;
213215 while let Ok ( restart) = inbox. recv_timeout ( Duration :: from_millis ( 50 ) ) {
@@ -217,22 +219,18 @@ impl FlycheckActor {
217219 }
218220 }
219221
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" ) ;
222225 match CargoHandle :: spawn ( command) {
223226 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) ) ;
229228 self . report_progress ( Progress :: DidStart ) ;
230229 }
231230 Err ( error) => {
232231 self . report_progress ( Progress :: DidFailToRestart ( format ! (
233232 "Failed to run the following command: {:?} error={}" ,
234- self . check_command( ) ,
235- error
233+ command_string, error
236234 ) ) ) ;
237235 }
238236 }
@@ -241,12 +239,12 @@ impl FlycheckActor {
241239 tracing:: debug!( flycheck_id = self . id, "flycheck finished" ) ;
242240
243241 // Watcher finished
244- let cargo_handle = self . cargo_handle . take ( ) . unwrap ( ) ;
242+ let ( cargo_handle, cmd_string ) = self . cargo_handle . take ( ) . unwrap ( ) ;
245243 let res = cargo_handle. join ( ) ;
246244 if res. is_err ( ) {
247245 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"
250248 ) ;
251249 }
252250 self . report_progress ( Progress :: DidFinish ( res) ) ;
@@ -271,18 +269,17 @@ impl FlycheckActor {
271269 }
272270
273271 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" ) ;
279274 cargo_handle. cancel ( ) ;
280275 self . report_progress ( Progress :: DidCancel ) ;
281276 }
282277 }
283278
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 {
286283 FlycheckConfig :: CargoCommand {
287284 command,
288285 target_triple,
@@ -297,7 +294,7 @@ impl FlycheckActor {
297294 cmd. arg ( command) ;
298295 cmd. current_dir ( & self . root ) ;
299296 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 ( ) ) ;
301298
302299 if let Some ( target) = target_triple {
303300 cmd. args ( & [ "--target" , target. as_str ( ) ] ) ;
@@ -317,7 +314,8 @@ impl FlycheckActor {
317314 }
318315 }
319316 cmd. envs ( extra_env) ;
320- ( cmd, extra_args)
317+ cmd. args ( extra_args) ;
318+ cmd
321319 }
322320 FlycheckConfig :: CustomCommand {
323321 command,
@@ -328,30 +326,24 @@ impl FlycheckActor {
328326 } => {
329327 let mut cmd = Command :: new ( command) ;
330328 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+ } ) ;
331338
332339 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+ } ;
348343
349- ( cmd, args )
344+ cmd
350345 }
351- } ;
352-
353- cmd. args ( args) ;
354- cmd
346+ }
355347 }
356348
357349 fn send ( & self , check_task : Message ) {
0 commit comments