1
+ use glob_match:: glob_match;
1
2
use std:: iter;
2
3
use std:: path:: { Path , PathBuf } ;
3
4
5
+ use crate :: GlobEntry ;
6
+
4
7
pub fn fast_glob (
5
- base_path : & Path ,
6
- patterns : & Vec < String > ,
8
+ patterns : & Vec < GlobEntry > ,
7
9
) -> Result < impl iter:: Iterator < Item = PathBuf > , std:: io:: Error > {
8
- Ok ( get_fast_patterns ( base_path , patterns)
10
+ Ok ( get_fast_patterns ( patterns)
9
11
. into_iter ( )
10
12
. flat_map ( |( base_path, patterns) | {
11
13
globwalk:: GlobWalkerBuilder :: from_patterns ( base_path, & patterns)
@@ -40,10 +42,13 @@ pub fn fast_glob(
40
42
/// tailwind --pwd ./project/pages --content "**/*.js"
41
43
/// tailwind --pwd ./project/components --content "**/*.js"
42
44
/// ```
43
- fn get_fast_patterns ( base_path : & Path , patterns : & Vec < String > ) -> Vec < ( PathBuf , Vec < String > ) > {
45
+ pub fn get_fast_patterns ( patterns : & Vec < GlobEntry > ) -> Vec < ( PathBuf , Vec < String > ) > {
44
46
let mut optimized_patterns: Vec < ( PathBuf , Vec < String > ) > = vec ! [ ] ;
45
47
46
48
for pattern in patterns {
49
+ let base_path = PathBuf :: from ( & pattern. base ) ;
50
+ let pattern = & pattern. glob ;
51
+
47
52
let is_negated = pattern. starts_with ( '!' ) ;
48
53
let mut pattern = pattern. clone ( ) ;
49
54
if is_negated {
@@ -54,13 +59,13 @@ fn get_fast_patterns(base_path: &Path, patterns: &Vec<String>) -> Vec<(PathBuf,
54
59
55
60
if folders. len ( ) <= 1 {
56
61
// No paths we can simplify, so let's use it as-is.
57
- optimized_patterns. push ( ( base_path. to_path_buf ( ) , vec ! [ pattern] ) ) ;
62
+ optimized_patterns. push ( ( base_path, vec ! [ pattern] ) ) ;
58
63
} else {
59
64
// We do have folders because `/` exists. Let's try to simplify the globs!
60
65
// Safety: We know that the length is greater than 1, so we can safely unwrap.
61
66
let file_pattern = folders. pop ( ) . unwrap ( ) ;
62
67
let all_folders = folders. clone ( ) ;
63
- let mut temp_paths = vec ! [ base_path. to_path_buf ( ) ] ;
68
+ let mut temp_paths = vec ! [ base_path] ;
64
69
65
70
let mut bail = false ;
66
71
@@ -131,6 +136,14 @@ fn get_fast_patterns(base_path: &Path, patterns: &Vec<String>) -> Vec<(PathBuf,
131
136
optimized_patterns
132
137
}
133
138
139
+ pub fn path_matches_globs ( path : & Path , globs : & [ GlobEntry ] ) -> bool {
140
+ let path = path. to_string_lossy ( ) ;
141
+
142
+ globs
143
+ . iter ( )
144
+ . any ( |g| glob_match ( & format ! ( "{}/{}" , g. base, g. glob) , & path) )
145
+ }
146
+
134
147
/// Given this input: a-{b,c}-d-{e,f}
135
148
/// We will get:
136
149
/// [
@@ -228,30 +241,38 @@ fn expand_braces(input: &str) -> Vec<String> {
228
241
#[ cfg( test) ]
229
242
mod tests {
230
243
use super :: get_fast_patterns;
244
+ use crate :: GlobEntry ;
231
245
use std:: path:: PathBuf ;
232
246
233
247
#[ test]
234
248
fn it_should_keep_globs_that_start_with_file_wildcards_as_is ( ) {
235
- let actual = get_fast_patterns ( & PathBuf :: from ( "/projects" ) , & vec ! [ "*.html" . to_string( ) ] ) ;
249
+ let actual = get_fast_patterns ( & vec ! [ GlobEntry {
250
+ base: "/projects" . to_string( ) ,
251
+ glob: "*.html" . to_string( ) ,
252
+ } ] ) ;
236
253
let expected = vec ! [ ( PathBuf :: from( "/projects" ) , vec![ "*.html" . to_string( ) ] ) ] ;
237
254
238
255
assert_eq ! ( actual, expected, ) ;
239
256
}
240
257
241
258
#[ test]
242
259
fn it_should_keep_globs_that_start_with_folder_wildcards_as_is ( ) {
243
- let actual = get_fast_patterns ( & PathBuf :: from ( "/projects" ) , & vec ! [ "**/*.html" . to_string( ) ] ) ;
260
+ let actual = get_fast_patterns ( & vec ! [ GlobEntry {
261
+ base: "/projects" . to_string( ) ,
262
+ glob: "**/*.html" . to_string( ) ,
263
+ } ] ) ;
264
+
244
265
let expected = vec ! [ ( PathBuf :: from( "/projects" ) , vec![ "**/*.html" . to_string( ) ] ) ] ;
245
266
246
267
assert_eq ! ( actual, expected, ) ;
247
268
}
248
269
249
270
#[ test]
250
271
fn it_should_move_the_starting_folder_to_the_path ( ) {
251
- let actual = get_fast_patterns (
252
- & PathBuf :: from ( "/projects" ) ,
253
- & vec ! [ "example/*.html" . to_string( ) ] ,
254
- ) ;
272
+ let actual = get_fast_patterns ( & vec ! [ GlobEntry {
273
+ base : "/projects" . to_string ( ) ,
274
+ glob : "example/*.html" . to_string( ) ,
275
+ } ] ) ;
255
276
let expected = vec ! [ (
256
277
PathBuf :: from( "/projects/example" ) ,
257
278
vec![ "*.html" . to_string( ) ] ,
@@ -262,10 +283,10 @@ mod tests {
262
283
263
284
#[ test]
264
285
fn it_should_move_the_starting_folders_to_the_path ( ) {
265
- let actual = get_fast_patterns (
266
- & PathBuf :: from ( "/projects" ) ,
267
- & vec ! [ "example/other/*.html" . to_string( ) ] ,
268
- ) ;
286
+ let actual = get_fast_patterns ( & vec ! [ GlobEntry {
287
+ base : "/projects" . to_string ( ) ,
288
+ glob : "example/other/*.html" . to_string( ) ,
289
+ } ] ) ;
269
290
let expected = vec ! [ (
270
291
PathBuf :: from( "/projects/example/other" ) ,
271
292
vec![ "*.html" . to_string( ) ] ,
@@ -276,10 +297,11 @@ mod tests {
276
297
277
298
#[ test]
278
299
fn it_should_branch_expandable_folders ( ) {
279
- let actual = get_fast_patterns (
280
- & PathBuf :: from ( "/projects" ) ,
281
- & vec ! [ "{foo,bar}/*.html" . to_string( ) ] ,
282
- ) ;
300
+ let actual = get_fast_patterns ( & vec ! [ GlobEntry {
301
+ base: "/projects" . to_string( ) ,
302
+ glob: "{foo,bar}/*.html" . to_string( ) ,
303
+ } ] ) ;
304
+
283
305
let expected = vec ! [
284
306
( PathBuf :: from( "/projects/foo" ) , vec![ "*.html" . to_string( ) ] ) ,
285
307
( PathBuf :: from( "/projects/bar" ) , vec![ "*.html" . to_string( ) ] ) ,
@@ -290,10 +312,10 @@ mod tests {
290
312
291
313
#[ test]
292
314
fn it_should_expand_multiple_expansions_in_the_same_folder ( ) {
293
- let actual = get_fast_patterns (
294
- & PathBuf :: from ( "/projects" ) ,
295
- & vec ! [ "a-{b,c}-d-{e,f}-g/*.html" . to_string( ) ] ,
296
- ) ;
315
+ let actual = get_fast_patterns ( & vec ! [ GlobEntry {
316
+ base : "/projects" . to_string ( ) ,
317
+ glob : "a-{b,c}-d-{e,f}-g/*.html" . to_string( ) ,
318
+ } ] ) ;
297
319
let expected = vec ! [
298
320
(
299
321
PathBuf :: from( "/projects/a-b-d-e-g" ) ,
@@ -318,10 +340,10 @@ mod tests {
318
340
319
341
#[ test]
320
342
fn multiple_expansions_per_folder_starting_at_the_root ( ) {
321
- let actual = get_fast_patterns (
322
- & PathBuf :: from ( "/projects" ) ,
323
- & vec ! [ "{a,b}-c-{d,e}-f/{b,c}-d-{e,f}-g/*.html" . to_string( ) ] ,
324
- ) ;
343
+ let actual = get_fast_patterns ( & vec ! [ GlobEntry {
344
+ base : "/projects" . to_string ( ) ,
345
+ glob : "{a,b}-c-{d,e}-f/{b,c}-d-{e,f}-g/*.html" . to_string( ) ,
346
+ } ] ) ;
325
347
let expected = vec ! [
326
348
(
327
349
PathBuf :: from( "/projects/a-c-d-f/b-d-e-g" ) ,
@@ -394,10 +416,11 @@ mod tests {
394
416
395
417
#[ test]
396
418
fn it_should_stop_expanding_once_we_hit_a_wildcard ( ) {
397
- let actual = get_fast_patterns (
398
- & PathBuf :: from ( "/projects" ) ,
399
- & vec ! [ "{foo,bar}/example/**/{baz,qux}/*.html" . to_string( ) ] ,
400
- ) ;
419
+ let actual = get_fast_patterns ( & vec ! [ GlobEntry {
420
+ base: "/projects" . to_string( ) ,
421
+ glob: "{foo,bar}/example/**/{baz,qux}/*.html" . to_string( ) ,
422
+ } ] ) ;
423
+
401
424
let expected = vec ! [
402
425
(
403
426
PathBuf :: from( "/projects/foo/example" ) ,
@@ -414,10 +437,10 @@ mod tests {
414
437
415
438
#[ test]
416
439
fn it_should_keep_the_negation_symbol_for_all_new_patterns ( ) {
417
- let actual = get_fast_patterns (
418
- & PathBuf :: from ( "/projects" ) ,
419
- & vec ! [ "!{foo,bar}/*.html" . to_string( ) ] ,
420
- ) ;
440
+ let actual = get_fast_patterns ( & vec ! [ GlobEntry {
441
+ base : "/projects" . to_string ( ) ,
442
+ glob : "!{foo,bar}/*.html" . to_string( ) ,
443
+ } ] ) ;
421
444
let expected = vec ! [
422
445
( PathBuf :: from( "/projects/foo" ) , vec![ "!*.html" . to_string( ) ] ) ,
423
446
( PathBuf :: from( "/projects/bar" ) , vec![ "!*.html" . to_string( ) ] ) ,
@@ -428,10 +451,10 @@ mod tests {
428
451
429
452
#[ test]
430
453
fn it_should_expand_a_complex_example ( ) {
431
- let actual = get_fast_patterns (
432
- & PathBuf :: from ( "/projects" ) ,
433
- & vec ! [ "a/{b,c}/d/{e,f}/g/*.html" . to_string( ) ] ,
434
- ) ;
454
+ let actual = get_fast_patterns ( & vec ! [ GlobEntry {
455
+ base : "/projects" . to_string ( ) ,
456
+ glob : "a/{b,c}/d/{e,f}/g/*.html" . to_string( ) ,
457
+ } ] ) ;
435
458
let expected = vec ! [
436
459
(
437
460
PathBuf :: from( "/projects/a/b/d/e/g" ) ,
0 commit comments