Skip to content

Commit 5f21b46

Browse files
committed
adding lots of tests, clean up types
Also, this fixes a but preventing `**/..` from working properly when it's the last in the pattern.
1 parent b12e6ba commit 5f21b46

23 files changed

+723
-151
lines changed

changelog.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ changes.
99
- Promise API instead of callbacks.
1010
- Accept pattern as string or array of strings.
1111
- Hybrid module distribution.
12-
13-
**Note:** `module.exports` in CommonJS mode is an object, not a
14-
function. Use the exported `default` or `glob` members to
15-
access the default function export in CommonJS modes.
16-
1712
- Full TypeScript support.
1813
- Exported `Glob` class is no longer an event emitter.
1914
- Exported `Glob` class has `walk()`, `walkSync()`, `stream()`,
@@ -69,7 +64,7 @@ changes.
6964
or vice versa, may thus result in more or fewer matches than
7065
expected. In general, it should only be used when the
7166
filesystem is known to differ from the platform default.
72-
- `realpath:true` no longer implies `absolute:true`. The
67+
- `realpath:true` no longer implies `absolute:true`. The
7368
relative path to the realpath will be emitted when `absolute`
7469
is not set.
7570

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"author": "Isaac Z. Schlueter <[email protected]> (http://blog.izs.me/)",
33
"name": "glob",
4-
"description": "a little globber",
4+
"description": "the most correct and second fastest glob implementation in JavaScript",
55
"version": "9.0.0-0",
66
"repository": {
77
"type": "git",
@@ -17,7 +17,7 @@
1717
},
1818
"require": {
1919
"types": "./dist/cjs/index-cjs.d.ts",
20-
"default": "./dist/cjs/index-cjs.js"
20+
"default": "./dist/cjs/index.js"
2121
}
2222
}
2323
},
@@ -59,7 +59,7 @@
5959
},
6060
"dependencies": {
6161
"fs.realpath": "^1.0.0",
62-
"minimatch": "^7.1.3",
62+
"minimatch": "^7.1.4",
6363
"minipass": "^4.2.1",
6464
"path-scurry": "^1.4.0"
6565
},

src/glob.ts

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,26 @@ const defaultPlatform: NodeJS.Platform =
2424
? process.platform
2525
: 'linux'
2626

