From 96b507b73ead79c98651f88e2b97d215885dcf43 Mon Sep 17 00:00:00 2001 From: chlorine Date: Mon, 10 Oct 2022 17:26:00 +0800 Subject: [PATCH] fix: add dir option support in link --global (#5473) Co-authored-by: Zoltan Kochan --- .changeset/few-ghosts-rule.md | 6 +++ .changeset/heavy-tools-agree.md | 5 ++ packages/core/src/install/index.ts | 2 +- .../plugin-commands-installation/src/link.ts | 8 +-- .../plugin-commands-installation/test/link.ts | 49 ++++++++++++++++++- 5 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 .changeset/few-ghosts-rule.md create mode 100644 .changeset/heavy-tools-agree.md diff --git a/.changeset/few-ghosts-rule.md b/.changeset/few-ghosts-rule.md new file mode 100644 index 00000000000..81230afe34a --- /dev/null +++ b/.changeset/few-ghosts-rule.md @@ -0,0 +1,6 @@ +--- +"@pnpm/plugin-commands-installation": patch +"pnpm": patch +--- + +`pnpm link --global` should work when a custom target directory is specified with the `--dir` CLI option [#5473](https://github.com/pnpm/pnpm/pull/5473). diff --git a/.changeset/heavy-tools-agree.md b/.changeset/heavy-tools-agree.md new file mode 100644 index 00000000000..be606f4f71d --- /dev/null +++ b/.changeset/heavy-tools-agree.md @@ -0,0 +1,5 @@ +--- +"@pnpm/core": patch +--- + +Fix WARN undefined has no binaries diff --git a/packages/core/src/install/index.ts b/packages/core/src/install/index.ts index 8fa8d6066ac..580a16440cd 100644 --- a/packages/core/src/install/index.ts +++ b/packages/core/src/install/index.ts @@ -1005,7 +1005,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => { if (opts.global && projectToInstall.mutation.includes('install')) { projectToInstall.wantedDependencies.forEach(pkg => { if (!linkedPackages?.includes(pkg.alias)) { - logger.warn({ message: `${pkg.alias} has no binaries`, prefix: opts.lockfileDir }) + logger.warn({ message: `${pkg.alias ?? pkg.pref} has no binaries`, prefix: opts.lockfileDir }) } }) } diff --git a/packages/plugin-commands-installation/src/link.ts b/packages/plugin-commands-installation/src/link.ts index bd98969c139..32170cddee1 100644 --- a/packages/plugin-commands-installation/src/link.ts +++ b/packages/plugin-commands-installation/src/link.ts @@ -113,6 +113,8 @@ export async function handler ( workspacePackages, }) + const linkCwdDir = opts.cliOptions?.dir && opts.cliOptions?.global ? path.resolve(opts.cliOptions.dir) : cwd + // pnpm link if ((params == null) || (params.length === 0)) { if (path.relative(linkOpts.dir, cwd) === '') { @@ -121,7 +123,7 @@ export async function handler ( const { manifest, writeProjectManifest } = await tryReadProjectManifest(opts.dir, opts) const newManifest = await addDependenciesToPackage( manifest ?? {}, - [`link:${opts.cliOptions?.dir ? path.resolve(opts.cliOptions.dir) : cwd}`], + [`link:${linkCwdDir}`], linkOpts ) await writeProjectManifest(newManifest) @@ -179,7 +181,7 @@ export async function handler ( globalPkgNames.forEach((pkgName) => pkgPaths.push(path.join(globalPkgPath, 'node_modules', pkgName))) } - const { manifest, writeProjectManifest } = await readProjectManifest(cwd, opts) + const { manifest, writeProjectManifest } = await readProjectManifest(linkCwdDir, opts) const linkConfig = await getConfig( { ...opts.cliOptions, dir: cwd }, @@ -190,7 +192,7 @@ export async function handler ( } ) const storeL = await createOrConnectStoreControllerCached(storeControllerCache, linkConfig) - const newManifest = await link(pkgPaths, path.join(cwd, 'node_modules'), { + const newManifest = await link(pkgPaths, path.join(linkCwdDir, 'node_modules'), { ...linkConfig, targetDependenciesField: linkOpts.targetDependenciesField, storeController: storeL.ctrl, diff --git a/packages/plugin-commands-installation/test/link.ts b/packages/plugin-commands-installation/test/link.ts index 08fecf2b7f8..94e6f5b30d7 100644 --- a/packages/plugin-commands-installation/test/link.ts +++ b/packages/plugin-commands-installation/test/link.ts @@ -64,6 +64,9 @@ test('link global bin', async function () { await link.handler({ ...DEFAULT_OPTS, + cliOptions: { + global: true, + }, bin: globalBin, dir: globalDir, }) @@ -72,7 +75,7 @@ test('link global bin', async function () { await isExecutable((value) => expect(value).toBeTruthy(), path.join(globalBin, 'package-with-bin')) }) -test('link --dir global bin', async function () { +test('link to global bin from the specified directory', async function () { prepare() process.chdir('..') @@ -88,6 +91,7 @@ test('link --dir global bin', async function () { await link.handler({ ...DEFAULT_OPTS, cliOptions: { + global: true, dir: path.resolve('./dir/package-with-bin-in-dir'), }, bin: globalBin, @@ -98,6 +102,49 @@ test('link --dir global bin', async function () { await isExecutable((value) => expect(value).toBeTruthy(), path.join(globalBin, 'package-with-bin-in-dir')) }) +test('link a global package to the specified directory', async function () { + const project = prepare() + process.chdir('..') + + const globalDir = path.resolve('global') + const globalBin = path.join(globalDir, 'bin') + const oldPath = process.env[PATH] + process.env[PATH] = `${globalBin}${path.delimiter}${oldPath ?? ''}` + await fs.mkdir(globalBin, { recursive: true }) + + await writePkg('global-package-with-bin', { name: 'global-package-with-bin', version: '1.0.0', bin: 'bin.js' }) + await fs.writeFile('global-package-with-bin/bin.js', '#!/usr/bin/env node\nconsole.log(/hi/)\n', 'utf8') + + process.chdir('global-package-with-bin') + + // link to global + await link.handler({ + ...DEFAULT_OPTS, + cliOptions: { + global: true, + }, + bin: globalBin, + dir: globalDir, + }) + + process.chdir('..') + + // link from global + await link.handler({ + ...DEFAULT_OPTS, + cliOptions: { + global: true, + dir: path.resolve('./project'), + }, + bin: globalBin, + dir: globalDir, + }, ['global-package-with-bin']) + + process.env[PATH] = oldPath + + await project.has('global-package-with-bin') +}) + test('relative link', async () => { const project = prepare({ dependencies: {