mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-25 08:08:14 -05:00
fix: add dir option support in link <pkg> --global (#5473)
Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
6
.changeset/few-ghosts-rule.md
Normal file
6
.changeset/few-ghosts-rule.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-installation": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
`pnpm link <pkg> --global` should work when a custom target directory is specified with the `--dir` CLI option [#5473](https://github.com/pnpm/pnpm/pull/5473).
|
||||
5
.changeset/heavy-tools-agree.md
Normal file
5
.changeset/heavy-tools-agree.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/core": patch
|
||||
---
|
||||
|
||||
Fix WARN undefined has no binaries
|
||||
@@ -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 })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user