diff --git a/packages/build-utils/src/fs/glob.ts b/packages/build-utils/src/fs/glob.ts index f9b5dc840..1ac87b138 100644 --- a/packages/build-utils/src/fs/glob.ts +++ b/packages/build-utils/src/fs/glob.ts @@ -6,7 +6,9 @@ import { lstat, Stats } from 'fs-extra'; import { normalizePath } from './normalize-path'; import FileFsRef from '../file-fs-ref'; -export type GlobOptions = vanillaGlob_.IOptions; +export interface GlobOptions extends vanillaGlob_.IOptions { + includeDirectories?: boolean; +} const vanillaGlob = promisify(vanillaGlob_); @@ -73,18 +75,20 @@ export default async function glob( } // Add empty directory entries - for (const relativePath of dirs) { - if (dirsWithEntries.has(relativePath)) continue; + if (options.includeDirectories) { + for (const relativePath of dirs) { + if (dirsWithEntries.has(relativePath)) continue; - let finalPath = relativePath; - if (mountpoint) { - finalPath = path.join(mountpoint, finalPath); + let finalPath = relativePath; + if (mountpoint) { + finalPath = path.join(mountpoint, finalPath); + } + + const fsPath = normalizePath(path.join(options.cwd, relativePath)); + const stat = statCache[fsPath]; + + results[finalPath] = new FileFsRef({ mode: stat.mode, fsPath }); } - - const fsPath = normalizePath(path.join(options.cwd, relativePath)); - const stat = statCache[fsPath]; - - results[finalPath] = new FileFsRef({ mode: stat.mode, fsPath }); } return results; diff --git a/packages/build-utils/test/unit.glob.test.ts b/packages/build-utils/test/unit.glob.test.ts index aeadcb459..4e002d53d 100644 --- a/packages/build-utils/test/unit.glob.test.ts +++ b/packages/build-utils/test/unit.glob.test.ts @@ -4,7 +4,7 @@ import { tmpdir } from 'os'; import { glob, isDirectory } from '../src'; 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')); try { await Promise.all([ @@ -19,6 +19,33 @@ describe('glob()', () => { ]); const files = await glob('**', dir); 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).toEqual([ 'another/subdir',