fix: a package should be able to be a dependency of itself (#4289)

This commit is contained in:
Zoltan Kochan
2022-01-30 05:02:42 +02:00
committed by GitHub
parent 9639f57872
commit 37d09a68fa
7 changed files with 58 additions and 22 deletions

View 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.

View File

@@ -0,0 +1,7 @@
---
"@pnpm/core": patch
"@pnpm/headless": patch
"pnpm": patch
---
A package should be able to be a dependency of itself.

View File

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

View File

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

View File

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

View File

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

View File

@@ -713,7 +713,7 @@ async function resolveDependency (
options.parentPkg.nodeId,
options.parentPkg.depPath,
depPath
)
) || depPath === options.parentPkg.depPath
) {
return null
}