[build-utils] Add includeDirectories option to glob() (#9245)

Instead of always including empty directories in `glob()`, make it an
opt-in behavior because technically it's a breaking change to include
them by default.
This commit is contained in:
Nathan Rajlich
2023-01-17 16:21:40 -08:00
committed by GitHub
parent 6d97e1673e
commit 22d3ee160b
2 changed files with 43 additions and 12 deletions

View File

@@ -6,7 +6,9 @@ import { lstat, Stats } from 'fs-extra';
import { normalizePath } from './normalize-path'; import { normalizePath } from './normalize-path';
import FileFsRef from '../file-fs-ref'; import FileFsRef from '../file-fs-ref';
export type GlobOptions = vanillaGlob_.IOptions; export interface GlobOptions extends vanillaGlob_.IOptions {
includeDirectories?: boolean;
}
const vanillaGlob = promisify(vanillaGlob_); const vanillaGlob = promisify(vanillaGlob_);
@@ -73,6 +75,7 @@ export default async function glob(
} }
// Add empty directory entries // Add empty directory entries
if (options.includeDirectories) {
for (const relativePath of dirs) { for (const relativePath of dirs) {
if (dirsWithEntries.has(relativePath)) continue; if (dirsWithEntries.has(relativePath)) continue;
@@ -86,6 +89,7 @@ export default async function glob(
results[finalPath] = new FileFsRef({ mode: stat.mode, fsPath }); results[finalPath] = new FileFsRef({ mode: stat.mode, fsPath });
} }
}
return results; return results;
} }

View File

@@ -4,7 +4,7 @@ import { tmpdir } from 'os';
import { glob, isDirectory } from '../src'; import { glob, isDirectory } from '../src';
describe('glob()', () => { describe('glob()', () => {
it('should return entries for empty directories', async () => { it('should not return entries for empty directories by default', async () => {
const dir = await fs.mkdtemp(join(tmpdir(), 'build-utils-test')); const dir = await fs.mkdtemp(join(tmpdir(), 'build-utils-test'));
try { try {
await Promise.all([ await Promise.all([
@@ -19,6 +19,33 @@ describe('glob()', () => {
]); ]);
const files = await glob('**', dir); const files = await glob('**', dir);
const fileNames = Object.keys(files).sort(); const fileNames = Object.keys(files).sort();
expect(fileNames).toHaveLength(2);
expect(fileNames).toEqual(['dir-with-file/data.json', 'root.txt']);
expect(isDirectory(files['dir-with-file/data.json'].mode)).toEqual(false);
expect(isDirectory(files['root.txt'].mode)).toEqual(false);
expect(files['dir-with-file']).toBeUndefined();
expect(files['another/subdir']).toBeUndefined();
expect(files['empty-dir']).toBeUndefined();
} finally {
await fs.remove(dir);
}
});
it('should return entries for empty directories with `includeDirectories: true`', async () => {
const dir = await fs.mkdtemp(join(tmpdir(), 'build-utils-test'));
try {
await Promise.all([
fs.writeFile(join(dir, 'root.txt'), 'file at the root'),
fs.mkdirp(join(dir, 'empty-dir')),
fs
.mkdirp(join(dir, 'dir-with-file'))
.then(() =>
fs.writeFile(join(dir, 'dir-with-file/data.json'), '{"a":"b"}')
),
fs.mkdirp(join(dir, 'another/subdir')),
]);
const files = await glob('**', { cwd: dir, includeDirectories: true });
const fileNames = Object.keys(files).sort();
expect(fileNames).toHaveLength(4); expect(fileNames).toHaveLength(4);
expect(fileNames).toEqual([ expect(fileNames).toEqual([
'another/subdir', 'another/subdir',