Skip to content

Commit

Permalink
Stop preserving ownership, stop performing chmod after copyFileSync (
Browse files Browse the repository at this point in the history
…#39)

Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
sindresorhus committed Mar 5, 2020
1 parent 1cda1f2 commit 4e536d5
Show file tree
Hide file tree
Showing 5 changed files with 3 additions and 94 deletions.
21 changes: 0 additions & 21 deletions fs.js
Expand Up @@ -9,7 +9,6 @@ const stat = promisify(fs.stat);
const lstat = promisify(fs.lstat);
const utimes = promisify(fs.utimes);
const chmod = promisify(fs.chmod);
const chown = promisify(fs.chown);

exports.closeSync = fs.closeSync.bind(fs);
exports.createWriteStream = fs.createWriteStream.bind(fs);
Expand Down Expand Up @@ -42,10 +41,6 @@ exports.chmod = (path, mode) => chmod(path, mode).catch(error => {
throw new CpFileError(`chmod \`${path}\` failed: ${error.message}`, error);
});

exports.chown = (path, uid, gid) => chown(path, uid, gid).catch(error => {
throw new CpFileError(`chown \`${path}\` failed: ${error.message}`, error);
});

exports.statSync = path => {
try {
return fs.statSync(path);
Expand All @@ -62,22 +57,6 @@ exports.utimesSync = (path, atime, mtime) => {
}
};

exports.chmodSync = (path, mode) => {
try {
return fs.chmodSync(path, mode);
} catch (error) {
throw new CpFileError(`chmod \`${path}\` failed: ${error.message}`, error);
}
};

exports.chownSync = (path, uid, gid) => {
try {
return fs.chownSync(path, uid, gid);
} catch (error) {
throw new CpFileError(`chown \`${path}\` failed: ${error.message}`, error);
}
};

exports.makeDir = path => makeDir(path, {fs}).catch(error => {
throw new CpFileError(`Cannot create directory \`${path}\`: ${error.message}`, error);
});
Expand Down
9 changes: 1 addition & 8 deletions index.js
Expand Up @@ -44,8 +44,7 @@ const cpFileAsync = async (source, destination, options, progressEmitter) => {

return Promise.all([
fs.utimes(destination, stats.atime, stats.mtime),
fs.chmod(destination, stats.mode),
fs.chown(destination, stats.uid, stats.gid)
fs.chmod(destination, stats.mode)
]);
}
};
Expand Down Expand Up @@ -83,11 +82,6 @@ const checkSourceIsFile = (stat, source) => {
}
};

const fixupAttributes = (destination, stat) => {
fs.chmodSync(destination, stat.mode);
fs.chownSync(destination, stat.uid, stat.gid);
};

module.exports.sync = (source, destination, options) => {
if (!source || !destination) {
throw new CpFileError('`source` and `destination` required');
Expand All @@ -114,5 +108,4 @@ module.exports.sync = (source, destination, options) => {
}

fs.utimesSync(destination, stat.atime, stat.mtime);
fixupAttributes(destination, stat);
};
1 change: 1 addition & 0 deletions readme.md
Expand Up @@ -8,6 +8,7 @@
- Resilient by using [graceful-fs](https://github.com/isaacs/node-graceful-fs).
- User-friendly by creating non-existent destination directories for you.
- Can be safe by turning off [overwriting](#optionsoverwrite).
- Preserves file mode, [but not ownership](https://github.com/sindresorhus/cp-file/issues/22#issuecomment-502079547).
- User-friendly errors.

## Install
Expand Down
24 changes: 0 additions & 24 deletions test/async.js
Expand Up @@ -113,14 +113,6 @@ test('preserve mode', async t => {
t.is(licenseStats.mode, tempStats.mode);
});

test('preserve ownership', async t => {
await cpFile('license', t.context.destination);
const licenseStats = fs.lstatSync('license');
const tempStats = fs.lstatSync(t.context.destination);
t.is(licenseStats.gid, tempStats.gid);
t.is(licenseStats.uid, tempStats.uid);
});

test('throw an Error if `source` does not exists', async t => {
const error = await t.throwsAsync(cpFile('NO_ENTRY', t.context.destination));
t.is(error.name, 'CpFileError', error.message);
Expand Down Expand Up @@ -226,22 +218,6 @@ test.serial('rethrow chmod errors', async t => {
fs.chmod.restore();
});

test.serial('rethrow chown errors', async t => {
const chownError = buildEPERM(t.context.destination, 'chown');

fs.chown = sinon.stub(fs, 'chown').throws(chownError);

clearModule('../fs');
const uncached = importFresh('..');
const error = await t.throwsAsync(uncached('license', t.context.destination));
t.is(error.name, 'CpFileError', error.message);
t.is(error.code, chownError.code, error.message);
t.is(error.path, chownError.path, error.message);
t.true(fs.chown.called);

fs.chown.restore();
});

test.serial('rethrow read after open errors', async t => {
const {createWriteStream, createReadStream} = fs;
let calledWriteEnd = 0;
Expand Down
42 changes: 1 addition & 41 deletions test/sync.js
Expand Up @@ -6,7 +6,7 @@ import test from 'ava';
import uuid from 'uuid';
import sinon from 'sinon';
import assertDateEqual from './helpers/_assert';
import {buildEACCES, buildENOSPC, buildEBADF, buildEPERM} from './helpers/_fs-errors';
import {buildEACCES, buildENOSPC, buildEBADF} from './helpers/_fs-errors';
import cpFile from '..';

const THREE_HUNDRED_KILO = (100 * 3 * 1024) + 1;
Expand Down Expand Up @@ -128,14 +128,6 @@ test('preserve mode', t => {
t.is(licenseStats.mode, tempStats.mode);
});

test('preserve ownership', t => {
cpFile.sync('license', t.context.destination);
const licenseStats = fs.lstatSync('license');
const tempStats = fs.lstatSync(t.context.destination);
t.is(licenseStats.gid, tempStats.gid);
t.is(licenseStats.uid, tempStats.uid);
});

test('throw an Error if `source` does not exists', t => {
const error = t.throws(() => {
cpFile.sync('NO_ENTRY', t.context.destination);
Expand Down Expand Up @@ -215,35 +207,3 @@ test('rethrow utimes errors', t => {

fs.utimesSync.restore();
});

test('rethrow chmod errors', t => {
const chmodError = buildEPERM(t.context.destination, 'chmod');

fs.chmodSync = sinon.stub(fs, 'chmodSync').throws(chmodError);

const error = t.throws(() => {
cpFile.sync('license', t.context.destination);
});
t.is(error.name, 'CpFileError', error.message);
t.is(error.errno, chmodError.errno, error.message);
t.is(error.code, chmodError.code, error.message);
t.true(fs.chmodSync.called);

fs.chmodSync.restore();
});

test('rethrow chown errors', t => {
const chownError = buildEPERM(t.context.destination, 'chown');

fs.chownSync = sinon.stub(fs, 'chownSync').throws(chownError);

const error = t.throws(() => {
cpFile.sync('license', t.context.destination);
});
t.is(error.name, 'CpFileError', error.message);
t.is(error.errno, chownError.errno, error.message);
t.is(error.code, chownError.code, error.message);
t.true(fs.chownSync.called);

fs.chownSync.restore();
});

0 comments on commit 4e536d5

Please sign in to comment.