@@ -21,6 +21,20 @@ 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+
31+ #[ derive( Clone , Debug , Default , PartialEq , Eq ) ]
32+ pub enum InvocationLocation {
33+ Root ( AbsPathBuf ) ,
34+ #[ default]
35+ Workspace ,
36+ }
37+
2438#[ derive( Clone , Debug , PartialEq , Eq ) ]
2539pub enum FlycheckConfig {
2640 CargoCommand {
@@ -37,6 +51,8 @@ pub enum FlycheckConfig {
3751 command : String ,
3852 args : Vec < String > ,
3953 extra_env : FxHashMap < String , String > ,
54+ invocation_strategy : InvocationStrategy ,
55+ invocation_location : InvocationLocation ,
4056 } ,
4157}
4258
@@ -136,11 +152,15 @@ enum Restart {
136152 No ,
137153}
138154
155+ /// A [`FlycheckActor`] is a single check instance of a workspace.
139156struct FlycheckActor {
157+ /// The workspace id of this flycheck instance.
140158 id : usize ,
141159 sender : Box < dyn Fn ( Message ) + Send > ,
142160 config : FlycheckConfig ,
143- workspace_root : AbsPathBuf ,
161+ /// Either the workspace root of the workspace we are flychecking,
162+ /// or the project root of the project.
163+ root : AbsPathBuf ,
144164 /// CargoHandle exists to wrap around the communication needed to be able to
145165 /// run `cargo check` without blocking. Currently the Rust standard library
146166 /// doesn't provide a way to read sub-process output without blocking, so we
@@ -162,11 +182,13 @@ impl FlycheckActor {
162182 workspace_root : AbsPathBuf ,
163183 ) -> FlycheckActor {
164184 tracing:: info!( %id, ?workspace_root, "Spawning flycheck" ) ;
165- FlycheckActor { id, sender, config, workspace_root, cargo_handle : None }
185+ FlycheckActor { id, sender, config, root : workspace_root, cargo_handle : None }
166186 }
167- fn progress ( & self , progress : Progress ) {
187+
188+ fn report_progress ( & self , progress : Progress ) {
168189 self . send ( Message :: Progress { id : self . id , progress } ) ;
169190 }
191+
170192 fn next_event ( & self , inbox : & Receiver < Restart > ) -> Option < Event > {
171193 let check_chan = self . cargo_handle . as_ref ( ) . map ( |cargo| & cargo. receiver ) ;
172194 if let Ok ( msg) = inbox. try_recv ( ) {
@@ -178,6 +200,7 @@ impl FlycheckActor {
178200 recv( check_chan. unwrap_or( & never( ) ) ) -> msg => Some ( Event :: CheckEvent ( msg. ok( ) ) ) ,
179201 }
180202 }
203+
181204 fn run ( mut self , inbox : Receiver < Restart > ) {
182205 ' event: while let Some ( event) = self . next_event ( & inbox) {
183206 match event {
@@ -203,10 +226,10 @@ impl FlycheckActor {
203226 "did restart flycheck"
204227 ) ;
205228 self . cargo_handle = Some ( cargo_handle) ;
206- self . progress ( Progress :: DidStart ) ;
229+ self . report_progress ( Progress :: DidStart ) ;
207230 }
208231 Err ( error) => {
209- self . progress ( Progress :: DidFailToRestart ( format ! (
232+ self . report_progress ( Progress :: DidFailToRestart ( format ! (
210233 "Failed to run the following command: {:?} error={}" ,
211234 self . check_command( ) ,
212235 error
@@ -226,17 +249,17 @@ impl FlycheckActor {
226249 self . check_command( )
227250 ) ;
228251 }
229- self . progress ( Progress :: DidFinish ( res) ) ;
252+ self . report_progress ( Progress :: DidFinish ( res) ) ;
230253 }
231254 Event :: CheckEvent ( Some ( message) ) => match message {
232255 CargoMessage :: CompilerArtifact ( msg) => {
233- self . progress ( Progress :: DidCheckCrate ( msg. target . name ) ) ;
256+ self . report_progress ( Progress :: DidCheckCrate ( msg. target . name ) ) ;
234257 }
235258
236259 CargoMessage :: Diagnostic ( msg) => {
237260 self . send ( Message :: AddDiagnostic {
238261 id : self . id ,
239- workspace_root : self . workspace_root . clone ( ) ,
262+ workspace_root : self . root . clone ( ) ,
240263 diagnostic : msg,
241264 } ) ;
242265 }
@@ -254,12 +277,12 @@ impl FlycheckActor {
254277 "did cancel flycheck"
255278 ) ;
256279 cargo_handle. cancel ( ) ;
257- self . progress ( Progress :: DidCancel ) ;
280+ self . report_progress ( Progress :: DidCancel ) ;
258281 }
259282 }
260283
261284 fn check_command ( & self ) -> Command {
262- let mut cmd = match & self . config {
285+ let ( mut cmd, args ) = match & self . config {
263286 FlycheckConfig :: CargoCommand {
264287 command,
265288 target_triple,
@@ -272,9 +295,7 @@ impl FlycheckActor {
272295 } => {
273296 let mut cmd = Command :: new ( toolchain:: cargo ( ) ) ;
274297 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 ( ) ) ;
298+ cmd. args ( & [ "--workspace" , "--message-format=json" ] ) ;
278299
279300 if let Some ( target) = target_triple {
280301 cmd. args ( & [ "--target" , target. as_str ( ) ] ) ;
@@ -293,18 +314,41 @@ impl FlycheckActor {
293314 cmd. arg ( features. join ( " " ) ) ;
294315 }
295316 }
296- cmd. args ( extra_args) ;
297317 cmd. envs ( extra_env) ;
298- cmd
318+ ( cmd, extra_args )
299319 }
300- FlycheckConfig :: CustomCommand { command, args, extra_env } => {
320+ FlycheckConfig :: CustomCommand {
321+ command,
322+ args,
323+ extra_env,
324+ invocation_strategy,
325+ invocation_location,
326+ } => {
301327 let mut cmd = Command :: new ( command) ;
302- cmd. args ( args) ;
303328 cmd. envs ( extra_env) ;
304- cmd
329+
330+ match invocation_location {
331+ InvocationLocation :: Workspace => {
332+ match invocation_strategy {
333+ InvocationStrategy :: Once => {
334+ cmd. current_dir ( & self . root ) ;
335+ }
336+ InvocationStrategy :: PerWorkspace => {
337+ // FIXME: cmd.current_dir(&affected_workspace);
338+ cmd. current_dir ( & self . root ) ;
339+ }
340+ }
341+ }
342+ InvocationLocation :: Root ( root) => {
343+ cmd. current_dir ( root) ;
344+ }
345+ }
346+
347+ ( cmd, args)
305348 }
306349 } ;
307- cmd. current_dir ( & self . workspace_root ) ;
350+
351+ cmd. args ( args) ;
308352 cmd
309353 }
310354
0 commit comments