mirror of
https://github.com/pnpm/pnpm.git
synced 2026-01-15 02:18:31 -05:00
close #5118
This commit is contained in:
committed by
Zoltan Kochan
parent
df80112cfe
commit
17344ca27f
6
.changeset/every-trains-shake.md
Normal file
6
.changeset/every-trains-shake.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-installation": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
When a user runs `pnpm update` on a dependency that is not directly listed in `package.json`, none of the direct dependencies should be updated [#10155](https://github.com/pnpm/pnpm/pull/10155).
|
||||
@@ -272,6 +272,8 @@ when running add/update with the --workspace option')
|
||||
}
|
||||
|
||||
let updateMatch: UpdateDepsMatcher | null
|
||||
let updatePackageManifest = opts.updatePackageManifest
|
||||
let updateMatching: ((pkgName: string) => boolean) | undefined
|
||||
if (opts.update) {
|
||||
if (params.length === 0) {
|
||||
const ignoreDeps = opts.updateConfig?.ignoreDependencies
|
||||
@@ -291,6 +293,10 @@ when running add/update with the --workspace option')
|
||||
throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES',
|
||||
'None of the specified packages were found in the dependencies.')
|
||||
}
|
||||
// No direct dependencies matched, so we're updating indirect dependencies only
|
||||
// Don't update package.json in this case, and limit updates to only matching dependencies
|
||||
updatePackageManifest = false
|
||||
updateMatching = (pkgName: string) => updateMatch!(pkgName) != null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +349,11 @@ when running add/update with the --workspace option')
|
||||
return
|
||||
}
|
||||
|
||||
const { updatedCatalogs, updatedManifest, ignoredBuilds } = await install(manifest, installOpts)
|
||||
const { updatedCatalogs, updatedManifest, ignoredBuilds } = await install(manifest, {
|
||||
...installOpts,
|
||||
updatePackageManifest,
|
||||
updateMatching,
|
||||
})
|
||||
if (opts.update === true && opts.save !== false) {
|
||||
await Promise.all([
|
||||
writeProjectManifest(updatedManifest),
|
||||
|
||||
@@ -684,6 +684,44 @@ test('update with tag @latest will downgrade prerelease', async function () {
|
||||
expect(lockfile2).toHaveProperty(['packages', '@pnpm.e2e/has-prerelease@2.0.0'])
|
||||
})
|
||||
|
||||
test('update indirect dependency should not update package.json', async function () {
|
||||
const project = prepare({
|
||||
dependencies: {
|
||||
'@pnpm.e2e/pkg-with-1-dep': '^100.0.0',
|
||||
},
|
||||
})
|
||||
|
||||
// Ensure the initial versions
|
||||
await addDistTag('@pnpm.e2e/pkg-with-1-dep', '100.0.0', 'latest')
|
||||
await addDistTag('@pnpm.e2e/dep-of-pkg-with-1-dep', '100.0.0', 'latest')
|
||||
|
||||
await execPnpm(['install'])
|
||||
|
||||
const pkg1 = await readPackageJsonFromDir(process.cwd())
|
||||
expect(pkg1.dependencies?.['@pnpm.e2e/pkg-with-1-dep']).toBe('^100.0.0')
|
||||
|
||||
const lockfile1 = project.readLockfile()
|
||||
expect(lockfile1.importers['.'].dependencies?.['@pnpm.e2e/pkg-with-1-dep'].version).toBe('100.0.0')
|
||||
|
||||
// Now publish a new version of the direct dependency and update the indirect dependency
|
||||
await addDistTag('@pnpm.e2e/pkg-with-1-dep', '100.1.0', 'latest')
|
||||
await addDistTag('@pnpm.e2e/dep-of-pkg-with-1-dep', '100.1.0', 'latest')
|
||||
|
||||
// Update the indirect dependency only
|
||||
await execPnpm(['update', '@pnpm.e2e/dep-of-pkg-with-1-dep@latest'])
|
||||
|
||||
// The direct dependency in package.json should remain unchanged at ^100.0.0
|
||||
const pkg2 = await readPackageJsonFromDir(process.cwd())
|
||||
expect(pkg2.dependencies?.['@pnpm.e2e/pkg-with-1-dep']).toBe('^100.0.0')
|
||||
|
||||
// But the lockfile should have the updated indirect dependency
|
||||
const lockfile2 = project.readLockfile()
|
||||
expect(Object.keys(lockfile2.packages ?? {})).toContain('@pnpm.e2e/dep-of-pkg-with-1-dep@100.1.0')
|
||||
|
||||
// The direct dependency should remain at 100.0.0 in the lockfile (not upgraded to 100.1.0)
|
||||
expect(lockfile2.importers['.'].dependencies?.['@pnpm.e2e/pkg-with-1-dep'].version).toBe('100.0.0')
|
||||
})
|
||||
|
||||
test('update to latest recursive workspace (outdated, updated, prerelease, outdated)', async function () {
|
||||
await addDistTag('@pnpm.e2e/has-prerelease', '2.0.0', 'latest')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user