@@ -10,6 +10,7 @@ use rayon::prelude::*;
10
10
use trustfall:: { FieldValue , TransparentValue } ;
11
11
12
12
use crate :: data_generation:: DataStorage ;
13
+ use crate :: query:: LintMode ;
13
14
use crate :: {
14
15
query:: { ActualSemverUpdate , LintLevel , OverrideStack , RequiredSemverUpdate , SemverQuery } ,
15
16
CrateReport , GlobalConfig , ReleaseType , WitnessGeneration ,
@@ -215,8 +216,9 @@ pub(super) fn run_check_release(
215
216
216
217
let ( queries_to_run, queries_to_skip) : ( Vec < _ > , _ ) =
217
218
SemverQuery :: all_queries ( ) . into_values ( ) . partition ( |query| {
218
- !version_change. supports_requirement ( overrides. effective_required_update ( query) )
219
- && overrides. effective_lint_level ( query) > LintLevel :: Allow
219
+ overrides. effective_lint_mode ( query) == LintMode :: AlwaysRun
220
+ || !version_change. supports_requirement ( overrides. effective_required_update ( query) )
221
+ && overrides. effective_lint_level ( query) > LintLevel :: Allow
220
222
} ) ;
221
223
let skipped_queries = queries_to_skip. len ( ) ;
222
224
@@ -272,6 +274,9 @@ pub(super) fn run_check_release(
272
274
273
275
let mut results_with_errors = vec ! [ ] ;
274
276
let mut results_with_warnings = vec ! [ ] ;
277
+ let mut results_with_always_run_errors = vec ! [ ] ;
278
+ let mut results_with_always_run_warnings = vec ! [ ] ;
279
+
275
280
for ( semver_query, time_to_decide, results) in all_results {
276
281
config
277
282
. log_verbose ( |config| {
@@ -309,20 +314,42 @@ pub(super) fn run_check_release(
309
314
. expect ( "print failed" ) ;
310
315
311
316
if !results. is_empty ( ) {
312
- match overrides. effective_lint_level ( semver_query) {
313
- LintLevel :: Deny => results_with_errors. push ( ( semver_query, results) ) ,
314
- LintLevel :: Warn => results_with_warnings. push ( ( semver_query, results) ) ,
315
- LintLevel :: Allow => unreachable ! (
317
+ let lint_level = overrides. effective_lint_level ( semver_query) ;
318
+ let lint_mode = overrides. effective_lint_mode ( semver_query) ;
319
+
320
+ match ( lint_level, lint_mode) {
321
+ ( LintLevel :: Deny , LintMode :: SemVer ) => {
322
+ results_with_errors. push ( ( semver_query, results) )
323
+ }
324
+ ( LintLevel :: Warn , LintMode :: SemVer ) => {
325
+ results_with_warnings. push ( ( semver_query, results) )
326
+ }
327
+ ( LintLevel :: Warn , LintMode :: AlwaysRun ) => {
328
+ results_with_always_run_warnings. push ( ( semver_query, results) )
329
+ }
330
+ ( LintLevel :: Deny , LintMode :: AlwaysRun ) => {
331
+ results_with_always_run_errors. push ( ( semver_query, results) )
332
+ }
333
+ ( LintLevel :: Allow , _) => unreachable ! (
316
334
"`LintLevel::Allow` lint was unexpectedly not skipped: {semver_query:?}"
317
335
) ,
318
336
} ;
319
337
}
320
338
}
321
339
322
- let produced_errors = !results_with_errors. is_empty ( ) ;
323
- let produced_warnings = !results_with_warnings. is_empty ( ) ;
324
- if produced_errors || produced_warnings {
325
- let status_color = if produced_errors {
340
+ let produced_semver_errors = !results_with_errors. is_empty ( ) ;
341
+ let produced_semver_warnings = !results_with_warnings. is_empty ( ) ;
342
+ let produced_always_run_errors = !results_with_always_run_errors. is_empty ( ) ;
343
+ let produced_always_run_warnings = !results_with_always_run_warnings. is_empty ( ) ;
344
+ let total_always_run_issues =
345
+ results_with_always_run_errors. len ( ) + results_with_always_run_warnings. len ( ) ;
346
+ let has_issues = produced_semver_errors
347
+ || produced_semver_warnings
348
+ || produced_always_run_errors
349
+ || produced_always_run_warnings;
350
+
351
+ if has_issues {
352
+ let status_color = if produced_semver_errors || produced_always_run_errors {
326
353
AnsiColor :: Red
327
354
} else {
328
355
AnsiColor :: Yellow
@@ -377,6 +404,35 @@ pub(super) fn run_check_release(
377
404
print_triggered_lint ( config, semver_query, results, witness_generation) ?;
378
405
}
379
406
407
+ for ( semver_query, results) in results_with_always_run_errors {
408
+ config. log_info ( |config| {
409
+ writeln ! (
410
+ config. stdout( ) ,
411
+ "\n --- risk failure {}: {} ---\n " ,
412
+ & semver_query. id,
413
+ & semver_query. human_readable_name
414
+ ) ?;
415
+ Ok ( ( ) )
416
+ } ) ?;
417
+
418
+ print_triggered_lint ( config, semver_query, results, witness_generation) ?;
419
+ }
420
+
421
+ // Process AlwaysRun warnings
422
+ for ( semver_query, results) in results_with_always_run_warnings {
423
+ config. log_info ( |config| {
424
+ writeln ! (
425
+ config. stdout( ) ,
426
+ "\n --- risk warning {}: {} ---\n " ,
427
+ semver_query. id,
428
+ semver_query. human_readable_name
429
+ ) ?;
430
+ Ok ( ( ) )
431
+ } ) ?;
432
+
433
+ print_triggered_lint ( config, semver_query, results, witness_generation) ?;
434
+ }
435
+
380
436
let required_bump = required_versions. iter ( ) . max ( ) . copied ( ) ;
381
437
let suggested_bump = suggested_versions. iter ( ) . max ( ) . copied ( ) ;
382
438
@@ -399,16 +455,14 @@ pub(super) fn run_check_release(
399
455
Color :: Ansi ( AnsiColor :: Red ) ,
400
456
true ,
401
457
) ?;
402
- } else if produced_warnings {
458
+ } else if produced_semver_warnings {
403
459
writeln ! ( config. stderr( ) ) ?;
404
460
config. shell_print (
405
461
"Summary" ,
406
462
"no semver update required" ,
407
463
Color :: Ansi ( AnsiColor :: Green ) ,
408
464
true ,
409
465
) ?;
410
- } else {
411
- unreachable ! ( "Expected either warnings or errors to be produced." ) ;
412
466
}
413
467
414
468
if let Some ( suggested_bump) = suggested_bump {
@@ -439,6 +493,30 @@ pub(super) fn run_check_release(
439
493
}
440
494
}
441
495
496
+ if total_always_run_issues > 0 {
497
+ writeln ! ( config. stderr( ) ) ?;
498
+ let label = if produced_always_run_errors {
499
+ "Risk Alert"
500
+ } else {
501
+ "Risk Notice"
502
+ } ;
503
+ let color = if produced_always_run_errors {
504
+ AnsiColor :: Red
505
+ } else {
506
+ AnsiColor :: Yellow
507
+ } ;
508
+
509
+ config. shell_print (
510
+ label,
511
+ format_args ! (
512
+ "{} potentially risky changes detected that require attention regardless of version bump" ,
513
+ total_always_run_issues
514
+ ) ,
515
+ Color :: Ansi ( color) ,
516
+ true ,
517
+ ) ?;
518
+ }
519
+
442
520
Ok ( CrateReport {
443
521
required_bump : required_bump. map ( ReleaseType :: from) ,
444
522
detected_bump : version_change,
0 commit comments