@@ -21,6 +21,13 @@ pub use cargo_metadata::diagnostic::{
21
21
DiagnosticSpanMacroExpansion ,
22
22
} ;
23
23
24
+ #[ derive( Copy , Clone , Debug , Default , PartialEq , Eq ) ]
25
+ pub enum InvocationStrategy {
26
+ Once ,
27
+ #[ default]
28
+ PerWorkspace ,
29
+ }
30
+
24
31
#[ derive( Clone , Debug , PartialEq , Eq ) ]
25
32
pub enum FlycheckConfig {
26
33
CargoCommand {
@@ -32,11 +39,13 @@ pub enum FlycheckConfig {
32
39
features : Vec < String > ,
33
40
extra_args : Vec < String > ,
34
41
extra_env : FxHashMap < String , String > ,
42
+ invocation_strategy : InvocationStrategy ,
35
43
} ,
36
44
CustomCommand {
37
45
command : String ,
38
46
args : Vec < String > ,
39
47
extra_env : FxHashMap < String , String > ,
48
+ invocation_strategy : InvocationStrategy ,
40
49
} ,
41
50
}
42
51
@@ -136,11 +145,15 @@ enum Restart {
136
145
No ,
137
146
}
138
147
148
+ /// A [`FlycheckActor`] is a single check instance of a workspace.
139
149
struct FlycheckActor {
150
+ /// The workspace id of this flycheck instance.
140
151
id : usize ,
141
152
sender : Box < dyn Fn ( Message ) + Send > ,
142
153
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 ,
144
157
/// CargoHandle exists to wrap around the communication needed to be able to
145
158
/// run `cargo check` without blocking. Currently the Rust standard library
146
159
/// doesn't provide a way to read sub-process output without blocking, so we
@@ -162,11 +175,13 @@ impl FlycheckActor {
162
175
workspace_root : AbsPathBuf ,
163
176
) -> FlycheckActor {
164
177
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 }
166
179
}
167
- fn progress ( & self , progress : Progress ) {
180
+
181
+ fn report_progress ( & self , progress : Progress ) {
168
182
self . send ( Message :: Progress { id : self . id , progress } ) ;
169
183
}
184
+
170
185
fn next_event ( & self , inbox : & Receiver < Restart > ) -> Option < Event > {
171
186
let check_chan = self . cargo_handle . as_ref ( ) . map ( |cargo| & cargo. receiver ) ;
172
187
if let Ok ( msg) = inbox. try_recv ( ) {
@@ -178,6 +193,7 @@ impl FlycheckActor {
178
193
recv( check_chan. unwrap_or( & never( ) ) ) -> msg => Some ( Event :: CheckEvent ( msg. ok( ) ) ) ,
179
194
}
180
195
}
196
+
181
197
fn run ( mut self , inbox : Receiver < Restart > ) {
182
198
' event: while let Some ( event) = self . next_event ( & inbox) {
183
199
match event {
@@ -203,10 +219,10 @@ impl FlycheckActor {
203
219
"did restart flycheck"
204
220
) ;
205
221
self . cargo_handle = Some ( cargo_handle) ;
206
- self . progress ( Progress :: DidStart ) ;
222
+ self . report_progress ( Progress :: DidStart ) ;
207
223
}
208
224
Err ( error) => {
209
- self . progress ( Progress :: DidFailToRestart ( format ! (
225
+ self . report_progress ( Progress :: DidFailToRestart ( format ! (
210
226
"Failed to run the following command: {:?} error={}" ,
211
227
self . check_command( ) ,
212
228
error
@@ -226,17 +242,17 @@ impl FlycheckActor {
226
242
self . check_command( )
227
243
) ;
228
244
}
229
- self . progress ( Progress :: DidFinish ( res) ) ;
245
+ self . report_progress ( Progress :: DidFinish ( res) ) ;
230
246
}
231
247
Event :: CheckEvent ( Some ( message) ) => match message {
232
248
CargoMessage :: CompilerArtifact ( msg) => {
233
- self . progress ( Progress :: DidCheckCrate ( msg. target . name ) ) ;
249
+ self . report_progress ( Progress :: DidCheckCrate ( msg. target . name ) ) ;
234
250
}
235
251
236
252
CargoMessage :: Diagnostic ( msg) => {
237
253
self . send ( Message :: AddDiagnostic {
238
254
id : self . id ,
239
- workspace_root : self . workspace_root . clone ( ) ,
255
+ workspace_root : self . root . clone ( ) ,
240
256
diagnostic : msg,
241
257
} ) ;
242
258
}
@@ -254,12 +270,12 @@ impl FlycheckActor {
254
270
"did cancel flycheck"
255
271
) ;
256
272
cargo_handle. cancel ( ) ;
257
- self . progress ( Progress :: DidCancel ) ;
273
+ self . report_progress ( Progress :: DidCancel ) ;
258
274
}
259
275
}
260
276
261
277
fn check_command ( & self ) -> Command {
262
- let mut cmd = match & self . config {
278
+ let ( mut cmd, args , invocation_strategy ) = match & self . config {
263
279
FlycheckConfig :: CargoCommand {
264
280
command,
265
281
target_triple,
@@ -269,12 +285,11 @@ impl FlycheckActor {
269
285
extra_args,
270
286
features,
271
287
extra_env,
288
+ invocation_strategy,
272
289
} => {
273
290
let mut cmd = Command :: new ( toolchain:: cargo ( ) ) ;
274
291
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" ] ) ;
278
293
279
294
if let Some ( target) = target_triple {
280
295
cmd. args ( & [ "--target" , target. as_str ( ) ] ) ;
@@ -293,18 +308,19 @@ impl FlycheckActor {
293
308
cmd. arg ( features. join ( " " ) ) ;
294
309
}
295
310
}
296
- cmd. args ( extra_args) ;
297
311
cmd. envs ( extra_env) ;
298
- cmd
312
+ ( cmd, extra_args , invocation_strategy )
299
313
}
300
- FlycheckConfig :: CustomCommand { command, args, extra_env } => {
314
+ FlycheckConfig :: CustomCommand { command, args, extra_env, invocation_strategy } => {
301
315
let mut cmd = Command :: new ( command) ;
302
- cmd. args ( args) ;
303
316
cmd. envs ( extra_env) ;
304
- cmd
317
+ ( cmd, args , invocation_strategy )
305
318
}
306
319
} ;
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
+ } ;
308
324
cmd
309
325
}
310
326
0 commit comments