1
1
import { spreadAsync } from '@vlocode/util' ;
2
2
import { minimatch , MinimatchOptions } from 'minimatch'
3
+ import { Glob } from 'glob'
3
4
4
5
export interface StatsOptions {
5
6
/**
@@ -33,7 +34,7 @@ export interface FindOptions extends WriteOptions {
33
34
/**
34
35
* Single or multiple Working directories to use when searching. If not specified the current working directory is used.
35
36
*/
36
- cwd ?: string | string [ ] ;
37
+ cwd ?: string | string [ ] ;
37
38
/**
38
39
* Glob patterns of natches to exclude from the search
39
40
*/
@@ -58,7 +59,7 @@ export interface FindOptions extends WriteOptions {
58
59
noCase ?: boolean ;
59
60
}
60
61
61
- type GlobPatterns = string | string [ ] | RegExp | RegExp [ ] ;
62
+ type GlobPatterns = string | string [ ] ;
62
63
63
64
export enum FindType {
64
65
file = 1 ,
@@ -185,55 +186,33 @@ export abstract class FileSystem {
185
186
* }
186
187
* ```
187
188
*/
188
- public async * find ( globPatterns : GlobPatterns , options ?: FindOptions ) : AsyncGenerator < string > {
189
- const inputCwd = options ?. cwd ;
190
- if ( Array . isArray ( inputCwd ) ) {
191
- // When multiple cwd's are specified, search each of them
192
- for ( const cwd of inputCwd ) {
193
- yield * this . find ( globPatterns , { ...options , cwd : this . normalizeSeparators ( cwd ) } ) ;
194
- }
195
- return ;
196
- }
189
+ public async * find ( patterns : GlobPatterns , options ?: FindOptions ) : AsyncGenerator < string > {
190
+ const globs = ( Array . isArray ( patterns ) ? patterns : [ patterns ] ) . flatMap (
191
+ pattern => ( options ?. cwd && Array . isArray ( options . cwd ) ? options . cwd : [ options ?. cwd ] ) . map (
192
+ ( cwd : string | undefined ) => new Glob ( pattern , {
193
+ cwd,
194
+ withFileTypes : true ,
195
+ windowsPathsNoEscape : true ,
196
+ dotRelative : true ,
197
+ ignore : options ?. exclude ,
198
+ noext : true ,
199
+ nodir : options ?. findType === FindType . file ,
200
+ maxDepth : options ?. depth ,
201
+ nocase : options ?. noCase
202
+ } )
203
+ )
204
+ ) ;
197
205
198
- const cwd = this . normalizeSeparators ( inputCwd ?? process . cwd ( ) ) ;
199
- const patterns = this . compilePatterns ( globPatterns ) ;
200
- const excludePatterns = options ?. exclude ? this . compilePatterns ( options ?. exclude ) : undefined ;
201
- const findType = typeof options ?. findType === 'string'
202
- ? ( options ?. findType === 'directory' ? FindType . directory : FindType . file )
203
- : ( options ?. findType ?? FindType . file | FindType . directory ) ;
204
- const depth = options ?. depth ;
205
206
let limit = options ?. limit ;
206
207
207
- for ( const info of await this . readDirectory ( cwd ) ) {
208
- const path = `${ cwd } /${ info . name } ` ;
209
-
210
- // Exclude according to exclude patterns
211
- if ( excludePatterns ?. some ( pattern => pattern . test ( info . name ) || pattern . test ( path ) ) ) {
212
- continue ;
213
- }
214
-
215
- if ( info . isDirectory ( ) ) {
216
- // Match directory
217
- if ( findType & FindType . directory ) {
218
- if ( patterns . some ( pattern => pattern . test ( info . name ) || pattern . test ( path ) ) ) {
219
- yield path ;
220
- if ( limit && -- limit <= 0 ) {
221
- return ;
222
- }
223
- }
224
- }
225
-
226
- if ( depth === undefined || depth > 0 ) {
227
- // Search sub directories when depth is not specified or when depth is not yet reached
228
- yield * this . find ( patterns , { ...options , cwd : path , depth : depth && depth - 1 , limit } ) ;
229
- }
230
- } else if ( info . isFile ( ) && findType & FindType . file ) {
231
- // Match files?
232
- if ( patterns . some ( pattern => pattern . test ( info . name ) || pattern . test ( path ) ) ) {
233
- yield path ;
234
- if ( limit && -- limit <= 0 ) {
235
- return ;
236
- }
208
+ for ( const glob of globs ) {
209
+ for await ( const file of glob ) {
210
+ if ( options ?. findType === FindType . directory && ! file . isDirectory ( ) ) {
211
+ continue ;
212
+ }
213
+ yield this . normalizeSeparators ( file . fullpath ( ) ) ;
214
+ if ( limit !== undefined && -- limit === 0 ) {
215
+ return ;
237
216
}
238
217
}
239
218
}
@@ -242,7 +221,7 @@ export abstract class FileSystem {
242
221
private compilePatterns ( patterns : GlobPatterns , options ?: MinimatchOptions ) : RegExp [ ] {
243
222
return ( Array . isArray ( patterns ) ? patterns : [ patterns ] ) . map ( pattern => {
244
223
if ( typeof pattern === 'string' ) {
245
- const compiled = minimatch . makeRe ( pattern , options ) ;
224
+ const compiled = minimatch . makeRe ( this . normalizeSeparators ( pattern ) , options ) ;
246
225
if ( ! compiled ) {
247
226
throw new Error ( `Invalid glob pattern: ${ pattern } ` ) ;
248
227
}
0 commit comments