@@ -4,15 +4,94 @@ use git_repository as git;
44
55pub fn list (
66 repo : git:: Repository ,
7- _filters : Vec < String > ,
7+ filters : Vec < String > ,
88 format : OutputFormat ,
9- out : impl std:: io:: Write ,
9+ mut out : impl std:: io:: Write ,
1010) -> Result < ( ) > {
1111 if format != OutputFormat :: Human {
1212 bail ! ( "Only human output format is supported at the moment" ) ;
1313 }
1414 let config = repo. config_snapshot ( ) ;
1515 let config = config. plumbing ( ) ;
16- config. write_to ( out) ?;
16+ if let Some ( frontmatter) = config. frontmatter ( ) {
17+ for event in frontmatter {
18+ event. write_to ( & mut out) ?;
19+ }
20+ }
21+ let filters: Vec < _ > = filters. into_iter ( ) . map ( Filter :: new) . collect ( ) ;
22+ let mut last_meta = None ;
23+ for ( section, matter) in config. sections_and_postmatter ( ) {
24+ if !filters. is_empty ( ) && !filters. iter ( ) . any ( |filter| filter. matches_section ( section) ) {
25+ continue ;
26+ }
27+
28+ let meta = section. meta ( ) ;
29+ if last_meta. map_or ( true , |last| last != meta) {
30+ write_meta ( meta, & mut out) ?;
31+ }
32+ last_meta = Some ( meta) ;
33+
34+ section. write_to ( & mut out) ?;
35+ for event in matter {
36+ event. write_to ( & mut out) ?;
37+ }
38+ writeln ! ( & mut out) ?;
39+ }
1740 Ok ( ( ) )
1841}
42+
43+ struct Filter {
44+ name : String ,
45+ subsection : Option < String > ,
46+ }
47+
48+ impl Filter {
49+ fn new ( input : String ) -> Self {
50+ match git:: config:: parse:: key ( & input) {
51+ Some ( key) => Filter {
52+ name : key. section_name . into ( ) ,
53+ subsection : key. subsection_name . map ( ToOwned :: to_owned) ,
54+ } ,
55+ None => Filter {
56+ name : input,
57+ subsection : None ,
58+ } ,
59+ }
60+ }
61+
62+ fn matches_section ( & self , section : & git:: config:: file:: Section < ' _ > ) -> bool {
63+ let ignore_case = git:: glob:: wildmatch:: Mode :: IGNORE_CASE ;
64+
65+ if !git:: glob:: wildmatch ( self . name . as_bytes ( ) . into ( ) , section. header ( ) . name ( ) , ignore_case) {
66+ return false ;
67+ }
68+ match ( self . subsection . as_deref ( ) , section. header ( ) . subsection_name ( ) ) {
69+ ( Some ( filter) , Some ( name) ) => {
70+ if !git:: glob:: wildmatch ( filter. as_bytes ( ) . into ( ) , name, ignore_case) {
71+ return false ;
72+ }
73+ }
74+ ( None , None ) | ( None , Some ( _) ) => { }
75+ _ => return false ,
76+ } ;
77+ true
78+ }
79+ }
80+
81+ fn write_meta ( meta : & git:: config:: file:: Metadata , out : & mut impl std:: io:: Write ) -> std:: io:: Result < ( ) > {
82+ writeln ! (
83+ out,
84+ "# From '{}' ({:?}{}{})" ,
85+ meta. path
86+ . as_deref( )
87+ . map( |p| p. display( ) . to_string( ) )
88+ . unwrap_or_else( || "memory" . into( ) ) ,
89+ meta. source,
90+ ( meta. level != 0 )
91+ . then( || format!( ", include level {}" , meta. level) )
92+ . unwrap_or_default( ) ,
93+ ( meta. trust != git:: sec:: Trust :: Full )
94+ . then( || "untrusted" )
95+ . unwrap_or_default( )
96+ )
97+ }
0 commit comments