|
3 | 3 | const debug = require("debug")("mocha:cli:watch"); |
4 | 4 | const path = require("node:path"); |
5 | 5 | const chokidar = require("chokidar"); |
6 | | -const glob = require("glob"); |
7 | 6 | const isPathInside = require("is-path-inside"); |
8 | | -const { minimatch } = require("minimatch"); |
| 7 | +const { minimatch, Minimatch } = require("minimatch"); |
9 | 8 | const Context = require("../context.js").Context; |
10 | 9 | const collectFiles = require("./collect-files.cjs"); |
11 | 10 | const { logSymbols } = require("../utils.cjs"); |
12 | 11 |
|
13 | 12 | /** |
14 | 13 | * @typedef {import('chokidar').FSWatcher} FSWatcher |
15 | | - * @typedef {import('glob').Glob['patterns'][number]} Pattern |
16 | | - * The `Pattern` class is not exported by the `glob` package. |
17 | | - * Ref [link](../../node_modules/glob/dist/commonjs/pattern.d.ts). |
18 | 14 | * @typedef {import('../mocha.cjs')} Mocha |
19 | 15 | * @typedef {import('../types.d.ts').BeforeWatchRun} BeforeWatchRun |
20 | 16 | * @typedef {import('../types.d.ts').FileCollectionOptions} FileCollectionOptions |
@@ -183,66 +179,40 @@ function createPathFilter(globPaths, basePath) { |
183 | 179 | // for checking if a path ends with `/**/*` |
184 | 180 | const globEnd = path.join(path.sep, "**", "*"); |
185 | 181 |
|
186 | | - /** |
187 | | - * The current glob pattern to check. |
188 | | - * @type {Pattern[]} |
189 | | - */ |
190 | 182 | const patterns = globPaths.flatMap((globPath) => { |
191 | | - return new glob.Glob(globPath, { |
| 183 | + const mm = new Minimatch(globPath, { |
192 | 184 | dot: true, |
193 | | - magicalBraces: true, |
194 | 185 | windowsPathsNoEscape: true, |
195 | | - }).patterns; |
196 | | - }, []); |
197 | | - |
198 | | - // each pattern will have its own path because of the `magicalBraces` option |
199 | | - for (const pattern of patterns) { |
200 | | - debug("processing glob pattern: %s", pattern.globString()); |
201 | | - |
202 | | - /** |
203 | | - * Path segments before the glob pattern. |
204 | | - * @type {string[]} |
205 | | - */ |
206 | | - const segments = []; |
207 | | - |
208 | | - /** |
209 | | - * The current glob pattern to check. |
210 | | - * @type {Pattern | null} |
211 | | - */ |
212 | | - let currentPattern = pattern; |
213 | | - let isGlob = false; |
214 | | - |
215 | | - do { |
216 | | - // save string patterns until a non-string (glob or regexp) is matched |
217 | | - const entry = currentPattern.pattern(); |
218 | | - const isString = typeof entry === "string"; |
219 | | - debug( |
220 | | - "found %s pattern: %s", |
221 | | - isString ? "string" : "glob or regexp", |
222 | | - entry, |
223 | | - ); |
224 | | - if (!isString) { |
225 | | - // if the entry is a glob |
226 | | - isGlob = true; |
227 | | - break; |
228 | | - } |
| 186 | + }); |
| 187 | + return mm.set.map((parts, index) => ({ |
| 188 | + parts, |
| 189 | + globString: mm.globSet[index], |
| 190 | + })); |
| 191 | + }); |
229 | 192 |
|
230 | | - segments.push(entry); |
| 193 | + for (const { parts, globString } of patterns) { |
| 194 | + debug("processing glob pattern: %s", globString); |
231 | 195 |
|
232 | | - // go to next pattern |
233 | | - } while ((currentPattern = currentPattern.rest())); |
| 196 | + let firstGlobIndex = parts.findIndex((part) => typeof part !== "string"); |
| 197 | + const isGlob = firstGlobIndex !== -1; |
234 | 198 | if (!isGlob) { |
235 | | - debug("all subpatterns of %j processed", pattern.globString()); |
| 199 | + firstGlobIndex = parts.length; |
| 200 | + debug("all subpatterns of %j processed", globString); |
236 | 201 | } |
237 | 202 |
|
238 | | - // match `cleanPath` (path without the glob part) and its subdirectories |
239 | | - const cleanPath = path.resolve(basePath, ...segments); |
| 203 | + // match `cleanPath` (path without the glob part) and its subdirectories. |
| 204 | + // After lots of errors, it turned out that globString is "/"-separated and keeps the absolute root (for example the |
| 205 | + // drive C:/ on Windows), so derive the static prefix from it. |
| 206 | + const cleanPath = path.resolve( |
| 207 | + basePath, |
| 208 | + globString.split("/").slice(0, firstGlobIndex).join("/"), |
| 209 | + ); |
240 | 210 | debug("clean path: %s", cleanPath); |
241 | 211 | res.dir.paths.add(cleanPath); |
242 | 212 | res.dir.globs.add(path.resolve(cleanPath, "**", "*")); |
243 | 213 |
|
244 | 214 | // match `absPath` and all of its contents |
245 | | - const absPath = path.resolve(basePath, pattern.globString()); |
| 215 | + const absPath = path.resolve(basePath, globString); |
246 | 216 | debug("absolute path: %s", absPath); |
247 | 217 | (isGlob ? res.match.globs : res.match.paths).add(absPath); |
248 | 218 |
|
|
0 commit comments