27-
export interface GlobOptions extends MinimatchOptions {
28-
ignore?: string | string[] | Ignore
27+
export interface GlobOptions {
28+
absolute?: boolean
29+
allowWindowsEscape?: boolean
30+
cwd?: string
31+
dot?: boolean
2932
follow?: boolean
33+
ignore?: string | string[] | Ignore
3034
mark?: boolean
35+
matchBase?: boolean
36+
nobrace?: boolean
37+
nocase?: boolean
3138
nodir?: boolean
32-
cwd?: string
39+
noext?: boolean
40+
noglobstar?: boolean
41+
platform?: NodeJS.Platform
3342
realpath?: boolean
34-
absolute?: boolean
35-
withFileTypes?: boolean
3643
scurry?: PathScurry
37-
platform?: NodeJS.Platform
3844
signal?: AbortSignal
45+
windowsPathsNoEscape?: boolean
46+
withFileTypes?: boolean
3947
}
4048

4149
export type GlobOptionsWithFileTypesTrue = GlobOptions & {
@@ -57,7 +65,7 @@ type Result<Opts> = Opts extends GlobOptionsWithFileTypesTrue
5765
: Opts extends GlobOptionsWithFileTypesUnset
5866
? string
5967
: string | Path
60-
type Results<Opts> = Result<Opts>[]
68+
export type Results<Opts> = Result<Opts>[]
6169

6270
type FileTypes<Opts> = Opts extends GlobOptionsWithFileTypesTrue
6371
? true
@@ -80,7 +88,6 @@ export class Glob<Opts extends GlobOptions> {
8088
globSet: GlobSet
8189
globParts: GlobParts
8290
realpath: boolean
83-
nonull: boolean
8491
absolute: boolean
8592
matchBase: boolean
8693
windowsPathsNoEscape: boolean
@@ -95,6 +102,8 @@ export class Glob<Opts extends GlobOptions> {
95102
platform: NodeJS.Platform
96103
patterns: Pattern[]
97104
signal?: AbortSignal
105+
nobrace: boolean
106+
noext: boolean
98107

99108
constructor(pattern: string | string[], opts: Opts) {
100109
this.withFileTypes = !!opts.withFileTypes as FileTypes<Opts>
@@ -104,24 +113,16 @@ export class Glob<Opts extends GlobOptions> {
104113
this.nodir = !!opts.nodir
105114
this.mark = !!opts.mark
106115
this.cwd = opts.cwd || ''
116+
this.nobrace = !!opts.nobrace
117+
this.noext = !!opts.noext
107118
this.realpath = !!opts.realpath
108-
this.nonull = !!opts.nonull
109119
this.absolute = !!opts.absolute
110120

111121
this.noglobstar = !!opts.noglobstar
112122
this.matchBase = !!opts.matchBase
113123

114-
// if we're returning Path objects, we can't do nonull, because
115-
// the pattern is a string, not a Path
116-
if (this.withFileTypes) {
117-
if (this.nonull) {
118-
throw new TypeError(
119-
'cannot set nonull:true and withFileTypes:true'
120-
)
121-
}
122-
if (this.absolute) {
123-
throw new Error('cannot set absolute:true and withFileTypes:true')
124-
}
124+
if (this.withFileTypes && this.absolute) {
125+
throw new Error('cannot set absolute:true and withFileTypes:true')
125126
}
126127

127128
if (typeof pattern === 'string') {
@@ -149,6 +150,12 @@ export class Glob<Opts extends GlobOptions> {
149150
this.opts = { ...opts, platform: this.platform }
150151
if (opts.scurry) {
151152
this.scurry = opts.scurry
153+
if (
154+
opts.nocase !== undefined &&
155+
opts.nocase !== opts.scurry.nocase
156+
) {
157+
throw new Error('nocase option contradicts provided scurry option')
158+
}
152159
} else {
153160
const Scurry =
154161
opts.platform === 'win32'
@@ -170,13 +177,18 @@ export class Glob<Opts extends GlobOptions> {
170177

171178
const mmo: MinimatchOptions = {
172179
// default nocase based on platform
173-
nocase: this.nocase,
174180
...opts,
175-
nonegate: true,
176-
nocomment: true,
181+
dot: this.dot,
182+
matchBase: this.matchBase,
183+
nobrace: this.nobrace,
184+
nocase: this.nocase,
177185
nocaseMagicOnly: true,
186+
nocomment: true,
187+
noext: this.noext,
188+
nonegate: true,
178189
optimizationLevel: 2,
179190
platform: this.platform,
191+
windowsPathsNoEscape: this.windowsPathsNoEscape,
180192
}
181193

182194
const mms = this.pattern.map(p => new Minimatch(p, mmo))
@@ -224,35 +236,35 @@ export class Glob<Opts extends GlobOptions> {
224236
return [...matches]
225237
}
226238

227-
stream(): Minipass<Result<Opts>>
228-
stream(): Minipass<string | Path> {
239+
stream(): Minipass<Result<Opts>, Result<Opts>>
240+
stream(): Minipass<string | Path, string | Path> {
229241
return new GlobStream(this.patterns, this.scurry.cwd, {
230242
...this.opts,
231243
platform: this.platform,
232244
nocase: this.nocase,
233245
}).stream()
234246
}
235247

236-
streamSync(): Minipass<Result<Opts>>
237-
streamSync(): Minipass<string | Path> {
248+
streamSync(): Minipass<Result<Opts>, Result<Opts>>
249+
streamSync(): Minipass<string | Path, string | Path> {
238250
return new GlobStream(this.patterns, this.scurry.cwd, {
239251
...this.opts,
240252
platform: this.platform,
241253
nocase: this.nocase,
242254
}).streamSync()
243255
}
244256

245-
iteratorSync(): Generator<Result<Opts>, void, void> {
257+
iterateSync(): Generator<Result<Opts>, void, void> {
246258
return this.streamSync()[Symbol.iterator]()
247259
}
248260
[Symbol.iterator]() {
249-
return this.iteratorSync()
261+
return this.iterateSync()
250262
}
251263

252-
iterator(): AsyncGenerator<Result<Opts>, void, void> {
264+
iterate(): AsyncGenerator<Result<Opts>, void, void> {
253265
return this.stream()[Symbol.asyncIterator]()
254266
}
255267
[Symbol.asyncIterator]() {
256-
return this.iterator()
268+
return this.iterate()
257269
}
258270
}

src/ignore.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,33 @@ const defaultPlatform: NodeJS.Platform =
1616
: 'linux'
1717

1818
export class Ignore {
19-
platform: NodeJS.Platform
20-
nocase: boolean
2119
relative: Minimatch[]
2220
relativeChildren: Minimatch[]
2321
absolute: Minimatch[]
2422
absoluteChildren: Minimatch[]
2523

2624
constructor(
2725
ignored: string[],
28-
{ platform = defaultPlatform, nocase }: GlobWalkerOpts
26+
{
27+
nobrace,
28+
nocase,
29+
noext,
30+
noglobstar,
31+
platform = defaultPlatform,
32+
}: GlobWalkerOpts
2933
) {
30-
this.platform = platform
31-
this.nocase = !!nocase
3234
this.relative = []
3335
this.absolute = []
3436
this.relativeChildren = []
3537
this.absoluteChildren = []
3638
const mmopts = {
37-
platform: this.platform,
38-
optimizationLevel: 2,
3939
dot: true,
40+
nobrace,
4041
nocase,
42+
noext,
43+
noglobstar,
44+
optimizationLevel: 2,
45+
platform,
4146
}
4247

4348
// this is a little weird, but it gives us a clean set of optimized
@@ -57,7 +62,7 @@ export class Ignore {
5762
for (let i = 0; i < mm.set.length; i++) {
5863
const parsed = mm.set[i]
5964
const globParts = mm.globParts[i]
60-
const p = new Pattern(parsed, globParts, 0, this.platform)
65+
const p = new Pattern(parsed, globParts, 0, platform)
6166
const m = new Minimatch(p.globString(), mmopts)
6267
const children = globParts[globParts.length - 1] === '**'
6368
const absolute = p.isAbsolute()

0 commit comments

Comments
 (0)