diff --git a/lib/ensure/__tests__/symlink.test.js b/lib/ensure/__tests__/symlink.test.js index 92222738..72ca417c 100644 --- a/lib/ensure/__tests__/symlink.test.js +++ b/lib/ensure/__tests__/symlink.test.js @@ -472,4 +472,40 @@ describe('fse-ensure-symlink', () => { assert.throws(() => createSymlinkSync(srcpath, dstpath), { code: 'EACCES' }) }) }) + + describe('ensureSymlinkSync() when src is a broken symlink', () => { + it('should create the symlink like ensureSymlink() does', async () => { + const brokenpath = path.join(TEST_DIR, 'broken-src') + fs.symlinkSync(path.join(TEST_DIR, 'missing-target'), brokenpath) + + await ensureSymlink(brokenpath, path.join(TEST_DIR, 'link-async')) + ensureSymlinkSync(brokenpath, path.join(TEST_DIR, 'link-sync')) + + assert.strictEqual(fs.readlinkSync(path.join(TEST_DIR, 'link-async')), brokenpath) + assert.strictEqual(fs.readlinkSync(path.join(TEST_DIR, 'link-sync')), brokenpath) + }) + + it('should create the symlink like ensureSymlink() does with a relative src', async () => { + // `broken-rel-src` does not exist relative to `dir-foo`, so it is resolved from the cwd + fs.symlinkSync('missing-target', 'broken-rel-src') + + await ensureSymlink('broken-rel-src', 'dir-foo/link-rel-async') + ensureSymlinkSync('broken-rel-src', 'dir-foo/link-rel-sync') + + assert.strictEqual(fs.readlinkSync('dir-foo/link-rel-async'), path.join('..', 'broken-rel-src')) + assert.strictEqual(fs.readlinkSync('dir-foo/link-rel-sync'), path.join('..', 'broken-rel-src')) + }) + }) + + describe('ensureSymlinkSync() when src does not exist', () => { + it('should throw ENOENT like ensureSymlink() does', async () => { + const srcpath = path.join(TEST_DIR, 'missing-src') + const relpath = 'missing-rel-src' + + await assert.rejects(ensureSymlink(srcpath, path.join(TEST_DIR, 'link-abs')), { code: 'ENOENT' }) + assert.throws(() => ensureSymlinkSync(srcpath, path.join(TEST_DIR, 'link-abs-sync')), { code: 'ENOENT' }) + await assert.rejects(ensureSymlink(relpath, path.join(TEST_DIR, 'link-rel')), { code: 'ENOENT' }) + assert.throws(() => ensureSymlinkSync(relpath, path.join(TEST_DIR, 'link-rel-sync')), { code: 'ENOENT' }) + }) + }) }) diff --git a/lib/ensure/symlink-paths.js b/lib/ensure/symlink-paths.js index 85dda475..3f7765ce 100644 --- a/lib/ensure/symlink-paths.js +++ b/lib/ensure/symlink-paths.js @@ -69,8 +69,12 @@ async function symlinkPaths (srcpath, dstpath) { function symlinkPathsSync (srcpath, dstpath) { if (path.isAbsolute(srcpath)) { - const exists = fs.existsSync(srcpath) - if (!exists) throw new Error('absolute srcpath does not exist') + try { + fs.lstatSync(srcpath) + } catch (err) { + err.message = err.message.replace('lstat', 'ensureSymlink') + throw err + } return { toCwd: srcpath, toDst: srcpath @@ -87,8 +91,12 @@ function symlinkPathsSync (srcpath, dstpath) { } } - const srcExists = fs.existsSync(srcpath) - if (!srcExists) throw new Error('relative srcpath does not exist') + try { + fs.lstatSync(srcpath) + } catch (err) { + err.message = err.message.replace('lstat', 'ensureSymlink') + throw err + } return { toCwd: srcpath, toDst: path.relative(dstdir, srcpath)