From 4b287926d26580480b735cd43bfd377d5e8b9f47 Mon Sep 17 00:00:00 2001 From: Frans Date: Sun, 13 Nov 2016 21:28:57 +0100 Subject: [PATCH] Fix: copy recursively from read only location. (fixes #98) --- ava-test/cp.js | 25 +++++++++++++++++++++++++ src/cp.js | 7 +++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ava-test/cp.js b/ava-test/cp.js index a7faec98..313313b1 100644 --- a/ava-test/cp.js +++ b/ava-test/cp.js @@ -647,3 +647,28 @@ test('Test with recursive option and symlinks.', t => { t.falsy(shell.test('-L', 'sym.lnk')); }); }); + + +// cp -R should be able to copy a readonly src (issue #98). +// On Windows, chmod acts VERY differently so skip these tests for now +test('cp -R should be able to copy a readonly src. issue #98; (Non window platforms only)', t => { + if (common.platform !== 'win') { + shell.cp('-r', 'resources/cp', t.context.tmp); + shell.chmod('555', `${t.context.tmp}/cp/`); + shell.chmod('555', `${t.context.tmp}/cp/dir_a`); + shell.chmod('555', `${t.context.tmp}/cp/dir_b`); + shell.chmod('555', `${t.context.tmp}/cp/a`); + + const result = shell.cp('-r', `${t.context.tmp}/cp`, `${t.context.tmp}/cp_cp`); + t.falsy(shell.error()); + t.falsy(result.stderr); + t.is(result.code, 0); + + t.is(shell.ls('-R', `${t.context.tmp}/cp`) + '', shell.ls('-R', `${t.context.tmp}/cp_cp`) + ''); + t.is(fs.statSync(`${t.context.tmp}/cp_cp`).mode & parseInt('777', 8), parseInt('555', 8)); + t.is(fs.statSync(`${t.context.tmp}/cp_cp/dir_a`).mode & parseInt('777', 8), parseInt('555', 8)); + t.is(fs.statSync(`${t.context.tmp}/cp_cp/a`).mode & parseInt('777', 8), parseInt('555', 8)); + + shell.chmod('-R', '755', t.context.tmp); + } +}); diff --git a/src/cp.js b/src/cp.js index 111e031c..7b7eef4f 100644 --- a/src/cp.js +++ b/src/cp.js @@ -94,8 +94,7 @@ function cpdirSyncRecursive(sourceDir, destDir, currentDepth, opts) { // Create the directory where all our junk is moving to; read the mode of the // source directory and mirror it try { - var checkDir = fs.statSync(sourceDir); - fs.mkdirSync(destDir, checkDir.mode); + fs.mkdirSync(destDir); } catch (e) { // if the directory already exists, that's okay if (e.code !== 'EEXIST') throw e; @@ -146,6 +145,10 @@ function cpdirSyncRecursive(sourceDir, destDir, currentDepth, opts) { } } } // for files + + // finally change the mode for the newly created directory. + var checkDir = fs.statSync(sourceDir); + fs.chmod(destDir, checkDir.mode); } // cpdirSyncRecursive function cpcheckcycle(sourceDir, srcFile) {