diff --git a/lib/ensure/__tests__/link.test.js b/lib/ensure/__tests__/link.test.js index b78313e5..7c38f4de 100644 --- a/lib/ensure/__tests__/link.test.js +++ b/lib/ensure/__tests__/link.test.js @@ -34,7 +34,7 @@ describe('fse-ensure-link', () => { [['../foo.txt', './link.txt'], 'file-error', 'file-error'], [['../dir-foo/foo.txt', './link.txt'], 'file-error', 'file-error'], // error is thrown if destination path exists - [['./foo.txt', './dir-foo/foo.txt'], 'file-error', 'file-dest-exists'], + [['./foo.txt', './dir-foo/foo.txt'], 'file-error', 'file-error'], [[path.resolve(path.join(TEST_DIR, './foo.txt')), './link.txt'], 'file-success', 'file-success'], [[path.resolve(path.join(TEST_DIR, './dir-foo/foo.txt')), './link.txt'], 'file-success', 'file-success'], [[path.resolve(path.join(TEST_DIR, './missing.txt')), './link.txt'], 'file-error', 'file-error'], @@ -107,23 +107,6 @@ describe('fse-ensure-link', () => { }) } - function fileDestExists (args, fn) { - const srcpath = args[0] - const dstpath = args[1] - - it(`should do nothing using src ${srcpath} and dst ${dstpath}`, done => { - const destinationContentBefore = fs.readFileSync(dstpath, 'utf8') - const callback = err => { - if (err) return done(err) - const destinationContentAfter = fs.readFileSync(dstpath, 'utf8') - assert.strictEqual(destinationContentBefore, destinationContentAfter) - return done() - } - args.push(callback) - return fn(...args) - }) - } - function fileSuccessSync (args, fn) { const srcpath = args[0] const dstpath = args[1] @@ -161,18 +144,6 @@ describe('fse-ensure-link', () => { }) } - function fileDestExistsSync (args, fn) { - const srcpath = args[0] - const dstpath = args[1] - - it(`should do nothing using src ${srcpath} and dst ${dstpath}`, () => { - const destinationContentBefore = fs.readFileSync(dstpath, 'utf8') - fn(...args) - const destinationContentAfter = fs.readFileSync(dstpath, 'utf8') - assert.strictEqual(destinationContentBefore, destinationContentAfter) - }) - } - describe('fs.link()', () => { const fn = fs.link tests.forEach(test => { @@ -181,7 +152,6 @@ describe('fse-ensure-link', () => { // const newBehavior = test[2] if (nativeBehavior === 'file-success') fileSuccess(args, fn) if (nativeBehavior === 'file-error') fileError(args, fn) - if (nativeBehavior === 'file-dest-exists') fileDestExists(args, fn) }) }) @@ -193,7 +163,6 @@ describe('fse-ensure-link', () => { const newBehavior = test[2] if (newBehavior === 'file-success') fileSuccess(args, fn) if (newBehavior === 'file-error') fileError(args, fn) - if (newBehavior === 'file-dest-exists') fileDestExists(args, fn) }) }) @@ -229,7 +198,6 @@ describe('fse-ensure-link', () => { // const newBehavior = test[2] if (nativeBehavior === 'file-success') fileSuccessSync(args, fn) if (nativeBehavior === 'file-error') fileErrorSync(args, fn) - if (nativeBehavior === 'file-dest-exists') fileDestExists(args, fn) }) }) @@ -241,7 +209,6 @@ describe('fse-ensure-link', () => { const newBehavior = test[2] if (newBehavior === 'file-success') fileSuccessSync(args, fn) if (newBehavior === 'file-error') fileErrorSync(args, fn) - if (newBehavior === 'file-dest-exists') fileDestExistsSync(args, fn) }) }) }) diff --git a/lib/ensure/__tests__/symlink.test.js b/lib/ensure/__tests__/symlink.test.js index 22a00430..1657f32f 100644 --- a/lib/ensure/__tests__/symlink.test.js +++ b/lib/ensure/__tests__/symlink.test.js @@ -35,7 +35,7 @@ describe('fse-ensure-symlink', () => { [['./missing.txt', './symlink.txt'], 'file-broken', 'file-error'], [['./missing.txt', './missing-dir/symlink.txt'], 'file-error', 'file-error'], // error is thrown if destination path exists - [['./foo.txt', './dir-foo/foo.txt'], 'file-error', 'file-dest-exists'], + [['./foo.txt', './dir-foo/foo.txt'], 'file-error', 'file-error'], [['./dir-foo', './symlink-dir-foo'], 'dir-success', 'dir-success'], [['../dir-bar', './dir-foo/symlink-dir-bar'], 'dir-success', 'dir-success'], [['./dir-bar', './dir-foo/symlink-dir-bar'], 'dir-broken', 'dir-success'], @@ -48,7 +48,7 @@ describe('fse-ensure-symlink', () => { [['./dir-foo', './alpha/beta/gamma/dir-foo'], 'dir-error', 'dir-success'], [['./missing', './dir-foo/symlink-dir-missing'], 'dir-broken', 'dir-error'], // error is thrown if destination path exists - [['./dir-foo', './real-alpha/real-beta'], 'dir-error', 'dir-dest-exists'], + [['./dir-foo', './real-alpha/real-beta'], 'dir-error', 'dir-error'], [[path.resolve(path.join(TEST_DIR, './foo.txt')), './symlink.txt'], 'file-success', 'file-success'], [[path.resolve(path.join(TEST_DIR, './dir-foo/foo.txt')), './symlink.txt'], 'file-success', 'file-success'], [[path.resolve(path.join(TEST_DIR, './missing.txt')), './symlink.txt'], 'file-broken', 'file-error'], @@ -138,22 +138,6 @@ describe('fse-ensure-symlink', () => { }) } - function fileDestExists (args, fn) { - const srcpath = args[0] - const dstpath = args[1] - it(`should do nothing using src ${srcpath} and dst ${dstpath}`, done => { - const destinationContentBefore = fs.readFileSync(dstpath, 'utf8') - const callback = err => { - if (err) return done(err) - const destinationContentAfter = fs.readFileSync(dstpath, 'utf8') - assert.strictEqual(destinationContentBefore, destinationContentAfter) - return done() - } - args.push(callback) - return fn(...args) - }) - } - function dirSuccess (args, fn) { const srcpath = args[0] const dstpath = args[1] @@ -214,22 +198,6 @@ describe('fse-ensure-symlink', () => { }) } - function dirDestExists (args, fn) { - const srcpath = args[0] - const dstpath = args[1] - it(`should do nothing using src ${srcpath} and dst ${dstpath}`, done => { - const destinationContentBefore = fs.readdirSync(dstpath) - const callback = err => { - if (err) return done(err) - const destinationContentAfter = fs.readdirSync(dstpath) - assert.deepStrictEqual(destinationContentBefore, destinationContentAfter) - return done() - } - args.push(callback) - return fn(...args) - }) - } - function fileSuccessSync (args, fn) { const srcpath = args[0] const dstpath = args[1] @@ -280,17 +248,6 @@ describe('fse-ensure-symlink', () => { }) } - function fileDestExistsSync (args, fn) { - const srcpath = args[0] - const dstpath = args[1] - it(`should do nothing using src ${srcpath} and dst ${dstpath}`, () => { - const destinationContentBefore = fs.readFileSync(dstpath, 'utf8') - fn(...args) - const destinationContentAfter = fs.readFileSync(dstpath, 'utf8') - assert.strictEqual(destinationContentBefore, destinationContentAfter) - }) - } - function dirSuccessSync (args, fn) { const srcpath = args[0] const dstpath = args[1] @@ -341,17 +298,6 @@ describe('fse-ensure-symlink', () => { }) } - function dirDestExistsSync (args, fn) { - const srcpath = args[0] - const dstpath = args[1] - it(`should do nothing using src ${srcpath} and dst ${dstpath}`, () => { - const destinationContentBefore = fs.readdirSync(dstpath) - fn(...args) - const destinationContentAfter = fs.readdirSync(dstpath) - assert.deepStrictEqual(destinationContentBefore, destinationContentAfter) - }) - } - describe('fs.symlink()', () => { const fn = fs.symlink tests.forEach(test => { @@ -361,12 +307,10 @@ describe('fse-ensure-symlink', () => { if (nativeBehavior === 'file-success') fileSuccess(args, fn) if (nativeBehavior === 'file-broken') fileBroken(args, fn) if (nativeBehavior === 'file-error') fileError(args, fn) - if (nativeBehavior === 'file-dest-exists') fileDestExists(args, fn) args.push('dir') if (nativeBehavior === 'dir-success') dirSuccess(args, fn) if (nativeBehavior === 'dir-broken') dirBroken(args, fn) if (nativeBehavior === 'dir-error') dirError(args, fn) - if (nativeBehavior === 'dir-dest-exists') dirDestExists(args, fn) }) }) @@ -379,11 +323,9 @@ describe('fse-ensure-symlink', () => { if (newBehavior === 'file-success') fileSuccess(args, fn) if (newBehavior === 'file-broken') fileBroken(args, fn) if (newBehavior === 'file-error') fileError(args, fn) - if (newBehavior === 'file-dest-exists') fileDestExists(args, fn) if (newBehavior === 'dir-success') dirSuccess(args, fn) if (newBehavior === 'dir-broken') dirBroken(args, fn) if (newBehavior === 'dir-error') dirError(args, fn) - if (newBehavior === 'dir-dest-exists') dirDestExists(args, fn) }) }) @@ -419,12 +361,10 @@ describe('fse-ensure-symlink', () => { if (nativeBehavior === 'file-success') fileSuccessSync(args, fn) if (nativeBehavior === 'file-broken') fileBrokenSync(args, fn) if (nativeBehavior === 'file-error') fileErrorSync(args, fn) - if (nativeBehavior === 'file-dest-exists') fileDestExistsSync(args, fn) args.push('dir') if (nativeBehavior === 'dir-success') dirSuccessSync(args, fn) if (nativeBehavior === 'dir-broken') dirBrokenSync(args, fn) if (nativeBehavior === 'dir-error') dirErrorSync(args, fn) - if (nativeBehavior === 'dir-dest-exists') dirDestExistsSync(args, fn) }) }) @@ -437,11 +377,9 @@ describe('fse-ensure-symlink', () => { if (newBehavior === 'file-success') fileSuccessSync(args, fn) if (newBehavior === 'file-broken') fileBrokenSync(args, fn) if (newBehavior === 'file-error') fileErrorSync(args, fn) - if (newBehavior === 'file-dest-exists') fileDestExistsSync(args, fn) if (newBehavior === 'dir-success') dirSuccessSync(args, fn) if (newBehavior === 'dir-broken') dirBrokenSync(args, fn) if (newBehavior === 'dir-error') dirErrorSync(args, fn) - if (newBehavior === 'dir-dest-exists') dirDestExistsSync(args, fn) }) }) }) diff --git a/lib/ensure/link.js b/lib/ensure/link.js index 2cd41962..00975971 100644 --- a/lib/ensure/link.js +++ b/lib/ensure/link.js @@ -14,9 +14,9 @@ function createLink (srcpath, dstpath, callback) { }) } - pathExists(dstpath, (err, destinationExists) => { - if (err) return callback(err) - if (destinationExists) return callback(null) + fs.lstat(dstpath, (err, stats) => { + if (!err && stats.isSymbolicLink()) return callback(null) + fs.lstat(srcpath, (err) => { if (err) { err.message = err.message.replace('lstat', 'ensureLink') @@ -37,8 +37,11 @@ function createLink (srcpath, dstpath, callback) { } function createLinkSync (srcpath, dstpath) { - const destinationExists = fs.existsSync(dstpath) - if (destinationExists) return undefined + let stats + try { + stats = fs.lstatSync(dstpath) + } catch {} + if (stats && stats.isSymbolicLink()) return try { fs.lstatSync(srcpath) diff --git a/lib/ensure/symlink.js b/lib/ensure/symlink.js index fe68b799..ec37ce12 100644 --- a/lib/ensure/symlink.js +++ b/lib/ensure/symlink.js @@ -21,9 +21,8 @@ function createSymlink (srcpath, dstpath, type, callback) { callback = (typeof type === 'function') ? type : callback type = (typeof type === 'function') ? false : type - pathExists(dstpath, (err, destinationExists) => { - if (err) return callback(err) - if (destinationExists) return callback(null) + fs.lstat(dstpath, (err, stats) => { + if (!err && stats.isSymbolicLink()) return callback(null) symlinkPaths(srcpath, dstpath, (err, relative) => { if (err) return callback(err) srcpath = relative.toDst @@ -44,8 +43,11 @@ function createSymlink (srcpath, dstpath, type, callback) { } function createSymlinkSync (srcpath, dstpath, type) { - const destinationExists = fs.existsSync(dstpath) - if (destinationExists) return undefined + let stats + try { + stats = fs.lstatSync(dstpath) + } catch {} + if (stats && stats.isSymbolicLink()) return const relative = symlinkPathsSync(srcpath, dstpath) srcpath = relative.toDst