fix: catch error when binfile is not exisit (#5946)

close #5945
This commit is contained in:
bohan
2023-01-19 12:13:11 +08:00
committed by GitHub
parent 98d6603f31
commit 90d26c449d
3 changed files with 68 additions and 31 deletions

View File

@@ -0,0 +1,6 @@
---
"pnpm": patch
"@pnpm/link-bins": patch
---
Don't crash when a bin file is not found and `prefer-symlinked-executables` is `true` [#5946](https://github.com/pnpm/pnpm/pull/5946).

View File

@@ -209,8 +209,15 @@ async function linkBin (cmd: CommandInfo, binsDir: string, opts?: LinkBinOptions
}
if (opts?.preferSymlinkedExecutables && !IS_WINDOWS && cmd.nodeExecPath == null) {
await symlinkDir(cmd.path, externalBinPath)
await fixBin(cmd.path, 0o755)
try {
await symlinkDir(cmd.path, externalBinPath)
await fixBin(cmd.path, 0o755)
} catch (err: any) { // eslint-disable-line
if (err.code !== 'ENOENT') {
throw err
}
globalWarn(`Failed to create bin at ${externalBinPath}. The source file at ${cmd.path} does not exist.`)
}
return
}

View File

@@ -72,34 +72,6 @@ test('linkBins()', async () => {
}
})
test('linkBins() should work when prefer-symlinked-executables enabled', async () => {
const binTarget = tempy.directory()
const warn = jest.fn()
const simpleFixture = f.prepare('simple-fixture')
await linkBins(path.join(simpleFixture, 'node_modules'), binTarget, { warn, preferSymlinkedExecutables: true })
expect(warn).not.toHaveBeenCalled()
expect(await fs.readdir(binTarget)).toEqual(getExpectedBins(['simple']))
const binLocation = path.join(binTarget, 'simple')
expect(await exists(binLocation)).toBe(true)
const content = await fs.readFile(binLocation, 'utf8')
if (IS_WINDOWS) {
expect(content).toMatch('node_modules/simple/index.js')
} else {
expect(content).toMatch('console.log(\'hello_world\')')
}
if (EXECUTABLE_SHEBANG_SUPPORTED) {
const binFile = path.join(binTarget, 'simple')
const stat = await fs.stat(binFile)
expect(stat.mode).toBe(parseInt('100755', 8))
expect(stat.isFile()).toBe(true)
const stdout = spawnSync(binFile).stdout.toString('utf-8')
expect(stdout).toMatch('hello_world')
}
})
test('linkBins() never creates a PowerShell shim for the pnpm CLI', async () => {
const binTarget = tempy.directory()
const fixture = f.prepare('pnpm-cli')
@@ -403,7 +375,7 @@ test("linkBins() emits global warning when bin points to path that doesn't exist
).toHaveBeenCalled()
})
testOnWindows('linkBins() shoud remove an existing .exe file from the target directory', async () => {
testOnWindows('linkBins() should remove an existing .exe file from the target directory', async () => {
const binTarget = tempy.directory()
writeFileSync(path.join(binTarget, 'simple.exe'), '', 'utf8')
const warn = jest.fn()
@@ -413,3 +385,55 @@ testOnWindows('linkBins() shoud remove an existing .exe file from the target dir
expect(await fs.readdir(binTarget)).toEqual(getExpectedBins(['simple']))
})
describe('enable prefer-symlinked-executables', () => {
test('linkBins()', async () => {
const binTarget = tempy.directory()
const warn = jest.fn()
const simpleFixture = f.prepare('simple-fixture')
await linkBins(path.join(simpleFixture, 'node_modules'), binTarget, { warn, preferSymlinkedExecutables: true })
expect(warn).not.toHaveBeenCalled()
expect(await fs.readdir(binTarget)).toEqual(getExpectedBins(['simple']))
const binLocation = path.join(binTarget, 'simple')
expect(await exists(binLocation)).toBe(true)
const content = await fs.readFile(binLocation, 'utf8')
if (IS_WINDOWS) {
expect(content).toMatch('node_modules/simple/index.js')
} else {
expect(content).toMatch('console.log(\'hello_world\')')
}
if (EXECUTABLE_SHEBANG_SUPPORTED) {
const binFile = path.join(binTarget, 'simple')
const stat = await fs.stat(binFile)
expect(stat.mode).toBe(parseInt('100755', 8))
expect(stat.isFile()).toBe(true)
const stdout = spawnSync(binFile).stdout.toString('utf-8')
expect(stdout).toMatch('hello_world')
}
})
test("linkBins() emits global warning when bin points to path that doesn't exist", async () => {
const binTarget = tempy.directory()
const binNotExistFixture = f.prepare('bin-not-exist')
await linkBins(path.join(binNotExistFixture, 'node_modules'), binTarget, {
allowExoticManifests: true,
warn: () => {},
preferSymlinkedExecutables: true,
})
if (IS_WINDOWS) {
// cmdShim
expect(await fs.readdir(binTarget)).toEqual(getExpectedBins([]))
} else {
// it will fix symlink file permission
expect(await fs.readdir(binTarget)).toEqual(getExpectedBins(['meow']))
}
expect(
globalWarn
).toHaveBeenCalled()
})
})