From 22c7acc4dc9d0272e90aacbf582d00598cc41e8b Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Mon, 12 Feb 2024 10:38:55 +0100 Subject: [PATCH] fix: linking globally a package with no name in package.json (#7637) close #4761 close #4793 --- .changeset/thin-pumpkins-mate.md | 6 ++++ .../src/resolveDependencies.ts | 2 +- pnpm/test/link.ts | 31 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 .changeset/thin-pumpkins-mate.md create mode 100644 pnpm/test/link.ts diff --git a/.changeset/thin-pumpkins-mate.md b/.changeset/thin-pumpkins-mate.md new file mode 100644 index 0000000000..b6224fadab --- /dev/null +++ b/.changeset/thin-pumpkins-mate.md @@ -0,0 +1,6 @@ +--- +"@pnpm/resolve-dependencies": patch +"pnpm": patch +--- + +Link globally the command of a package that has no name in `package.json` [#4761](https://github.com/pnpm/pnpm/issues/4761). diff --git a/pkg-manager/resolve-dependencies/src/resolveDependencies.ts b/pkg-manager/resolve-dependencies/src/resolveDependencies.ts index 5705ebbee7..d3c5f296e0 100644 --- a/pkg-manager/resolve-dependencies/src/resolveDependencies.ts +++ b/pkg-manager/resolve-dependencies/src/resolveDependencies.ts @@ -1156,7 +1156,7 @@ async function resolveDependency ( throw new PnpmError('MISSING_PACKAGE_JSON', `Can't install ${wantedDependency.pref}: Missing package.json file`) } return { - alias: wantedDependency.alias || manifest.name, + alias: wantedDependency.alias || manifest.name || path.basename(pkgResponse.body.resolution.directory), depPath: pkgResponse.body.id, dev: wantedDependency.dev, isLinkedDependency: true, diff --git a/pnpm/test/link.ts b/pnpm/test/link.ts new file mode 100644 index 0000000000..a78b121a23 --- /dev/null +++ b/pnpm/test/link.ts @@ -0,0 +1,31 @@ +import path from 'path' +import PATH_NAME from 'path-name' +import fs from 'fs' +import { isExecutable } from '@pnpm/assert-project' +import { LAYOUT_VERSION } from '@pnpm/constants' +import { prepare } from '@pnpm/prepare' +import { execPnpm } from './utils' + +test('link globally the command of a package that has no name in package.json', async () => { + prepare() + fs.mkdirSync('cmd') + process.chdir('cmd') + fs.writeFileSync('package.json', JSON.stringify({ bin: { cmd: 'bin.js' } }), 'utf8') + fs.writeFileSync('bin.js', `#!/usr/bin/env node +console.log("hello world");`, 'utf8') + + const global = path.resolve('..', 'global') + const pnpmHome = path.join(global, 'pnpm') + fs.mkdirSync(global) + + const env = { [PATH_NAME]: pnpmHome, PNPM_HOME: pnpmHome, XDG_DATA_HOME: global } + + await execPnpm(['link', '--global'], { env }) + + const globalPrefix = path.join(global, `pnpm/global/${LAYOUT_VERSION}`) + expect(fs.existsSync(path.join(globalPrefix, 'node_modules/cmd'))).toBeTruthy() + const ok = (value: any) => { // eslint-disable-line + expect(value).toBeTruthy() + } + await isExecutable(ok, path.join(pnpmHome, 'cmd')) +})