mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-23 23:29:17 -05:00
fix: handle EISDIR error when bin field points to directory (#10080)
close #9441
This commit is contained in:
6
.changeset/gold-colts-brush.md
Normal file
6
.changeset/gold-colts-brush.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@pnpm/link-bins": patch
|
||||||
|
"pnpm": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fixed EISDIR error when bin field points to a directory [#9441](https://github.com/pnpm/pnpm/issues/9441).
|
||||||
@@ -57,6 +57,7 @@
|
|||||||
"ebusy",
|
"ebusy",
|
||||||
"ehrkoext",
|
"ehrkoext",
|
||||||
"eintegrity",
|
"eintegrity",
|
||||||
|
"eisdir",
|
||||||
"elifecycle",
|
"elifecycle",
|
||||||
"elit",
|
"elit",
|
||||||
"emfile",
|
"emfile",
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ async function linkBin (cmd: CommandInfo, binsDir: string, opts?: LinkBinOptions
|
|||||||
await symlinkDir(cmd.path, externalBinPath)
|
await symlinkDir(cmd.path, externalBinPath)
|
||||||
await fixBin(cmd.path, 0o755)
|
await fixBin(cmd.path, 0o755)
|
||||||
} catch (err: any) { // eslint-disable-line
|
} catch (err: any) { // eslint-disable-line
|
||||||
if (err.code !== 'ENOENT') {
|
if (err.code !== 'ENOENT' && err.code !== 'EISDIR') {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
globalWarn(`Failed to create bin at ${externalBinPath}. ${err.message as string}`)
|
globalWarn(`Failed to create bin at ${externalBinPath}. ${err.message as string}`)
|
||||||
@@ -308,7 +308,7 @@ async function linkBin (cmd: CommandInfo, binsDir: string, opts?: LinkBinOptions
|
|||||||
nodeExecPath: cmd.nodeExecPath,
|
nodeExecPath: cmd.nodeExecPath,
|
||||||
})
|
})
|
||||||
} catch (err: any) { // eslint-disable-line
|
} catch (err: any) { // eslint-disable-line
|
||||||
if (err.code !== 'ENOENT') {
|
if (err.code !== 'ENOENT' && err.code !== 'EISDIR') {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
globalWarn(`Failed to create bin at ${externalBinPath}. ${err.message as string}`)
|
globalWarn(`Failed to create bin at ${externalBinPath}. ${err.message as string}`)
|
||||||
|
|||||||
2
pkg-manager/link-bins/test/fixtures/bin-is-directory/.gitignore
vendored
Normal file
2
pkg-manager/link-bins/test/fixtures/bin-is-directory/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
!**/node_modules/**/*
|
||||||
|
!/node_modules/
|
||||||
1
pkg-manager/link-bins/test/fixtures/bin-is-directory/node_modules/invalid-bin/dist/readme.txt
generated
vendored
Normal file
1
pkg-manager/link-bins/test/fixtures/bin-is-directory/node_modules/invalid-bin/dist/readme.txt
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
This is a directory, not a file.
|
||||||
5
pkg-manager/link-bins/test/fixtures/bin-is-directory/node_modules/invalid-bin/package.json
generated
vendored
Normal file
5
pkg-manager/link-bins/test/fixtures/bin-is-directory/node_modules/invalid-bin/package.json
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "invalid-bin",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"bin": "./dist"
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ const f = fixtures(__dirname)
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.mocked(binsConflictLogger.debug).mockClear()
|
jest.mocked(binsConflictLogger.debug).mockClear()
|
||||||
|
jest.mocked(globalWarn).mockClear()
|
||||||
})
|
})
|
||||||
|
|
||||||
const POWER_SHELL_IS_SUPPORTED = isWindows()
|
const POWER_SHELL_IS_SUPPORTED = isWindows()
|
||||||
@@ -535,6 +536,17 @@ testOnWindows('linkBins() should remove an existing .exe file from the target di
|
|||||||
expect(fs.readdirSync(binTarget)).toEqual(getExpectedBins(['simple']))
|
expect(fs.readdirSync(binTarget)).toEqual(getExpectedBins(['simple']))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('linkBins() should handle bin field pointing to a directory gracefully', async () => {
|
||||||
|
const binTarget = tempy.directory()
|
||||||
|
const binIsDirFixture = f.prepare('bin-is-directory')
|
||||||
|
const warn = jest.fn()
|
||||||
|
|
||||||
|
await linkBins(path.join(binIsDirFixture, 'node_modules'), binTarget, { warn })
|
||||||
|
|
||||||
|
expect(fs.readdirSync(binTarget)).toEqual([])
|
||||||
|
expect(globalWarn).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
describe('enable prefer-symlinked-executables', () => {
|
describe('enable prefer-symlinked-executables', () => {
|
||||||
test('linkBins()', async () => {
|
test('linkBins()', async () => {
|
||||||
const binTarget = tempy.directory()
|
const binTarget = tempy.directory()
|
||||||
|
|||||||
Reference in New Issue
Block a user