From 08f898114accd24f70714a6a5b253cc93f91e509 Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Tue, 11 Jul 2023 17:34:17 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20don=E2=80=99t=20try=20to=20chmod=20unlin?= =?UTF-8?q?ked=20files=20(#80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `linkGently` would return true if a link target had been visited before. `linkBin` would then chmod the link `to`, regardless of whether this file exists. This causes `npm install` to fail if multiple packages link to a non-existent bin with the same name. By returning false in `linkGently`, `linkBin` no skips the chmod on the non-existent file. ## References Fixes npm/cli#4597 --- lib/link-gently.js | 2 +- test/link-gently.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/link-gently.js b/lib/link-gently.js index 89ca0f6..d1e955e 100644 --- a/lib/link-gently.js +++ b/lib/link-gently.js @@ -28,7 +28,7 @@ const CLOBBER = Symbol('clobber - ours or in forceful mode') const linkGently = async ({ path, to, from, absFrom, force }) => { if (seen.has(to)) { - return true + return false } seen.add(to) diff --git a/test/link-gently.js b/test/link-gently.js index 32dc774..1048578 100644 --- a/test/link-gently.js +++ b/test/link-gently.js @@ -109,7 +109,7 @@ t.test('racey race', async t => { existingLink: t.fixture('symlink', './pkg/hello.js'), existingFile: 'hello', }) - await Promise.all([ + const multipleLinked = await Promise.all([ mockedLinkGently({ path: `${dir}/pkg`, from: `./pkg/hello.js`, @@ -126,6 +126,8 @@ t.test('racey race', async t => { }), new Promise((res) => fs.symlink(__filename, `${dir}/racecar`, 'file', res)), ]) + t.ok(multipleLinked[0] || multipleLinked[1], 'should link one path succesfully') + t.notSame(multipleLinked[0], multipleLinked[1], 'should fail to link the other path') const target = fs.readlinkSync(`${dir}/racecar`) t.match(target, /^\.\/(other)?pkg\/hello\.js$/, 'should link to one of them') })