Skip to content

Commit 5c36510

Browse files
committed
fs: add support for URL for fs.glob's cwd option
PR-URL: #58182 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: LiviaMedeiros <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jason Zhang <[email protected]>
1 parent 4cc4195 commit 5c36510

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

doc/api/fs.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,9 @@ changes:
10781078
- version: REPLACEME
10791079
pr-url: https://github.com/nodejs/node/pull/57513
10801080
description: Marking the API stable.
1081+
- version: REPLACEME
1082+
pr-url: https://github.com/nodejs/node/pull/58182
1083+
description: Add support for `URL` instances for `cwd` option.
10811084
- version: v22.14.0
10821085
pr-url: https://github.com/nodejs/node/pull/56489
10831086
description: Add support for `exclude` option to accept glob patterns.
@@ -1088,7 +1091,7 @@ changes:
10881091
10891092
* `pattern` {string|string\[]}
10901093
* `options` {Object}
1091-
* `cwd` {string} current working directory. **Default:** `process.cwd()`
1094+
* `cwd` {string|URL} current working directory. **Default:** `process.cwd()`
10921095
* `exclude` {Function|string\[]} Function to filter out files/directories or a
10931096
list of glob patterns to be excluded. If a function is provided, return
10941097
`true` to exclude the item, `false` to include it. **Default:** `undefined`.
@@ -3131,6 +3134,9 @@ changes:
31313134
- version: REPLACEME
31323135
pr-url: https://github.com/nodejs/node/pull/57513
31333136
description: Marking the API stable.
3137+
- version: REPLACEME
3138+
pr-url: https://github.com/nodejs/node/pull/58182
3139+
description: Add support for `URL` instances for `cwd` option.
31343140
- version: v22.14.0
31353141
pr-url: https://github.com/nodejs/node/pull/56489
31363142
description: Add support for `exclude` option to accept glob patterns.
@@ -3142,7 +3148,7 @@ changes:
31423148
* `pattern` {string|string\[]}
31433149
31443150
* `options` {Object}
3145-
* `cwd` {string} current working directory. **Default:** `process.cwd()`
3151+
* `cwd` {string|URL} current working directory. **Default:** `process.cwd()`
31463152
* `exclude` {Function|string\[]} Function to filter out files/directories or a
31473153
list of glob patterns to be excluded. If a function is provided, return
31483154
`true` to exclude the item, `false` to include it. **Default:** `undefined`.
@@ -5682,6 +5688,9 @@ changes:
56825688
- version: REPLACEME
56835689
pr-url: https://github.com/nodejs/node/pull/57513
56845690
description: Marking the API stable.
5691+
- version: REPLACEME
5692+
pr-url: https://github.com/nodejs/node/pull/58182
5693+
description: Add support for `URL` instances for `cwd` option.
56855694
- version: v22.14.0
56865695
pr-url: https://github.com/nodejs/node/pull/56489
56875696
description: Add support for `exclude` option to accept glob patterns.
@@ -5692,7 +5701,7 @@ changes:
56925701
56935702
* `pattern` {string|string\[]}
56945703
* `options` {Object}
5695-
* `cwd` {string} current working directory. **Default:** `process.cwd()`
5704+
* `cwd` {string|URL} current working directory. **Default:** `process.cwd()`
56965705
* `exclude` {Function|string\[]} Function to filter out files/directories or a
56975706
list of glob patterns to be excluded. If a function is provided, return
56985707
`true` to exclude the item, `false` to include it. **Default:** `undefined`.

lib/internal/fs/glob.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const {
3838
hideStackFrames,
3939
} = require('internal/errors');
4040
const assert = require('internal/assert');
41+
const { toPathIfFileURL } = require('internal/url');
4142

4243
let minimatch;
4344
function lazyMinimatch() {
@@ -268,7 +269,7 @@ class Glob {
268269
constructor(pattern, options = kEmptyObject) {
269270
validateObject(options, 'options');
270271
const { exclude, cwd, withFileTypes } = options;
271-
this.#root = cwd ?? '.';
272+
this.#root = toPathIfFileURL(cwd) ?? '.';
272273
this.#withFileTypes = !!withFileTypes;
273274
if (exclude != null) {
274275
validateStringArrayOrFunction(exclude, 'options.exclude');

test/parallel/test-fs-glob.mjs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { resolve, dirname, sep, relative, join, isAbsolute } from 'node:path';
44
import { mkdir, writeFile, symlink, glob as asyncGlob } from 'node:fs/promises';
55
import { glob, globSync, Dirent } from 'node:fs';
66
import { test, describe } from 'node:test';
7+
import { pathToFileURL } from 'node:url';
78
import { promisify } from 'node:util';
89
import assert from 'node:assert';
910

@@ -338,6 +339,39 @@ describe('fsPromises glob', function() {
338339
}
339340
});
340341

342+
describe('glob - with file: URL as cwd', function() {
343+
const promisified = promisify(glob);
344+
for (const [pattern, expected] of Object.entries(patterns)) {
345+
test(pattern, async () => {
346+
const actual = (await promisified(pattern, { cwd: pathToFileURL(fixtureDir) })).sort();
347+
const normalized = expected.filter(Boolean).map((item) => item.replaceAll('/', sep)).sort();
348+
assert.deepStrictEqual(actual, normalized);
349+
});
350+
}
351+
});
352+
353+
describe('globSync - with file: URL as cwd', function() {
354+
for (const [pattern, expected] of Object.entries(patterns)) {
355+
test(pattern, () => {
356+
const actual = globSync(pattern, { cwd: pathToFileURL(fixtureDir) }).sort();
357+
const normalized = expected.filter(Boolean).map((item) => item.replaceAll('/', sep)).sort();
358+
assert.deepStrictEqual(actual, normalized);
359+
});
360+
}
361+
});
362+
363+
describe('fsPromises.glob - with file: URL as cwd', function() {
364+
for (const [pattern, expected] of Object.entries(patterns)) {
365+
test(pattern, async () => {
366+
const actual = [];
367+
for await (const item of asyncGlob(pattern, { cwd: pathToFileURL(fixtureDir) })) actual.push(item);
368+
actual.sort();
369+
const normalized = expected.filter(Boolean).map((item) => item.replaceAll('/', sep)).sort();
370+
assert.deepStrictEqual(actual, normalized);
371+
});
372+
}
373+
});
374+
341375
const normalizeDirent = (dirent) => relative(fixtureDir, join(dirent.parentPath, dirent.name));
342376
// The call to `join()` with only one argument is important, as
343377
// it ensures that the proper path seperators are applied.

0 commit comments

Comments
 (0)