From af354012a69f12c01e325e5c9e37c4e83a706bf1 Mon Sep 17 00:00:00 2001 From: Ryan Zimmerman <17342435+RyanZim@users.noreply.github.com> Date: Fri, 16 Apr 2021 13:01:52 -0400 Subject: [PATCH] Ensure copy filter fn is not called more than needed (#883) Fixes #809 --- .../__tests__/copy-sync-file.test.js | 19 +++++++++++++++++++ lib/copy-sync/copy-sync.js | 2 +- lib/copy/__tests__/copy.test.js | 19 +++++++++++++++++++ lib/copy/copy.js | 4 ++-- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/lib/copy-sync/__tests__/copy-sync-file.test.js b/lib/copy-sync/__tests__/copy-sync-file.test.js index 6ffff60da..f656e04e9 100644 --- a/lib/copy-sync/__tests__/copy-sync-file.test.js +++ b/lib/copy-sync/__tests__/copy-sync-file.test.js @@ -104,6 +104,25 @@ describe('+ copySync() / file', () => { assert(fs.existsSync(destFile3)) }) + it('should not call filter fn more than needed', () => { + const src = path.join(TEST_DIR, 'foo') + + fs.writeFileSync(src, '') + + const dest = path.join(TEST_DIR, 'bar') + + let filterCallCount = 0 + const filter = () => { + filterCallCount++ + return true + } + + fs.copySync(src, dest, filter) + + assert.strictEqual(filterCallCount, 1) + assert(fs.existsSync(dest)) + }) + describe('> when the destination dir does not exist', () => { it('should create the destination directory and copy the file', () => { const src = path.join(TEST_DIR, 'file.txt') diff --git a/lib/copy-sync/copy-sync.js b/lib/copy-sync/copy-sync.js index 2d9523ecc..5e245b91d 100644 --- a/lib/copy-sync/copy-sync.js +++ b/lib/copy-sync/copy-sync.js @@ -30,7 +30,7 @@ function handleFilterAndCopy (destStat, src, dest, opts) { if (opts.filter && !opts.filter(src, dest)) return const destParent = path.dirname(dest) if (!fs.existsSync(destParent)) mkdirsSync(destParent) - return startCopy(destStat, src, dest, opts) + return getStats(destStat, src, dest, opts) } function startCopy (destStat, src, dest, opts) { diff --git a/lib/copy/__tests__/copy.test.js b/lib/copy/__tests__/copy.test.js index e7eed97f8..71470a27a 100644 --- a/lib/copy/__tests__/copy.test.js +++ b/lib/copy/__tests__/copy.test.js @@ -283,6 +283,25 @@ describe('fs-extra', () => { }) }) + it('should not call filter fn more than needed', done => { + const src = path.join(TEST_DIR, 'foo') + fs.writeFileSync(src, '') + const dest = path.join(TEST_DIR, 'bar') + + let filterCallCount = 0 + const filter = () => { + filterCallCount++ + return true + } + + fse.copy(src, dest, filter, err => { + assert(!err) + assert.strictEqual(filterCallCount, 1) + assert(fs.existsSync(dest)) + done() + }) + }) + it('accepts options object in place of filter', done => { const srcFile1 = path.join(TEST_DIR, '1.jade') fs.writeFileSync(srcFile1, '') diff --git a/lib/copy/copy.js b/lib/copy/copy.js index c12578db9..2a2874f3c 100644 --- a/lib/copy/copy.js +++ b/lib/copy/copy.js @@ -42,10 +42,10 @@ function checkParentDir (destStat, src, dest, opts, cb) { const destParent = path.dirname(dest) pathExists(destParent, (err, dirExists) => { if (err) return cb(err) - if (dirExists) return startCopy(destStat, src, dest, opts, cb) + if (dirExists) return getStats(destStat, src, dest, opts, cb) mkdirs(destParent, err => { if (err) return cb(err) - return startCopy(destStat, src, dest, opts, cb) + return getStats(destStat, src, dest, opts, cb) }) }) }