diff --git a/docs/copy.md b/docs/copy.md index df834486..f7909d0f 100644 --- a/docs/copy.md +++ b/docs/copy.md @@ -9,7 +9,7 @@ Copy a file or directory. The directory can have contents. Like `cp -r`. - `errorOnExist` ``: when `overwrite` is `false` and the destination exists, throw an error. Default is `false`. - `dereference` ``: dereference symlinks, default is `false`. - `preserveTimestamps` ``: will set last modification and access times to the ones of the original source files, default is `false`. - - `filter` ``: Function to filter copied files. Return `true` to include, `false` to exclude. + - `filter` ``: Function to filter copied files. Return `true` to include, `false` to exclude. Can also return a `Promise` that resolves to `true` or `false` (or pass in an `async` function). - `callback` `` ## Example: diff --git a/lib/copy/__tests__/copy.test.js b/lib/copy/__tests__/copy.test.js index d8e38f63..98692b40 100644 --- a/lib/copy/__tests__/copy.test.js +++ b/lib/copy/__tests__/copy.test.js @@ -249,6 +249,19 @@ describe('fs-extra', () => { }) }) + it('allows filter fn to return a promise', done => { + const srcFile1 = path.join(TEST_DIR, '1.css') + fs.writeFileSync(srcFile1, '') + const destFile1 = path.join(TEST_DIR, 'dest1.css') + const filter = s => Promise.resolve(s.split('.').pop() !== 'css') + + fse.copy(srcFile1, destFile1, filter, err => { + assert(!err) + assert(!fs.existsSync(destFile1)) + done() + }) + }) + it('should apply filter recursively', done => { const FILES = 2 // Don't match anything that ends with a digit higher than 0: diff --git a/lib/copy/copy.js b/lib/copy/copy.js index f270c1d7..421436a5 100644 --- a/lib/copy/copy.js +++ b/lib/copy/copy.js @@ -13,7 +13,7 @@ function copy (src, dest, opts, cb) { if (typeof opts === 'function' && !cb) { cb = opts opts = {} - } else if (typeof opts === 'function' || opts instanceof RegExp) { + } else if (typeof opts === 'function') { opts = {filter: opts} } @@ -49,8 +49,13 @@ function copy (src, dest, opts, cb) { } function startCopy (src, dest, opts, cb) { - if (opts.filter && !opts.filter(src, dest)) return cb() - return getStats(src, dest, opts, cb) + if (opts.filter) { + Promise.resolve(opts.filter(src, dest)) + .then(include => { + if (include) getStats(src, dest, opts, cb) + else cb() + }, error => cb(error)) + } else getStats(src, dest, opts, cb) } function getStats (src, dest, opts, cb) {