@@ -38,6 +38,7 @@ use format::lazy_format;
3838use indexmap:: { IndexMap , IndexSet } ;
3939use itertools:: Itertools ;
4040use joinery:: JoinableIterator ;
41+ use metadata:: ImplementationStatus ;
4142use miette:: { miette, Diagnostic , IntoDiagnostic , NamedSource , Report , SourceSpan , WrapErr } ;
4243use path_dsl:: path;
4344use rayon:: prelude:: { IntoParallelIterator , ParallelIterator } ;
@@ -97,6 +98,9 @@ enum Subcommand {
9798 /// The heuristic for resolving differences between current metadata and processed reports.
9899 #[ clap( long, default_value = "reset-contradictory" ) ]
99100 preset : ReportProcessingPreset ,
101+ /// The `implementation-status` that changes should be applied to.
102+ #[ clap( value_enum, long, default_value_t = ImplementationStatus :: Backlog ) ]
103+ implementation_status : ImplementationStatus ,
100104 } ,
101105 /// Parse test metadata, apply automated fixups, and re-emit it in normalized form.
102106 #[ clap( name = "fixup" , alias = "fmt" ) ]
@@ -167,6 +171,7 @@ fn run(cli: Cli) -> ExitCode {
167171 report_globs,
168172 report_paths,
169173 preset,
174+ implementation_status,
170175 } => {
171176 let report_globs = {
172177 let mut found_glob_parse_err = false ;
@@ -553,49 +558,63 @@ fn run(cli: Cli) -> ExitCode {
553558 let recombined_tests_iter = entries_by_cts_path
554559 . chain ( other_entries_by_test)
555560 . filter_map ( |( test_path, test_entry) | {
561+ /// Reconciles `meta_props` with `reported` if they match
562+ /// `implementation_status_filter`.
563+ ///
564+ /// For subtests, `parent_implementation_status` should be specified so the
565+ /// parent test's implementation status can be used for filtering.
556566 fn reconcile < Out > (
567+ parent_implementation_status : Option <
568+ & ExpandedPropertyValue < ImplementationStatus > ,
569+ > ,
557570 meta_props : & mut TestProps < Out > ,
558571 reported : BTreeMap < Platform , BTreeMap < BuildProfile , Expected < Out > > > ,
559572 preset : ReportProcessingPreset ,
573+ implementation_status_filter : ImplementationStatus ,
560574 ) where
561575 Out : Debug + Default + EnumSetType ,
562576 {
563- let reconciled = ' resolve: {
564- let reported = |platform, build_profile| {
577+ let implementation_status = meta_props
578+ . implementation_status
579+ . or ( parent_implementation_status. cloned ( ) )
580+ . unwrap_or_default ( ) ;
581+ let should_apply_changes =
582+ |key| implementation_status[ key] == implementation_status_filter;
583+ let reconciled = {
584+ let reported = |( platform, build_profile) | {
565585 reported
566586 . get ( & platform)
567587 . and_then ( |rep| rep. get ( & build_profile) )
568588 . copied ( )
569589 } ;
570- let all_reported = || {
571- ExpandedPropertyValue :: from_query ( |platform, build_profile| {
572- reported ( platform, build_profile) . unwrap_or_default ( )
573- } )
574- } ;
575- let resolve = match preset {
576- ReportProcessingPreset :: ResetAll => {
577- break ' resolve all_reported ( ) ;
578- }
579- ReportProcessingPreset :: ResetContradictory => {
580- |meta : Expected < _ > , rep : Option < Expected < _ > > | {
581- rep. filter ( |rep| !meta. is_superset ( rep) ) . unwrap_or ( meta)
590+ if let Some ( meta_expected) = meta_props. expected {
591+ let resolve = match preset {
592+ ReportProcessingPreset :: ResetAll => {
593+ |_meta, rep : Option < _ > | rep. unwrap_or_default ( )
582594 }
583- }
584- ReportProcessingPreset :: Merge => |meta, rep| match rep {
585- Some ( rep) => meta | rep,
586- None => meta,
587- } ,
588- } ;
595+ ReportProcessingPreset :: ResetContradictory => {
596+ |meta : Expected < _ > , rep : Option < Expected < _ > > | {
597+ rep. filter ( |rep| !meta. is_superset ( rep) ) . unwrap_or ( meta)
598+ }
599+ }
600+ ReportProcessingPreset :: Merge => |meta, rep| match rep {
601+ Some ( rep) => meta | rep,
602+ None => meta,
603+ } ,
604+ } ;
589605
590- if let Some ( meta_expected) = meta_props. expected {
591606 ExpandedPropertyValue :: from_query ( |platform, build_profile| {
592- resolve (
593- meta_expected[ ( platform, build_profile) ] ,
594- reported ( platform, build_profile) ,
595- )
607+ let key = ( platform, build_profile) ;
608+ if should_apply_changes ( key) {
609+ resolve ( meta_expected[ key] , reported ( key) )
610+ } else {
611+ meta_expected[ key]
612+ }
596613 } )
597614 } else {
598- all_reported ( )
615+ ExpandedPropertyValue :: from_query ( |platform, build_profile| {
616+ reported ( ( platform, build_profile) ) . unwrap_or_default ( )
617+ } )
599618 }
600619 } ;
601620 meta_props. expected = Some ( reconciled) ;
@@ -664,7 +683,13 @@ fn run(cli: Cli) -> ExitCode {
664683 }
665684 }
666685
667- reconcile ( & mut properties, test_reported, preset) ;
686+ reconcile (
687+ None ,
688+ & mut properties,
689+ test_reported,
690+ preset,
691+ implementation_status,
692+ ) ;
668693
669694 let mut subtests = BTreeMap :: new ( ) ;
670695 for ( subtest_name, subtest) in subtest_entries {
@@ -675,17 +700,30 @@ fn run(cli: Cli) -> ExitCode {
675700 }
676701
677702 let Entry {
678- meta_props : properties ,
703+ meta_props : subtest_properties ,
679704 reported : subtest_reported,
680705 } = subtest;
681706
682- let mut properties = properties. unwrap_or_default ( ) ;
683- reconcile ( & mut properties, subtest_reported, preset) ;
684- for ( _, expected) in properties. expected . as_mut ( ) . unwrap ( ) . iter_mut ( ) {
707+ let mut subtest_properties = subtest_properties. unwrap_or_default ( ) ;
708+ reconcile (
709+ properties. implementation_status . as_ref ( ) ,
710+ & mut subtest_properties,
711+ subtest_reported,
712+ preset,
713+ implementation_status,
714+ ) ;
715+ for ( _, expected) in
716+ subtest_properties. expected . as_mut ( ) . unwrap ( ) . iter_mut ( )
717+ {
685718 taint_subtest_timeouts_by_suspicion ( expected) ;
686719 }
687720
688- subtests. insert ( subtest_name, Subtest { properties } ) ;
721+ subtests. insert (
722+ subtest_name,
723+ Subtest {
724+ properties : subtest_properties,
725+ } ,
726+ ) ;
689727 }
690728
691729 if subtests. is_empty ( ) && properties == Default :: default ( ) {
0 commit comments