@@ -226,12 +226,23 @@ pub(crate) struct ConcernConfig {
226226#[ derive( PartialEq , Eq , Debug , serde:: Deserialize ) ]
227227pub ( crate ) struct MentionsConfig {
228228 #[ serde( flatten) ]
229- pub ( crate ) paths : HashMap < String , MentionsPathConfig > ,
229+ pub ( crate ) entries : HashMap < String , MentionsEntryConfig > ,
230+ }
231+
232+ #[ derive( PartialEq , Eq , Debug , Default , serde:: Deserialize ) ]
233+ #[ serde( rename_all = "kebab-case" ) ]
234+ pub ( crate ) enum MentionsEntryType {
235+ #[ default]
236+ Filename ,
237+ Content ,
230238}
231239
232240#[ derive( PartialEq , Eq , Debug , serde:: Deserialize ) ]
233241#[ serde( deny_unknown_fields) ]
234- pub ( crate ) struct MentionsPathConfig {
242+ pub ( crate ) struct MentionsEntryConfig {
243+ #[ serde( alias = "type" ) ]
244+ #[ serde( default ) ]
245+ pub ( crate ) type_ : MentionsEntryType ,
235246 pub ( crate ) message : Option < String > ,
236247 #[ serde( default ) ]
237248 pub ( crate ) cc : Vec < String > ,
@@ -563,8 +574,62 @@ pub(crate) struct RenderedLinkConfig {
563574#[ serde( rename_all = "kebab-case" ) ]
564575#[ serde( deny_unknown_fields) ]
565576pub ( crate ) struct IssueLinksConfig {
566- #[ serde( default = "default_true" ) ]
567- pub ( crate ) check_commits : bool ,
577+ #[ serde( default ) ]
578+ pub ( crate ) check_commits : IssueLinksCheckCommitsConfig ,
579+ }
580+
581+ #[ derive( PartialEq , Eq , Debug ) ]
582+ pub ( crate ) enum IssueLinksCheckCommitsConfig {
583+ /// No checking of commits
584+ Off ,
585+ /// Only check for uncanonicalized issue links in commits
586+ Uncanonicalized ,
587+ /// Check for all issue links in commits
588+ All ,
589+ }
590+
591+ impl Default for IssueLinksCheckCommitsConfig {
592+ fn default ( ) -> Self {
593+ IssueLinksCheckCommitsConfig :: All
594+ }
595+ }
596+
597+ impl < ' de > serde:: Deserialize < ' de > for IssueLinksCheckCommitsConfig {
598+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
599+ where
600+ D : serde:: Deserializer < ' de > ,
601+ {
602+ struct CheckCommitsVisitor ;
603+
604+ impl < ' de > serde:: de:: Visitor < ' de > for CheckCommitsVisitor {
605+ type Value = IssueLinksCheckCommitsConfig ;
606+
607+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
608+ formatter. write_str ( "a bool or the string \" uncanonicalized\" " )
609+ }
610+
611+ fn visit_bool < E > ( self , v : bool ) -> Result < Self :: Value , E > {
612+ Ok ( if v {
613+ IssueLinksCheckCommitsConfig :: All
614+ } else {
615+ IssueLinksCheckCommitsConfig :: Off
616+ } )
617+ }
618+
619+ fn visit_str < E > ( self , v : & str ) -> Result < Self :: Value , E >
620+ where
621+ E : serde:: de:: Error ,
622+ {
623+ if v == "uncanonicalized" {
624+ Ok ( IssueLinksCheckCommitsConfig :: Uncanonicalized )
625+ } else {
626+ Err ( E :: custom ( "expected \" uncanonicalized\" " ) )
627+ }
628+ }
629+ }
630+
631+ deserializer. deserialize_any ( CheckCommitsVisitor )
632+ }
568633}
569634
570635#[ derive( PartialEq , Eq , Debug , serde:: Deserialize ) ]
@@ -587,11 +652,6 @@ pub(crate) struct BehindUpstreamConfig {
587652 pub ( crate ) days_threshold : Option < usize > ,
588653}
589654
590- #[ inline]
591- fn default_true ( ) -> bool {
592- true
593- }
594-
595655#[ derive( PartialEq , Eq , Debug , serde:: Deserialize ) ]
596656pub ( crate ) struct BackportConfig {
597657 // Config identifier -> labels
@@ -714,7 +774,7 @@ mod tests {
714774
715775 #[ test]
716776 fn sample ( ) {
717- let config = r#"
777+ let config = r## "
718778 [relabel]
719779 allow-unauthenticated = [
720780 "C-*"
@@ -745,6 +805,18 @@ mod tests {
745805 core = "T-core"
746806 infra = "T-infra"
747807
808+ [mentions."src/"]
809+ cc = ["@someone"]
810+
811+ [mentions."target/"]
812+ message = "This is a message."
813+ cc = ["@someone"]
814+
815+ [mentions."#[rustc_attr]"]
816+ type = "content"
817+ message = "This is a message."
818+ cc = ["@someone"]
819+
748820 [shortcut]
749821
750822 [issue-links]
@@ -766,7 +838,7 @@ mod tests {
766838 [range-diff]
767839
768840 [review-changes-since]
769- "# ;
841+ "## ;
770842 let config = toml:: from_str :: < Config > ( & config) . unwrap ( ) ;
771843 let mut ping_teams = HashMap :: new ( ) ;
772844 ping_teams. insert (
@@ -834,7 +906,34 @@ mod tests {
834906 github_releases: None ,
835907 review_submitted: None ,
836908 review_requested: None ,
837- mentions: None ,
909+ mentions: Some ( MentionsConfig {
910+ entries: HashMap :: from( [
911+ (
912+ "src/" . to_string( ) ,
913+ MentionsEntryConfig {
914+ type_: MentionsEntryType :: Filename ,
915+ message: None ,
916+ cc: vec![ "@someone" . to_string( ) ]
917+ }
918+ ) ,
919+ (
920+ "target/" . to_string( ) ,
921+ MentionsEntryConfig {
922+ type_: MentionsEntryType :: Filename ,
923+ message: Some ( "This is a message." . to_string( ) ) ,
924+ cc: vec![ "@someone" . to_string( ) ]
925+ }
926+ ) ,
927+ (
928+ "#[rustc_attr]" . to_string( ) ,
929+ MentionsEntryConfig {
930+ type_: MentionsEntryType :: Content ,
931+ message: Some ( "This is a message." . to_string( ) ) ,
932+ cc: vec![ "@someone" . to_string( ) ]
933+ }
934+ )
935+ ] )
936+ } ) ,
838937 no_merges: None ,
839938 pr_tracking: None ,
840939 transfer: None ,
@@ -845,7 +944,7 @@ mod tests {
845944 exclude_files: vec![ ] ,
846945 } ) ,
847946 issue_links: Some ( IssueLinksConfig {
848- check_commits: true ,
947+ check_commits: IssueLinksCheckCommitsConfig :: All ,
849948 } ) ,
850949 no_mentions: Some ( NoMentionsConfig {
851950 exclude_titles: vec![ "subtree update" . into( ) ] ,
@@ -940,7 +1039,7 @@ mod tests {
9401039 bot_pull_requests: None ,
9411040 rendered_link: None ,
9421041 issue_links: Some ( IssueLinksConfig {
943- check_commits: false ,
1042+ check_commits: IssueLinksCheckCommitsConfig :: Off ,
9441043 } ) ,
9451044 no_mentions: None ,
9461045 behind_upstream: Some ( BehindUpstreamConfig {
@@ -982,34 +1081,17 @@ mod tests {
9821081 }
9831082
9841083 #[ test]
985- fn relabel_new_config ( ) {
1084+ fn issue_links_uncanonicalized ( ) {
9861085 let config = r#"
987- [relabel]
988- allow-unauthenticated = ["ABCD-*"]
989-
990- [relabel.to-stable]
991- add-labels = ["regression-from-stable-to-stable"]
992- rem-labels = ["regression-from-stable-to-beta", "regression-from-stable-to-nightly"]
1086+ [issue-links]
1087+ check-commits = "uncanonicalized"
9931088 "# ;
9941089 let config = toml:: from_str :: < Config > ( & config) . unwrap ( ) ;
995-
996- let mut relabel_configs = HashMap :: new ( ) ;
997- relabel_configs. insert (
998- "to-stable" . into ( ) ,
999- RelabelRuleConfig {
1000- add_labels : vec ! [ "regression-from-stable-to-stable" . to_string( ) ] ,
1001- rem_labels : vec ! [
1002- "regression-from-stable-to-beta" . to_string( ) ,
1003- "regression-from-stable-to-nightly" . to_string( ) ,
1004- ] ,
1005- } ,
1006- ) ;
1007-
1008- let expected_cfg = RelabelConfig {
1009- allow_unauthenticated : vec ! [ "ABCD-*" . to_string( ) ] ,
1010- configs : Some ( relabel_configs) ,
1011- } ;
1012-
1013- assert_eq ! ( config. relabel, Some ( expected_cfg) ) ;
1090+ assert ! ( matches!(
1091+ config. issue_links,
1092+ Some ( IssueLinksConfig {
1093+ check_commits: IssueLinksCheckCommitsConfig :: Uncanonicalized
1094+ } )
1095+ ) ) ;
10141096 }
10151097}
0 commit comments