diff --git a/.changeset/empty-dancers-stare.md b/.changeset/empty-dancers-stare.md new file mode 100644 index 0000000000..20c4d88c7d --- /dev/null +++ b/.changeset/empty-dancers-stare.md @@ -0,0 +1,7 @@ +--- +"@pnpm/core": patch +"@pnpm/link-bins": patch +"pnpm": patch +--- + +Don't crash if a bin file cannot be created because the source files could not be found. diff --git a/package.json b/package.json index bb00f76759..6d8da887f1 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@commitlint/prompt-cli": "^14.1.0", "@pnpm/eslint-config": "workspace:*", "@pnpm/meta-updater": "0.0.6", - "@pnpm/registry-mock": "^2.8.0", + "@pnpm/registry-mock": "^2.9.0", "@pnpm/tsconfig": "workspace:*", "@types/jest": "^26.0.24", "@types/node": "^14.17.32", diff --git a/packages/core/test/install/misc.ts b/packages/core/test/install/misc.ts index 9f2738663a..bbb0b0178d 100644 --- a/packages/core/test/install/misc.ts +++ b/packages/core/test/install/misc.ts @@ -1311,3 +1311,11 @@ test('two dependencies have the same version and name. The only difference is th expect((await fs.readdir(path.resolve('node_modules/.pnpm'))).length).toBe(5) }) + +test('installing a package with broken bin', async () => { + const project = prepareEmpty() + + await addDependenciesToPackage({}, ['broken-bin@1.0.0'], await testDefaults({ fastUnpack: false })) + + await project.has('broken-bin') +}) diff --git a/packages/link-bins/src/index.ts b/packages/link-bins/src/index.ts index 09c8730002..df6c2f7a76 100644 --- a/packages/link-bins/src/index.ts +++ b/packages/link-bins/src/index.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'fs' import Module from 'module' import path from 'path' import PnpmError from '@pnpm/error' -import logger from '@pnpm/logger' +import logger, { globalWarn } from '@pnpm/logger' import { getAllDependenciesFromManifest } from '@pnpm/manifest-utils' import binify, { Command } from '@pnpm/package-bins' import readModulesDir from '@pnpm/read-modules-dir' @@ -211,11 +211,19 @@ async function linkBin (cmd: CommandInfo, binsDir: string, opts?: { extendNodePa nodePath = union(nodePath, await getBinNodePaths(binsParentDir)) } } - await cmdShim(cmd.path, externalBinPath, { - createPwshFile: cmd.makePowerShellShim, - nodePath, - nodeExecPath: cmd.nodeExecPath, - }) + try { + await cmdShim(cmd.path, externalBinPath, { + createPwshFile: cmd.makePowerShellShim, + nodePath, + nodeExecPath: cmd.nodeExecPath, + }) + } 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 + } // ensure that bin are executable and not containing // windows line-endings(CRLF) on the hashbang line if (EXECUTABLE_SHEBANG_SUPPORTED) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b7ada590b5..c6c78cba77 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,7 +39,7 @@ importers: '@commitlint/prompt-cli': ^14.1.0 '@pnpm/eslint-config': workspace:* '@pnpm/meta-updater': 0.0.6 - '@pnpm/registry-mock': ^2.8.0 + '@pnpm/registry-mock': ^2.9.0 '@pnpm/tsconfig': workspace:* '@types/jest': ^26.0.24 '@types/node': ^14.17.32 @@ -70,7 +70,7 @@ importers: '@commitlint/prompt-cli': 14.1.0 '@pnpm/eslint-config': link:utils/eslint-config '@pnpm/meta-updater': 0.0.6 - '@pnpm/registry-mock': 2.8.0 + '@pnpm/registry-mock': 2.9.0 '@pnpm/tsconfig': link:utils/tsconfig '@types/jest': 26.0.24 '@types/node': 14.17.33 @@ -4887,8 +4887,8 @@ packages: strip-bom: 4.0.0 dev: true - /@pnpm/registry-mock/2.8.0: - resolution: {integrity: sha512-Pfvl8wbcetA+m/95LwX3q0/Q+DupL6gHBc9yZJeLDlqZ6Q65B9PykeUR+xRw1qipXvBTr8OTJ7joQKkak0VqCQ==} + /@pnpm/registry-mock/2.9.0: + resolution: {integrity: sha512-o3jkMVvyZ/kGZXVQ4f+8ENH2p2A/AIH4kAz0d4ULxtCeXS5ujRIqCfwaBYIU2NfJrZP8lSMYsLBat1egXJV+GA==} engines: {node: '>=10.13'} hasBin: true dependencies: