fs: add support for URL for fs.glob's cwd option

PR-URL: https://github.com/nodejs/node/pull/58182
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jason Zhang <xzha4350@gmail.com>
This commit is contained in:
Antoine du Hamel 2025-05-11 19:29:45 +02:00
parent 4cc4195493
commit 5c36510dec
No known key found for this signature in database
GPG Key ID: 21D900FFDB233756
3 changed files with 48 additions and 4 deletions

View File

@ -1078,6 +1078,9 @@ changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/57513
description: Marking the API stable.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58182
description: Add support for `URL` instances for `cwd` option.
- version: v22.14.0
pr-url: https://github.com/nodejs/node/pull/56489
description: Add support for `exclude` option to accept glob patterns.
@ -1088,7 +1091,7 @@ changes:
* `pattern` {string|string\[]}
* `options` {Object}
* `cwd` {string} current working directory. **Default:** `process.cwd()`
* `cwd` {string|URL} current working directory. **Default:** `process.cwd()`
* `exclude` {Function|string\[]} Function to filter out files/directories or a
list of glob patterns to be excluded. If a function is provided, return
`true` to exclude the item, `false` to include it. **Default:** `undefined`.
@ -3131,6 +3134,9 @@ changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/57513
description: Marking the API stable.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58182
description: Add support for `URL` instances for `cwd` option.
- version: v22.14.0
pr-url: https://github.com/nodejs/node/pull/56489
description: Add support for `exclude` option to accept glob patterns.
@ -3142,7 +3148,7 @@ changes:
* `pattern` {string|string\[]}
* `options` {Object}
* `cwd` {string} current working directory. **Default:** `process.cwd()`
* `cwd` {string|URL} current working directory. **Default:** `process.cwd()`
* `exclude` {Function|string\[]} Function to filter out files/directories or a
list of glob patterns to be excluded. If a function is provided, return
`true` to exclude the item, `false` to include it. **Default:** `undefined`.
@ -5682,6 +5688,9 @@ changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/57513
description: Marking the API stable.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58182
description: Add support for `URL` instances for `cwd` option.
- version: v22.14.0
pr-url: https://github.com/nodejs/node/pull/56489
description: Add support for `exclude` option to accept glob patterns.
@ -5692,7 +5701,7 @@ changes:
* `pattern` {string|string\[]}
* `options` {Object}
* `cwd` {string} current working directory. **Default:** `process.cwd()`
* `cwd` {string|URL} current working directory. **Default:** `process.cwd()`
* `exclude` {Function|string\[]} Function to filter out files/directories or a
list of glob patterns to be excluded. If a function is provided, return
`true` to exclude the item, `false` to include it. **Default:** `undefined`.

View File

@ -38,6 +38,7 @@ const {
hideStackFrames,
} = require('internal/errors');
const assert = require('internal/assert');
const { toPathIfFileURL } = require('internal/url');
let minimatch;
function lazyMinimatch() {
@ -268,7 +269,7 @@ class Glob {
constructor(pattern, options = kEmptyObject) {
validateObject(options, 'options');
const { exclude, cwd, withFileTypes } = options;
this.#root = cwd ?? '.';
this.#root = toPathIfFileURL(cwd) ?? '.';
this.#withFileTypes = !!withFileTypes;
if (exclude != null) {
validateStringArrayOrFunction(exclude, 'options.exclude');

View File

@ -4,6 +4,7 @@ import { resolve, dirname, sep, relative, join, isAbsolute } from 'node:path';
import { mkdir, writeFile, symlink, glob as asyncGlob } from 'node:fs/promises';
import { glob, globSync, Dirent } from 'node:fs';
import { test, describe } from 'node:test';
import { pathToFileURL } from 'node:url';
import { promisify } from 'node:util';
import assert from 'node:assert';
@ -338,6 +339,39 @@ describe('fsPromises glob', function() {
}
});
describe('glob - with file: URL as cwd', function() {
const promisified = promisify(glob);
for (const [pattern, expected] of Object.entries(patterns)) {
test(pattern, async () => {
const actual = (await promisified(pattern, { cwd: pathToFileURL(fixtureDir) })).sort();
const normalized = expected.filter(Boolean).map((item) => item.replaceAll('/', sep)).sort();
assert.deepStrictEqual(actual, normalized);
});
}
});
describe('globSync - with file: URL as cwd', function() {
for (const [pattern, expected] of Object.entries(patterns)) {
test(pattern, () => {
const actual = globSync(pattern, { cwd: pathToFileURL(fixtureDir) }).sort();
const normalized = expected.filter(Boolean).map((item) => item.replaceAll('/', sep)).sort();
assert.deepStrictEqual(actual, normalized);
});
}
});
describe('fsPromises.glob - with file: URL as cwd', function() {
for (const [pattern, expected] of Object.entries(patterns)) {
test(pattern, async () => {
const actual = [];
for await (const item of asyncGlob(pattern, { cwd: pathToFileURL(fixtureDir) })) actual.push(item);
actual.sort();
const normalized = expected.filter(Boolean).map((item) => item.replaceAll('/', sep)).sort();
assert.deepStrictEqual(actual, normalized);
});
}
});
const normalizeDirent = (dirent) => relative(fixtureDir, join(dirent.parentPath, dirent.name));
// The call to `join()` with only one argument is important, as
// it ensures that the proper path seperators are applied.