mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-23 17:41:50 -04:00
fix: a package should be able to be a dependency of itself (#4289)
This commit is contained in:
5
.changeset/kind-walls-cover.md
Normal file
5
.changeset/kind-walls-cover.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/resolve-dependencies": major
|
||||
---
|
||||
|
||||
Don't skip a dependency that is named the same way as the package, if it has a different version.
|
||||
7
.changeset/nice-dragons-end.md
Normal file
7
.changeset/nice-dragons-end.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@pnpm/core": patch
|
||||
"@pnpm/headless": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
A package should be able to be a dependency of itself.
|
||||
@@ -423,6 +423,14 @@ async function linkAllPkgs (
|
||||
})
|
||||
}
|
||||
depNode.isBuilt = isBuilt
|
||||
|
||||
const selfDep = depNode.children[depNode.name]
|
||||
if (selfDep) {
|
||||
const pkg = opts.depGraph[selfDep]
|
||||
if (!pkg || !pkg.installable && pkg.optional) return
|
||||
const targetModulesDir = path.join(depNode.modules, depNode.name, 'node_modules')
|
||||
await limitLinking(async () => symlinkDependency(pkg.dir, targetModulesDir, depNode.name))
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -449,21 +457,14 @@ async function linkAllModules (
|
||||
}, {})
|
||||
|
||||
await Promise.all(
|
||||
Object.keys(childrenToLink)
|
||||
.map(async (childAlias) => {
|
||||
if (childrenToLink[childAlias].startsWith('link:')) {
|
||||
await limitLinking(async () => symlinkDependency(path.resolve(opts.lockfileDir, childrenToLink[childAlias].substr(5)), modules, childAlias))
|
||||
return
|
||||
}
|
||||
const pkg = depGraph[childrenToLink[childAlias]]
|
||||
if (!pkg || !pkg.installable && pkg.optional) return
|
||||
if (childAlias === name) {
|
||||
logger.warn({
|
||||
message: `Cannot link dependency with name ${childAlias} to ${modules}. Dependency's name should differ from the parent's name.`,
|
||||
prefix: opts.lockfileDir,
|
||||
})
|
||||
Object.entries(childrenToLink)
|
||||
.map(async ([childAlias, childDepPath]) => {
|
||||
if (childDepPath.startsWith('link:')) {
|
||||
await limitLinking(async () => symlinkDependency(path.resolve(opts.lockfileDir, childDepPath.substr(5)), modules, childAlias))
|
||||
return
|
||||
}
|
||||
const pkg = depGraph[childDepPath]
|
||||
if (!pkg || !pkg.installable && pkg.optional || childAlias === name) return
|
||||
await limitLinking(async () => symlinkDependency(pkg.dir, modules, childAlias))
|
||||
})
|
||||
)
|
||||
|
||||
@@ -1320,3 +1320,23 @@ test('installing a package with broken bin', async () => {
|
||||
|
||||
await project.has('broken-bin')
|
||||
})
|
||||
|
||||
test('a package should be able to be a dependency of itself', async () => {
|
||||
const project = prepareEmpty()
|
||||
|
||||
const manifest = await addDependenciesToPackage({}, ['@paul-soporan/test-package-self-require-trap@2.0.0'], await testDefaults())
|
||||
|
||||
const subpkg = '.pnpm/@paul-soporan+test-package-self-require-trap@2.0.0/node_modules/@paul-soporan/test-package-self-require-trap/node_modules/@paul-soporan/test-package-self-require-trap/package.json'
|
||||
{
|
||||
const pkg = project.requireModule(subpkg)
|
||||
expect(pkg.version).toBe('1.0.0')
|
||||
}
|
||||
|
||||
await rimraf('node_modules')
|
||||
await install(manifest, await testDefaults({ frozenLockfile: true }))
|
||||
|
||||
{
|
||||
const pkg = project.requireModule(subpkg)
|
||||
expect(pkg.version).toBe('1.0.0')
|
||||
}
|
||||
})
|
||||
|
||||
@@ -690,6 +690,14 @@ async function linkAllPkgs (
|
||||
})
|
||||
}
|
||||
depNode.isBuilt = isBuilt
|
||||
|
||||
const selfDep = depNode.children[depNode.name]
|
||||
if (selfDep) {
|
||||
const pkg = opts.depGraph[selfDep]
|
||||
if (!pkg) return
|
||||
const targetModulesDir = path.join(depNode.modules, depNode.name, 'node_modules')
|
||||
await limitLinking(async () => symlinkDependency(pkg.dir, targetModulesDir, depNode.name))
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -763,17 +771,13 @@ async function linkAllModules (
|
||||
}, {})
|
||||
|
||||
await Promise.all(
|
||||
Object.keys(childrenToLink)
|
||||
.map(async (alias) => {
|
||||
Object.entries(childrenToLink)
|
||||
.map(async ([alias, pkgDir]) => {
|
||||
// if (!pkg.installable && pkg.optional) return
|
||||
if (alias === depNode.name) {
|
||||
logger.warn({
|
||||
message: `Cannot link dependency with name ${alias} to ${depNode.modules}. Dependency's name should differ from the parent's name.`,
|
||||
prefix: opts.lockfileDir,
|
||||
})
|
||||
return
|
||||
}
|
||||
await limitLinking(async () => symlinkDependency(childrenToLink[alias], depNode.modules, alias))
|
||||
await limitLinking(async () => symlinkDependency(pkgDir, depNode.modules, alias))
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
@@ -11,7 +11,6 @@ export interface WantedDependency {
|
||||
export default function getNonDevWantedDependencies (pkg: DependencyManifest) {
|
||||
const bd = pkg.bundleDependencies ?? pkg.bundleDependencies
|
||||
const bundledDeps = new Set(Array.isArray(bd) ? bd : [])
|
||||
bundledDeps.add(pkg.name)
|
||||
const filterDeps = getNotBundledDeps.bind(null, bundledDeps)
|
||||
return getWantedDependenciesFromGivenSet(
|
||||
filterDeps({ ...pkg.optionalDependencies, ...pkg.dependencies }),
|
||||
|
||||
@@ -713,7 +713,7 @@ async function resolveDependency (
|
||||
options.parentPkg.nodeId,
|
||||
options.parentPkg.depPath,
|
||||
depPath
|
||||
)
|
||||
) || depPath === options.parentPkg.depPath
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user