diff --git a/.changeset/rich-books-relate.md b/.changeset/rich-books-relate.md new file mode 100644 index 0000000000..f53d649020 --- /dev/null +++ b/.changeset/rich-books-relate.md @@ -0,0 +1,5 @@ +--- +"supi": patch +--- + +Linking should not fail on context checks. diff --git a/.changeset/sixty-yaks-buy.md b/.changeset/sixty-yaks-buy.md new file mode 100644 index 0000000000..5fc856cfa6 --- /dev/null +++ b/.changeset/sixty-yaks-buy.md @@ -0,0 +1,5 @@ +--- +"@pnpm/plugin-commands-installation": patch +--- + +`pnpm link -g ` should not break node_modules of the target project. diff --git a/.changeset/ten-dogs-call.md b/.changeset/ten-dogs-call.md new file mode 100644 index 0000000000..c20e4ed82b --- /dev/null +++ b/.changeset/ten-dogs-call.md @@ -0,0 +1,5 @@ +--- +"@pnpm/plugin-commands-installation": patch +--- + +Do not run installation in the global package, when linking a dependency using `pnpm link -g `. diff --git a/packages/plugin-commands-installation/src/link.ts b/packages/plugin-commands-installation/src/link.ts index d677081dc5..92d2c6db27 100644 --- a/packages/plugin-commands-installation/src/link.ts +++ b/packages/plugin-commands-installation/src/link.ts @@ -17,6 +17,7 @@ import { install, InstallOptions, link, + LinkFunctionOptions, linkToGlobal, WorkspacePackages, } from 'supi' @@ -124,27 +125,6 @@ export async function handler ( const [pkgPaths, pkgNames] = partition((inp) => isFilespec.test(inp), params) - if (pkgNames.length > 0) { - let globalPkgNames!: string[] - if (opts.workspaceDir) { - workspacePackagesArr = await findWorkspacePackages(opts.workspaceDir, opts) - - const pkgsFoundInWorkspace = workspacePackagesArr - .filter(({ manifest }) => manifest.name && pkgNames.includes(manifest.name)) - pkgsFoundInWorkspace.forEach((pkgFromWorkspace) => pkgPaths.push(pkgFromWorkspace.dir)) - - if ((pkgsFoundInWorkspace.length > 0) && !linkOpts.targetDependenciesField) { - linkOpts.targetDependenciesField = 'dependencies' - } - - globalPkgNames = pkgNames.filter((pkgName) => !pkgsFoundInWorkspace.some((pkgFromWorkspace) => pkgFromWorkspace.manifest.name === pkgName)) - } else { - globalPkgNames = pkgNames - } - const globalPkgPath = pathAbsolute(opts.dir) - globalPkgNames.forEach((pkgName) => pkgPaths.push(path.join(globalPkgPath, 'node_modules', pkgName))) - } - await Promise.all( pkgPaths.map(async (dir) => installLimit(async () => { const s = await createOrConnectStoreControllerCached(storeControllerCache, opts) @@ -171,12 +151,46 @@ export async function handler ( ) })) ) + + if (pkgNames.length > 0) { + let globalPkgNames!: string[] + if (opts.workspaceDir) { + workspacePackagesArr = await findWorkspacePackages(opts.workspaceDir, opts) + + const pkgsFoundInWorkspace = workspacePackagesArr + .filter(({ manifest }) => manifest.name && pkgNames.includes(manifest.name)) + pkgsFoundInWorkspace.forEach((pkgFromWorkspace) => pkgPaths.push(pkgFromWorkspace.dir)) + + if ((pkgsFoundInWorkspace.length > 0) && !linkOpts.targetDependenciesField) { + linkOpts.targetDependenciesField = 'dependencies' + } + + globalPkgNames = pkgNames.filter((pkgName) => !pkgsFoundInWorkspace.some((pkgFromWorkspace) => pkgFromWorkspace.manifest.name === pkgName)) + } else { + globalPkgNames = pkgNames + } + const globalPkgPath = pathAbsolute(opts.dir) + globalPkgNames.forEach((pkgName) => pkgPaths.push(path.join(globalPkgPath, 'node_modules', pkgName))) + } + const { manifest, writeProjectManifest } = await readProjectManifest(cwd, opts) + const linkConfig = await getConfig( + { ...opts.cliOptions, dir: cwd }, + { + excludeReporter: true, + rcOptionsTypes: installCommand.rcOptionsTypes(), + workspaceDir: await findWorkspaceDir(cwd), + } + ) + const storeL = await createOrConnectStoreControllerCached(storeControllerCache, linkConfig) const newManifest = await link(pkgPaths, path.join(cwd, 'node_modules'), { - ...linkOpts, + ...linkConfig, + targetDependenciesField: linkOpts.targetDependenciesField, + storeController: storeL.ctrl, + storeDir: storeL.dir, manifest, - }) + } as LinkFunctionOptions) await writeProjectManifest(newManifest) await Promise.all( diff --git a/packages/supi/src/link/index.ts b/packages/supi/src/link/index.ts index 480e490140..7202b3ed22 100644 --- a/packages/supi/src/link/index.ts +++ b/packages/supi/src/link/index.ts @@ -37,13 +37,17 @@ import { LinkOptions, } from './options' +type LinkFunctionOptions = LinkOptions & { + linkToBin?: string + dir: string +} + +export { LinkFunctionOptions } + export default async function link ( linkFromPkgs: Array<{alias: string, path: string} | string>, destModules: string, - maybeOpts: LinkOptions & { - linkToBin?: string - dir: string - } + maybeOpts: LinkFunctionOptions ) { const reporter = maybeOpts?.reporter if ((reporter != null) && typeof reporter === 'function') { @@ -53,7 +57,7 @@ export default async function link ( const ctx = await getContextForSingleImporter(opts.manifest, { ...opts, extraBinPaths: [], // ctx.extraBinPaths is not needed, so this is fine - }) + }, true) const importerId = getLockfileImporterId(ctx.lockfileDir, opts.dir) const currentLockfile = clone(ctx.currentLockfile)