@@ -4,15 +4,94 @@ use git_repository as git;
4
4
5
5
pub fn list (
6
6
repo : git:: Repository ,
7
- _filters : Vec < String > ,
7
+ filters : Vec < String > ,
8
8
format : OutputFormat ,
9
- out : impl std:: io:: Write ,
9
+ mut out : impl std:: io:: Write ,
10
10
) -> Result < ( ) > {
11
11
if format != OutputFormat :: Human {
12
12
bail ! ( "Only human output format is supported at the moment" ) ;
13
13
}
14
14
let config = repo. config_snapshot ( ) ;
15
15
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
+ }
17
40
Ok ( ( ) )
18
41
}
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