@@ -21,6 +21,13 @@ pub use cargo_metadata::diagnostic::{
2121 DiagnosticSpanMacroExpansion ,
2222} ;
2323
24+ #[ derive( Copy , Clone , Debug , Default , PartialEq , Eq ) ]
25+ pub enum InvocationStrategy {
26+ Once ,
27+ #[ default]
28+ PerWorkspace ,
29+ }
30+
2431#[ derive( Clone , Debug , PartialEq , Eq ) ]
2532pub enum FlycheckConfig {
2633 CargoCommand {
@@ -32,11 +39,13 @@ pub enum FlycheckConfig {
3239 features : Vec < String > ,
3340 extra_args : Vec < String > ,
3441 extra_env : FxHashMap < String , String > ,
42+ invocation_strategy : InvocationStrategy ,
3543 } ,
3644 CustomCommand {
3745 command : String ,
3846 args : Vec < String > ,
3947 extra_env : FxHashMap < String , String > ,
48+ invocation_strategy : InvocationStrategy ,
4049 } ,
4150}
4251
@@ -136,11 +145,15 @@ enum Restart {
136145 No ,
137146}
138147
148+ /// A [`FlycheckActor`] is a single check instance of a workspace.
139149struct FlycheckActor {
150+ /// The workspace id of this flycheck instance.
140151 id : usize ,
141152 sender : Box < dyn Fn ( Message ) + Send > ,
142153 config : FlycheckConfig ,
143- 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 ,
144157 /// CargoHandle exists to wrap around the communication needed to be able to
145158 /// run `cargo check` without blocking. Currently the Rust standard library
146159 /// doesn't provide a way to read sub-process output without blocking, so we
@@ -162,11 +175,13 @@ impl FlycheckActor {
162175 workspace_root : AbsPathBuf ,
163176 ) -> FlycheckActor {
164177 tracing:: info!( %id, ?workspace_root, "Spawning flycheck" ) ;
165- FlycheckActor { id, sender, config, workspace_root, cargo_handle : None }
178+ FlycheckActor { id, sender, config, root : workspace_root, cargo_handle : None }
166179 }
167- fn progress ( & self , progress : Progress ) {
180+
181+ fn report_progress ( & self , progress : Progress ) {
168182 self . send ( Message :: Progress { id : self . id , progress } ) ;
169183 }
184+
170185 fn next_event ( & self , inbox : & Receiver < Restart > ) -> Option < Event > {
171186 let check_chan = self . cargo_handle . as_ref ( ) . map ( |cargo| & cargo. receiver ) ;
172187 if let Ok ( msg) = inbox. try_recv ( ) {
@@ -178,6 +193,7 @@ impl FlycheckActor {
178193 recv( check_chan. unwrap_or( & never( ) ) ) -> msg => Some ( Event :: CheckEvent ( msg. ok( ) ) ) ,
179194 }
180195 }
196+
181197 fn run ( mut self , inbox : Receiver < Restart > ) {
182198 ' event: while let Some ( event) = self . next_event ( & inbox) {
183199 match event {
@@ -203,10 +219,10 @@ impl FlycheckActor {
203219 "did restart flycheck"
204220 ) ;
205221 self . cargo_handle = Some ( cargo_handle) ;
206- self . progress ( Progress :: DidStart ) ;
222+ self . report_progress ( Progress :: DidStart ) ;
207223 }
208224 Err ( error) => {
209- self . progress ( Progress :: DidFailToRestart ( format ! (
225+ self . report_progress ( Progress :: DidFailToRestart ( format ! (
210226 "Failed to run the following command: {:?} error={}" ,
211227 self . check_command( ) ,
212228 error
@@ -226,17 +242,17 @@ impl FlycheckActor {
226242 self . check_command( )
227243 ) ;
228244 }
229- self . progress ( Progress :: DidFinish ( res) ) ;
245+ self . report_progress ( Progress :: DidFinish ( res) ) ;
230246 }
231247 Event :: CheckEvent ( Some ( message) ) => match message {
232248 CargoMessage :: CompilerArtifact ( msg) => {
233- self . progress ( Progress :: DidCheckCrate ( msg. target . name ) ) ;
249+ self . report_progress ( Progress :: DidCheckCrate ( msg. target . name ) ) ;
234250 }
235251
236252 CargoMessage :: Diagnostic ( msg) => {
237253 self . send ( Message :: AddDiagnostic {
238254 id : self . id ,
239- workspace_root : self . workspace_root . clone ( ) ,
255+ workspace_root : self . root . clone ( ) ,
240256 diagnostic : msg,
241257 } ) ;
242258 }
@@ -254,12 +270,12 @@ impl FlycheckActor {
254270 "did cancel flycheck"
255271 ) ;
256272 cargo_handle. cancel ( ) ;
257- self . progress ( Progress :: DidCancel ) ;
273+ self . report_progress ( Progress :: DidCancel ) ;
258274 }
259275 }
260276
261277 fn check_command ( & self ) -> Command {
262- let mut cmd = match & self . config {
278+ let ( mut cmd, args , invocation_strategy ) = match & self . config {
263279 FlycheckConfig :: CargoCommand {
264280 command,
265281 target_triple,
@@ -269,12 +285,11 @@ impl FlycheckActor {
269285 extra_args,
270286 features,
271287 extra_env,
288+ invocation_strategy,
272289 } => {
273290 let mut cmd = Command :: new ( toolchain:: cargo ( ) ) ;
274291 cmd. arg ( command) ;
275- cmd. current_dir ( & self . workspace_root ) ;
276- cmd. args ( & [ "--workspace" , "--message-format=json" , "--manifest-path" ] )
277- . arg ( self . workspace_root . join ( "Cargo.toml" ) . as_os_str ( ) ) ;
292+ cmd. args ( & [ "--workspace" , "--message-format=json" ] ) ;
278293
279294 if let Some ( target) = target_triple {
280295 cmd. args ( & [ "--target" , target. as_str ( ) ] ) ;
@@ -293,18 +308,19 @@ impl FlycheckActor {
293308 cmd. arg ( features. join ( " " ) ) ;
294309 }
295310 }
296- cmd. args ( extra_args) ;
297311 cmd. envs ( extra_env) ;
298- cmd
312+ ( cmd, extra_args , invocation_strategy )
299313 }
300- FlycheckConfig :: CustomCommand { command, args, extra_env } => {
314+ FlycheckConfig :: CustomCommand { command, args, extra_env, invocation_strategy } => {
301315 let mut cmd = Command :: new ( command) ;
302- cmd. args ( args) ;
303316 cmd. envs ( extra_env) ;
304- cmd
317+ ( cmd, args , invocation_strategy )
305318 }
306319 } ;
307- cmd. current_dir ( & self . workspace_root ) ;
320+ match invocation_strategy {
321+ InvocationStrategy :: PerWorkspace => cmd. current_dir ( & self . root ) ,
322+ InvocationStrategy :: Once => cmd. args ( args) ,
323+ } ;
308324 cmd
309325 }
310326
0 commit comments