@@ -332,27 +332,47 @@ impl Commit<'_> {
332
332
if let ( Some ( field_name) , Some ( pattern_regex) ) =
333
333
( parser. field . as_ref ( ) , parser. pattern . as_ref ( ) )
334
334
{
335
- let value = if field_name == "body" {
336
- body. clone ( )
335
+ let values = if field_name == "body" {
336
+ vec ! [ body. clone( ) ] . into_iter ( ) . collect ( )
337
337
} else {
338
338
tera:: dotted_pointer ( & lookup_context, field_name) . and_then ( |v| {
339
- match & v {
340
- Value :: String ( s) => Some ( s. clone ( ) ) ,
339
+ match v {
340
+ Value :: String ( s) => Some ( vec ! [ s. clone( ) ] ) ,
341
341
Value :: Number ( _) | Value :: Bool ( _) | Value :: Null => {
342
- Some ( v. to_string ( ) )
342
+ Some ( vec ! [ v. to_string( ) ] )
343
+ }
344
+ Value :: Array ( arr) => {
345
+ let mut values = Vec :: new ( ) ;
346
+ for item in arr {
347
+ match item {
348
+ Value :: String ( s) => values. push ( s. clone ( ) ) ,
349
+ Value :: Number ( _) |
350
+ Value :: Bool ( _) |
351
+ Value :: Null => values. push ( item. to_string ( ) ) ,
352
+ _ => continue ,
353
+ }
354
+ }
355
+ Some ( values)
343
356
}
344
357
_ => None ,
345
358
}
346
359
} )
347
360
} ;
348
- match value {
349
- Some ( value) => {
350
- regex_checks. push ( ( pattern_regex, value) ) ;
361
+ match values {
362
+ Some ( values) => {
363
+ if values. is_empty ( ) {
364
+ trace ! ( "field '{field_name}' is present but empty" ) ;
365
+ } else {
366
+ for value in values {
367
+ regex_checks. push ( ( pattern_regex, value) ) ;
368
+ }
369
+ }
351
370
}
352
371
None => {
353
372
return Err ( AppError :: FieldError ( format ! (
354
373
"field '{field_name}' is missing or has unsupported \
355
- type (expected String, Number, Bool, or Null)",
374
+ type (expected a String, Number, Bool, or Null — or \
375
+ an Array of these scalar values)",
356
376
) ) ) ;
357
377
}
358
378
}
@@ -727,11 +747,83 @@ mod test {
727
747
) ;
728
748
}
729
749
750
+ #[ test]
751
+ fn parse_body ( ) -> Result < ( ) > {
752
+ let mut commit = Commit :: new (
753
+ String :: from ( "8f55e69eba6e6ce811ace32bd84cc82215673cb6" ) ,
754
+ String :: from (
755
+ "fix: do something
756
+
757
+ Introduce something great
758
+
759
+ BREAKING CHANGE: drop support for something else
760
+ Refs: #123
761
+ " ,
762
+ ) ,
763
+ ) ;
764
+ commit. author = Signature {
765
+ name : Some ( "John Doe" . to_string ( ) ) ,
766
+ email : None ,
767
+ timestamp : 0x0 ,
768
+ } ;
769
+ commit. remote = Some ( crate :: contributor:: RemoteContributor {
770
+ username : None ,
771
+ pr_title : Some ( "feat: do something" . to_string ( ) ) ,
772
+ pr_number : None ,
773
+ pr_labels : vec ! [
774
+ String :: from( "feature" ) ,
775
+ String :: from( "deprecation" ) ,
776
+ ] ,
777
+ is_first_time : true ,
778
+ } ) ;
779
+ let commit = commit. into_conventional ( ) ?;
780
+ let commit = commit. parse_links ( & [
781
+ LinkParser {
782
+ pattern : Regex :: new ( "RFC(\\ d+)" ) ?,
783
+ href : String :: from ( "rfc://$1" ) ,
784
+ text : None ,
785
+ } ,
786
+ LinkParser {
787
+ pattern : Regex :: new ( "#(\\ d+)" ) ?,
788
+ href : String :: from ( "https://github.com/$1" ) ,
789
+ text : None ,
790
+ } ,
791
+ ] ) ?;
792
+
793
+ let parsed_commit = commit. clone ( ) . parse (
794
+ & [ CommitParser {
795
+ sha : None ,
796
+ message : None ,
797
+ body : Regex :: new ( "something great" ) . ok ( ) ,
798
+ footer : None ,
799
+ group : Some ( String :: from ( "Test group" ) ) ,
800
+ default_scope : None ,
801
+ scope : None ,
802
+ skip : None ,
803
+ field : None ,
804
+ pattern : None ,
805
+ } ] ,
806
+ false ,
807
+ false ,
808
+ ) ?;
809
+ assert_eq ! ( Some ( String :: from( "Test group" ) ) , parsed_commit. group) ;
810
+
811
+ Ok ( ( ) )
812
+ }
813
+
730
814
#[ test]
731
815
fn parse_commit_field ( ) -> Result < ( ) > {
732
816
let mut commit = Commit :: new (
733
817
String :: from ( "8f55e69eba6e6ce811ace32bd84cc82215673cb6" ) ,
734
- String :: from ( "feat: do something" ) ,
818
+ String :: from (
819
+ "fix: do something
820
+
821
+ Introduce something great
822
+
823
+ BREAKING CHANGE: drop support for something else
824
+ Refs: #123
825
+ " ,
826
+ ) ,
735
827
) ;
736
828
commit. author = Signature {
737
829
name : Some ( "John Doe" . to_string ( ) ) ,
@@ -742,9 +834,25 @@ mod test {
742
834
username : None ,
743
835
pr_title : Some ( "feat: do something" . to_string ( ) ) ,
744
836
pr_number : None ,
745
- pr_labels : Vec :: new ( ) ,
837
+ pr_labels : vec ! [
838
+ String :: from( "feature" ) ,
839
+ String :: from( "deprecation" ) ,
840
+ ] ,
746
841
is_first_time : true ,
747
842
} ) ;
843
+ let commit = commit. into_conventional ( ) ?;
844
+ let commit = commit. parse_links ( & [
845
+ LinkParser {
846
+ pattern : Regex :: new ( "RFC(\\ d+)" ) ?,
847
+ href : String :: from ( "rfc://$1" ) ,
848
+ text : None ,
849
+ } ,
850
+ LinkParser {
851
+ pattern : Regex :: new ( "#(\\ d+)" ) ?,
852
+ href : String :: from ( "https://github.com/$1" ) ,
853
+ text : None ,
854
+ } ,
855
+ ] ) ?;
748
856
749
857
let parsed_commit = commit. clone ( ) . parse (
750
858
& [ CommitParser {
@@ -782,7 +890,25 @@ mod test {
782
890
) ?;
783
891
assert_eq ! ( Some ( String :: from( "Test group" ) ) , parsed_commit. group) ;
784
892
785
- let parse_result = commit. clone ( ) . parse (
893
+ let parsed_commit = commit. clone ( ) . parse (
894
+ & [ CommitParser {
895
+ sha : None ,
896
+ message : None ,
897
+ body : None ,
898
+ footer : None ,
899
+ group : Some ( String :: from ( "Test group" ) ) ,
900
+ default_scope : None ,
901
+ scope : None ,
902
+ skip : None ,
903
+ field : Some ( String :: from ( "body" ) ) ,
904
+ pattern : Regex :: new ( "something great" ) . ok ( ) ,
905
+ } ] ,
906
+ false ,
907
+ false ,
908
+ ) ?;
909
+ assert_eq ! ( Some ( String :: from( "Test group" ) ) , parsed_commit. group) ;
910
+
911
+ let parsed_commit = commit. clone ( ) . parse (
786
912
& [ CommitParser {
787
913
sha : None ,
788
914
message : None ,
@@ -793,15 +919,50 @@ mod test {
793
919
scope : None ,
794
920
skip : None ,
795
921
field : Some ( String :: from ( "remote.pr_labels" ) ) ,
922
+ pattern : Regex :: new ( "feature|deprecation" ) . ok ( ) ,
923
+ } ] ,
924
+ false ,
925
+ false ,
926
+ ) ?;
927
+ assert_eq ! ( Some ( String :: from( "Test group" ) ) , parsed_commit. group) ;
928
+
929
+ let parsed_commit = commit. clone ( ) . parse (
930
+ & [ CommitParser {
931
+ sha : None ,
932
+ message : None ,
933
+ body : None ,
934
+ footer : None ,
935
+ group : Some ( String :: from ( "Test group" ) ) ,
936
+ default_scope : None ,
937
+ scope : None ,
938
+ skip : None ,
939
+ field : Some ( String :: from ( "links" ) ) ,
940
+ pattern : Regex :: new ( ".*" ) . ok ( ) ,
941
+ } ] ,
942
+ false ,
943
+ false ,
944
+ ) ?;
945
+ assert_eq ! ( None , parsed_commit. group) ;
946
+
947
+ let parse_result = commit. clone ( ) . parse (
948
+ & [ CommitParser {
949
+ sha : None ,
950
+ message : None ,
951
+ body : None ,
952
+ footer : None ,
953
+ group : Some ( String :: from ( "Test group" ) ) ,
954
+ default_scope : None ,
955
+ scope : None ,
956
+ skip : None ,
957
+ field : Some ( String :: from ( "remote" ) ) ,
796
958
pattern : Regex :: new ( ".*" ) . ok ( ) ,
797
959
} ] ,
798
960
false ,
799
961
false ,
800
962
) ;
801
963
assert ! (
802
964
parse_result. is_err( ) ,
803
- "Expected error when using unsupported field `remote.pr_labels`, but \
804
- got Ok"
965
+ "Expected error when using unsupported field `remote`, but got Ok"
805
966
) ;
806
967
807
968
Ok ( ( ) )
0 commit comments