66
77use std:: {
88 fmt, io,
9- path:: Path ,
109 process:: { ChildStderr , ChildStdout , Command , Stdio } ,
1110 time:: Duration ,
1211} ;
@@ -25,7 +24,6 @@ pub use cargo_metadata::diagnostic::{
2524#[ derive( Copy , Clone , Debug , Default , PartialEq , Eq ) ]
2625pub enum InvocationStrategy {
2726 OnceInRoot ,
28- PerWorkspaceWithManifestPath ,
2927 #[ default]
3028 PerWorkspace ,
3129}
@@ -153,7 +151,9 @@ struct FlycheckActor {
153151 id : usize ,
154152 sender : Box < dyn Fn ( Message ) + Send > ,
155153 config : FlycheckConfig ,
156- workspace_root : AbsPathBuf ,
154+ /// Either the workspace root of the workspace we are flychecking,
155+ /// or the project root of the project.
156+ root : AbsPathBuf ,
157157 /// CargoHandle exists to wrap around the communication needed to be able to
158158 /// run `cargo check` without blocking. Currently the Rust standard library
159159 /// doesn't provide a way to read sub-process output without blocking, so we
@@ -175,7 +175,7 @@ impl FlycheckActor {
175175 workspace_root : AbsPathBuf ,
176176 ) -> FlycheckActor {
177177 tracing:: info!( %id, ?workspace_root, "Spawning flycheck" ) ;
178- FlycheckActor { id, sender, config, workspace_root, cargo_handle : None }
178+ FlycheckActor { id, sender, config, root : workspace_root, cargo_handle : None }
179179 }
180180
181181 fn report_progress ( & self , progress : Progress ) {
@@ -210,20 +210,7 @@ impl FlycheckActor {
210210 }
211211 }
212212
213- let mut command = self . check_command ( ) ;
214- let invocation_strategy = self . invocation_strategy ( ) ;
215- match invocation_strategy {
216- InvocationStrategy :: OnceInRoot => ( ) ,
217- InvocationStrategy :: PerWorkspaceWithManifestPath => {
218- command. arg ( "--manifest-path" ) ;
219- command. arg ( <_ as AsRef < Path > >:: as_ref (
220- & self . workspace_root . join ( "Cargo.toml" ) ,
221- ) ) ;
222- }
223- InvocationStrategy :: PerWorkspace => {
224- command. current_dir ( & self . workspace_root ) ;
225- }
226- }
213+ let command = self . check_command ( ) ;
227214 tracing:: debug!( ?command, "will restart flycheck" ) ;
228215 match CargoHandle :: spawn ( command) {
229216 Ok ( cargo_handle) => {
@@ -265,7 +252,7 @@ impl FlycheckActor {
265252 CargoMessage :: Diagnostic ( msg) => {
266253 self . send ( Message :: AddDiagnostic {
267254 id : self . id ,
268- workspace_root : self . workspace_root . clone ( ) ,
255+ workspace_root : self . root . clone ( ) ,
269256 diagnostic : msg,
270257 } ) ;
271258 }
@@ -287,15 +274,8 @@ impl FlycheckActor {
287274 }
288275 }
289276
290- fn invocation_strategy ( & self ) -> InvocationStrategy {
291- match self . config {
292- FlycheckConfig :: CargoCommand { invocation_strategy, .. }
293- | FlycheckConfig :: CustomCommand { invocation_strategy, .. } => invocation_strategy,
294- }
295- }
296-
297277 fn check_command ( & self ) -> Command {
298- let mut cmd = match & self . config {
278+ let ( mut cmd, args , invocation_strategy ) = match & self . config {
299279 FlycheckConfig :: CargoCommand {
300280 command,
301281 target_triple,
@@ -305,13 +285,11 @@ impl FlycheckActor {
305285 extra_args,
306286 features,
307287 extra_env,
308- invocation_strategy : _ ,
288+ invocation_strategy,
309289 } => {
310290 let mut cmd = Command :: new ( toolchain:: cargo ( ) ) ;
311291 cmd. arg ( command) ;
312- cmd. current_dir ( & self . workspace_root ) ;
313- cmd. args ( & [ "--workspace" , "--message-format=json" , "--manifest-path" ] )
314- . arg ( self . workspace_root . join ( "Cargo.toml" ) . as_os_str ( ) ) ;
292+ cmd. args ( & [ "--workspace" , "--message-format=json" ] ) ;
315293
316294 if let Some ( target) = target_triple {
317295 cmd. args ( & [ "--target" , target. as_str ( ) ] ) ;
@@ -330,18 +308,35 @@ impl FlycheckActor {
330308 cmd. arg ( features. join ( " " ) ) ;
331309 }
332310 }
333- cmd. args ( extra_args) ;
334311 cmd. envs ( extra_env) ;
335- cmd
312+ ( cmd, extra_args , invocation_strategy )
336313 }
337- FlycheckConfig :: CustomCommand { command, args, extra_env, invocation_strategy : _ } => {
314+ FlycheckConfig :: CustomCommand { command, args, extra_env, invocation_strategy } => {
338315 let mut cmd = Command :: new ( command) ;
339- cmd. args ( args) ;
340316 cmd. envs ( extra_env) ;
341- cmd
317+ ( cmd, args , invocation_strategy )
342318 }
343319 } ;
344- cmd. current_dir ( & self . workspace_root ) ;
320+ if let InvocationStrategy :: PerWorkspace = invocation_strategy {
321+ let mut with_manifest_path = false ;
322+ for arg in args {
323+ if let Some ( _) = arg. find ( "$manifest_path" ) {
324+ with_manifest_path = true ;
325+ cmd. arg ( arg. replace (
326+ "$manifest_path" ,
327+ & self . root . join ( "Cargo.toml" ) . display ( ) . to_string ( ) ,
328+ ) ) ;
329+ } else {
330+ cmd. arg ( arg) ;
331+ }
332+ }
333+
334+ if !with_manifest_path {
335+ cmd. current_dir ( & self . root ) ;
336+ }
337+ } else {
338+ cmd. args ( args) ;
339+ }
345340 cmd
346341 }
347342
0 commit comments