fix(link): don't run install in the global pkg when linking global pkgs (#3594)

close #3462
This commit is contained in:
Zoltan Kochan
2021-07-12 02:58:54 +03:00
committed by GitHub
parent a1b85a72ab
commit d3ec941d2c
5 changed files with 61 additions and 28 deletions

View File

@@ -0,0 +1,5 @@
---
"supi": patch
---
Linking should not fail on context checks.

View File

@@ -0,0 +1,5 @@
---
"@pnpm/plugin-commands-installation": patch
---
`pnpm link -g <pkg>` should not break node_modules of the target project.

View File

@@ -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 <pkg name>`.

View File

@@ -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(

View File

@@ -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)