@@ -4,13 +4,12 @@ use crate::formatters::manifest::{read_prjfmt_manifest, RootManifest};
4
4
use crate :: { emoji, CLOG } ;
5
5
use anyhow:: { anyhow, Error , Result } ;
6
6
use filetime:: FileTime ;
7
- use glob;
8
7
use rayon:: prelude:: * ;
9
8
use serde:: { Deserialize , Serialize } ;
10
9
use std:: cmp:: Ordering ;
11
10
use std:: collections:: { BTreeMap , BTreeSet } ;
12
11
use std:: fs:: { metadata, read_to_string} ;
13
- use std:: iter:: Iterator ;
12
+ use std:: iter:: { IntoIterator , Iterator } ;
14
13
use std:: path:: PathBuf ;
15
14
use xshell:: cmd;
16
15
@@ -113,38 +112,48 @@ pub fn run_prjfmt(cwd: PathBuf, cache_dir: PathBuf) -> anyhow::Result<()> {
113
112
pub fn glob_to_path (
114
113
cwd : & PathBuf ,
115
114
extensions : & FileExtensions ,
116
- _includes : & Option < Vec < String > > ,
117
- _excludes : & Option < Vec < String > > ,
115
+ includes : & Option < Vec < String > > ,
116
+ excludes : & Option < Vec < String > > ,
118
117
) -> anyhow:: Result < Vec < PathBuf > > {
119
- let dir = cwd. to_str ( ) . unwrap_or ( "" ) ;
120
-
121
- let glob_ext = |extension| -> anyhow:: Result < _ > {
122
- let pat = format ! ( "{}/**/{}" , dir, extension) ;
123
- let globs = glob:: glob ( & pat) . map_err ( |err| {
124
- anyhow:: anyhow!(
125
- "{} Error at position: {} due to {}" ,
126
- emoji:: ERROR ,
127
- err. pos,
128
- err. msg
129
- )
130
- } ) ?;
131
-
132
- Ok ( globs. map ( |glob_res| Ok ( glob_res?) ) )
133
- } ;
118
+ use ignore:: { overrides:: OverrideBuilder , WalkBuilder } ;
134
119
135
- match extensions {
136
- FileExtensions :: SingleFile ( sfile) => glob_ext ( sfile) ?. collect ( ) ,
137
- FileExtensions :: MultipleFile ( strs) => {
138
- strs. iter ( )
139
- . map ( glob_ext)
140
- . try_fold ( Vec :: new ( ) , |mut v, globs| {
141
- for glob in globs? {
142
- v. push ( glob?)
143
- }
144
- Ok ( v)
145
- } )
120
+ let mut overrides_builder = OverrideBuilder :: new ( cwd) ;
121
+
122
+ if let Some ( includes) = includes {
123
+ for include in includes {
124
+ // Remove trailing `/` as we add one explicitly in the override
125
+ let include = include. trim_end_matches ( '/' ) ;
126
+ for extension in extensions. into_iter ( ) {
127
+ overrides_builder. add ( & format ! ( "{}/**/{}" , include, extension) ) ?;
128
+ }
129
+ }
130
+ } else {
131
+ for extension in extensions. into_iter ( ) {
132
+ overrides_builder. add ( & extension) ?;
146
133
}
147
134
}
135
+
136
+ if let Some ( excludes) = excludes {
137
+ for exclude in excludes {
138
+ overrides_builder. add ( & format ! ( "!{}" , exclude) ) ?;
139
+ }
140
+ }
141
+
142
+ let overrides = overrides_builder. build ( ) ?;
143
+
144
+ Ok ( WalkBuilder :: new ( cwd)
145
+ . overrides ( overrides)
146
+ . build ( )
147
+ . filter_map ( |e| {
148
+ e. ok ( ) . and_then ( |e| {
149
+ match e. file_type ( ) {
150
+ // Skip directory entries
151
+ Some ( t) if t. is_dir ( ) => None ,
152
+ _ => Some ( e. into_path ( ) ) ,
153
+ }
154
+ } )
155
+ } )
156
+ . collect ( ) )
148
157
}
149
158
150
159
/// Convert each PathBuf into FileMeta
@@ -246,6 +255,18 @@ pub enum FileExtensions {
246
255
MultipleFile ( Vec < String > ) ,
247
256
}
248
257
258
+ impl < ' a > IntoIterator for & ' a FileExtensions {
259
+ type Item = & ' a String ;
260
+ type IntoIter = either:: Either < std:: iter:: Once < & ' a String > , std:: slice:: Iter < ' a , String > > ;
261
+
262
+ fn into_iter ( self ) -> Self :: IntoIter {
263
+ match self {
264
+ FileExtensions :: SingleFile ( glob) => either:: Either :: Left ( std:: iter:: once ( glob) ) ,
265
+ FileExtensions :: MultipleFile ( globs) => either:: Either :: Right ( globs. iter ( ) ) ,
266
+ }
267
+ }
268
+ }
269
+
249
270
#[ derive( Debug , Deserialize , Serialize , Clone ) ]
250
271
/// Each context of the formatter config
251
272
pub struct CmdContext {
0 commit comments