@@ -5,12 +5,12 @@ use crate::results::{BrokenReason, EncodingType, FailureReason, TestResult, Writ
5
5
use crate :: runner:: tasks:: TaskCtx ;
6
6
use crate :: runner:: OverrideResult ;
7
7
use cargo_metadata:: diagnostic:: DiagnosticLevel ;
8
- use cargo_metadata:: Message ;
8
+ use cargo_metadata:: { Message , Metadata , PackageId } ;
9
9
use failure:: Error ;
10
10
use remove_dir_all:: remove_dir_all;
11
11
use rustwide:: cmd:: { CommandError , ProcessLinesActions , SandboxBuilder } ;
12
12
use rustwide:: { Build , PrepareError } ;
13
- use std:: collections:: BTreeSet ;
13
+ use std:: collections:: { BTreeSet , HashSet } ;
14
14
use std:: convert:: TryFrom ;
15
15
16
16
fn failure_reason ( err : & Error ) -> FailureReason {
@@ -61,10 +61,25 @@ pub(super) fn detect_broken<T>(res: Result<T, Error>) -> Result<T, Error> {
61
61
}
62
62
}
63
63
64
+ fn get_local_packages ( build_env : & Build ) -> Fallible < HashSet < PackageId > > {
65
+ Ok ( build_env
66
+ . cargo ( )
67
+ . args ( & [ "metadata" , "--no-deps" , "--format-version=1" ] )
68
+ . log_output ( false )
69
+ . run_capture ( ) ?
70
+ . stdout_lines ( )
71
+ . iter ( )
72
+ . filter_map ( |line| serde_json:: from_str :: < Metadata > ( line) . ok ( ) )
73
+ . flat_map ( |metadata| metadata. packages . into_iter ( ) . map ( |pkg| pkg. id ) )
74
+ . collect :: < HashSet < _ > > ( ) )
75
+ }
76
+
64
77
fn run_cargo < DB : WriteResults > (
65
78
ctx : & TaskCtx < DB > ,
66
79
build_env : & Build ,
67
80
args : & [ & str ] ,
81
+ check_errors : bool ,
82
+ local_packages_id : & HashSet < PackageId > ,
68
83
) -> Fallible < ( ) > {
69
84
let mut rustflags = format ! ( "--cap-lints={}" , ctx. experiment. cap_lints. to_str( ) ) ;
70
85
if let Some ( ref tc_rustflags) = ctx. toolchain . rustflags {
@@ -84,42 +99,46 @@ fn run_cargo<DB: WriteResults>(
84
99
85
100
let mut detect_error = |line : & str , actions : & mut ProcessLinesActions | {
86
101
// Avoid trying to deserialize non JSON output
87
- if line. starts_with ( '{' ) {
88
- let message = serde_json:: from_str ( line) ;
89
- if let Ok ( message) = message {
90
- match message {
91
- Message :: CompilerMessage ( compiler_message) => {
92
- let inner_message = compiler_message. message ;
93
- match (
94
- inner_message. level ,
95
- Crate :: try_from ( & compiler_message. package_id ) ,
96
- ) {
97
- // the only local crate in a well defined job is the crate currently being tested
98
- ( DiagnosticLevel :: Error , Ok ( Crate :: Local ( _) ) ) => {
99
- if let Some ( code) = inner_message. code {
100
- error_codes. insert ( DiagnosticCode :: from ( code. code ) ) ;
101
- }
102
- }
103
- ( DiagnosticLevel :: Ice , Ok ( Crate :: Local ( _) ) ) => did_ice = true ,
104
- // If the error is in a crate that is not local then it's referred to a dependency
105
- // of the current crate
106
- ( DiagnosticLevel :: Error , Ok ( krate) ) => {
107
- deps. insert ( krate) ;
108
- }
109
- ( DiagnosticLevel :: Ice , Ok ( krate) ) => {
110
- deps. insert ( krate) ;
111
- }
102
+ if !line. starts_with ( '{' ) {
103
+ return ;
104
+ }
112
105
113
- _ => ( ) ,
114
- }
106
+ let message = match serde_json:: from_str ( line) {
107
+ Ok ( message) => message,
108
+ Err ( _) => return ,
109
+ } ;
115
110
116
- actions. replace_with_lines (
117
- inner_message. rendered . unwrap_or_default ( ) . split ( '\n' ) ,
118
- ) ;
111
+ match message {
112
+ Message :: CompilerMessage ( compiler_message) => {
113
+ let inner_message = compiler_message. message ;
114
+ match ( inner_message. level , & compiler_message. package_id ) {
115
+ // the only local crate in a well defined job is the crate currently being tested
116
+ ( DiagnosticLevel :: Error , pkgid) if local_packages_id. contains ( pkgid) => {
117
+ if let Some ( code) = inner_message. code {
118
+ error_codes. insert ( DiagnosticCode :: from ( code. code ) ) ;
119
+ }
120
+ }
121
+ ( DiagnosticLevel :: Ice , pkgid) if local_packages_id. contains ( pkgid) => {
122
+ did_ice = true
123
+ }
124
+ // If the error is in a crate that is not local then it's referred to a dependency
125
+ // of the current crate
126
+ ( DiagnosticLevel :: Error , pkgid) => {
127
+ if let Ok ( krate) = Crate :: try_from ( pkgid) {
128
+ deps. insert ( krate) ;
129
+ }
119
130
}
120
- _ => actions. remove_line ( ) ,
131
+ ( DiagnosticLevel :: Ice , pkgid) => {
132
+ if let Ok ( krate) = Crate :: try_from ( pkgid) {
133
+ deps. insert ( krate) ;
134
+ }
135
+ }
136
+ _ => ( ) ,
121
137
}
138
+
139
+ actions. replace_with_lines ( inner_message. rendered . unwrap_or_default ( ) . split ( '\n' ) ) ;
122
140
}
141
+ _ => actions. remove_line ( ) ,
123
142
}
124
143
} ;
125
144
@@ -128,8 +147,11 @@ fn run_cargo<DB: WriteResults>(
128
147
. args ( args)
129
148
. env ( "CARGO_INCREMENTAL" , "0" )
130
149
. env ( "RUST_BACKTRACE" , "full" )
131
- . env ( rustflags_env, rustflags)
132
- . process_lines ( & mut detect_error) ;
150
+ . env ( rustflags_env, rustflags) ;
151
+
152
+ if check_errors {
153
+ command = command. process_lines ( & mut detect_error) ;
154
+ }
133
155
134
156
if ctx. quiet {
135
157
command = command. no_output_timeout ( None ) ;
@@ -154,7 +176,7 @@ fn run_cargo<DB: WriteResults>(
154
176
pub ( super ) fn run_test < DB : WriteResults > (
155
177
action : & str ,
156
178
ctx : & TaskCtx < DB > ,
157
- test_fn : fn ( & TaskCtx < DB > , & Build ) -> Fallible < TestResult > ,
179
+ test_fn : fn ( & TaskCtx < DB > , & Build , & HashSet < PackageId > ) -> Fallible < TestResult > ,
158
180
) -> Fallible < ( ) > {
159
181
if let Some ( res) = ctx
160
182
. db
@@ -195,23 +217,34 @@ pub(super) fn run_test<DB: WriteResults>(
195
217
build = build. patch_with_git ( & patch. name , & patch. repo , & patch. branch ) ;
196
218
}
197
219
198
- detect_broken ( build. run ( |build| test_fn ( ctx, build) ) )
220
+ detect_broken ( build. run ( |build| {
221
+ let local_packages_id = get_local_packages ( build) ?;
222
+ test_fn ( ctx, build, & local_packages_id)
223
+ } ) )
199
224
} ,
200
225
) ?;
201
226
}
202
227
Ok ( ( ) )
203
228
}
204
229
205
- fn build < DB : WriteResults > ( ctx : & TaskCtx < DB > , build_env : & Build ) -> Fallible < ( ) > {
230
+ fn build < DB : WriteResults > (
231
+ ctx : & TaskCtx < DB > ,
232
+ build_env : & Build ,
233
+ local_packages_id : & HashSet < PackageId > ,
234
+ ) -> Fallible < ( ) > {
206
235
run_cargo (
207
236
ctx,
208
237
build_env,
209
238
& [ "build" , "--frozen" , "--message-format=json" ] ,
239
+ true ,
240
+ local_packages_id,
210
241
) ?;
211
242
run_cargo (
212
243
ctx,
213
244
build_env,
214
245
& [ "test" , "--frozen" , "--no-run" , "--message-format=json" ] ,
246
+ true ,
247
+ local_packages_id,
215
248
) ?;
216
249
Ok ( ( ) )
217
250
}
@@ -220,15 +253,18 @@ fn test<DB: WriteResults>(ctx: &TaskCtx<DB>, build_env: &Build) -> Fallible<()>
220
253
run_cargo (
221
254
ctx,
222
255
build_env,
223
- & [ "test" , "--frozen" , "--message-format=json" ] ,
256
+ & [ "test" , "--frozen" ] ,
257
+ false ,
258
+ & HashSet :: new ( ) ,
224
259
)
225
260
}
226
261
227
262
pub ( super ) fn test_build_and_test < DB : WriteResults > (
228
263
ctx : & TaskCtx < DB > ,
229
264
build_env : & Build ,
265
+ local_packages_id : & HashSet < PackageId > ,
230
266
) -> Fallible < TestResult > {
231
- let build_r = build ( ctx, build_env) ;
267
+ let build_r = build ( ctx, build_env, local_packages_id ) ;
232
268
let test_r = if build_r. is_ok ( ) {
233
269
Some ( test ( ctx, build_env) )
234
270
} else {
@@ -246,8 +282,9 @@ pub(super) fn test_build_and_test<DB: WriteResults>(
246
282
pub ( super ) fn test_build_only < DB : WriteResults > (
247
283
ctx : & TaskCtx < DB > ,
248
284
build_env : & Build ,
285
+ local_packages_id : & HashSet < PackageId > ,
249
286
) -> Fallible < TestResult > {
250
- if let Err ( err) = build ( ctx, build_env) {
287
+ if let Err ( err) = build ( ctx, build_env, local_packages_id ) {
251
288
Ok ( TestResult :: BuildFail ( failure_reason ( & err) ) )
252
289
} else {
253
290
Ok ( TestResult :: TestSkipped )
@@ -257,11 +294,20 @@ pub(super) fn test_build_only<DB: WriteResults>(
257
294
pub ( super ) fn test_check_only < DB : WriteResults > (
258
295
ctx : & TaskCtx < DB > ,
259
296
build_env : & Build ,
297
+ local_packages_id : & HashSet < PackageId > ,
260
298
) -> Fallible < TestResult > {
261
299
if let Err ( err) = run_cargo (
262
300
ctx,
263
301
build_env,
264
- & [ "check" , "--frozen" , "--all" , "--all-targets" ] ,
302
+ & [
303
+ "check" ,
304
+ "--frozen" ,
305
+ "--all" ,
306
+ "--all-targets" ,
307
+ "--message-format=json" ,
308
+ ] ,
309
+ true ,
310
+ local_packages_id,
265
311
) {
266
312
Ok ( TestResult :: BuildFail ( failure_reason ( & err) ) )
267
313
} else {
@@ -272,11 +318,20 @@ pub(super) fn test_check_only<DB: WriteResults>(
272
318
pub ( super ) fn test_clippy_only < DB : WriteResults > (
273
319
ctx : & TaskCtx < DB > ,
274
320
build_env : & Build ,
321
+ local_packages_id : & HashSet < PackageId > ,
275
322
) -> Fallible < TestResult > {
276
323
if let Err ( err) = run_cargo (
277
324
ctx,
278
325
build_env,
279
- & [ "clippy" , "--frozen" , "--all" , "--all-targets" ] ,
326
+ & [
327
+ "clippy" ,
328
+ "--frozen" ,
329
+ "--all" ,
330
+ "--all-targets" ,
331
+ "--message-format=json" ,
332
+ ] ,
333
+ true ,
334
+ local_packages_id,
280
335
) {
281
336
Ok ( TestResult :: BuildFail ( failure_reason ( & err) ) )
282
337
} else {
@@ -287,11 +342,20 @@ pub(super) fn test_clippy_only<DB: WriteResults>(
287
342
pub ( super ) fn test_rustdoc < DB : WriteResults > (
288
343
ctx : & TaskCtx < DB > ,
289
344
build_env : & Build ,
345
+ local_packages_id : & HashSet < PackageId > ,
290
346
) -> Fallible < TestResult > {
291
347
let res = run_cargo (
292
348
ctx,
293
349
build_env,
294
- & [ "doc" , "--frozen" , "--no-deps" , "--document-private-items" ] ,
350
+ & [
351
+ "doc" ,
352
+ "--frozen" ,
353
+ "--no-deps" ,
354
+ "--document-private-items" ,
355
+ "--message-format=json" ,
356
+ ] ,
357
+ true ,
358
+ local_packages_id,
295
359
) ;
296
360
297
361
// Make sure to remove the built documentation
0 commit comments