Skip to content

Commit 3134980

Browse files
ericprestemonEric Prestemoniclanton
authored
[rush] Fix sync-back when dependencies move to devDependencies (#5811)
* [rush] Fix sync-back when dependencies move to devDependencies 'rush update' failed to sync back the corrected pnpm-lock.yaml when a dependency moved to devDependencies because isWorkspaceProjectModifiedAsync would unconditionally fall through to the 'dependencies' section if a package was missing from 'devDependencies'. This fall-through is now gated on the new set regularDependencyNames to support legitimate dual-declarations while correctly detecting when a dependency has been moved out of the 'dependencies' section. * Update common/changes/@microsoft/rush/fix-rush-update-devDependency-sync_2026-05-29-12-00.json Co-authored-by: Ian Clanton-Thuon <iclanton@users.noreply.github.com> * Update common/changes/@microsoft/rush/fix-rush-update-devDependency-sync_2026-05-29-12-00.json Co-authored-by: Ian Clanton-Thuon <iclanton@users.noreply.github.com> --------- Co-authored-by: Eric Prestemon <eric.prestemon@users.noreply.github.com> Co-authored-by: Ian Clanton-Thuon <iclanton@users.noreply.github.com>
1 parent 1d6cb66 commit 3134980

4 files changed

Lines changed: 70 additions & 0 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"changes": [
3+
{
4+
"comment": "Fix `rush update` not syncing `pnpm-lock.yaml` when a workspace dependency moves from `dependencies` to `devDependencies`.",
5+
"type": "patch",
6+
"packageName": "@microsoft/rush"
7+
}
8+
],
9+
"packageName": "@microsoft/rush",
10+
"email": "ericprestemon@users.noreply.github.com"
11+
}

libraries/rush-lib/src/logic/pnpm/PnpmShrinkwrapFile.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,8 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile {
11241124
const importerDevDependencies: Set<string> = new Set(Object.keys(importer.devDependencies ?? {}));
11251125
const importerDependenciesMeta: Set<string> = new Set(Object.keys(importer.dependenciesMeta ?? {}));
11261126

1127+
const regularDependencyNames: Set<string> = new Set(dependencyList.map(({ name }) => name));
1128+
11271129
for (const { dependencyType, name, version } of allDependencies) {
11281130
let isOptional: boolean = false;
11291131
let specifierFromLockfile: IPnpmVersionSpecifier | undefined;
@@ -1148,6 +1150,10 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile {
11481150
importerDevDependencies.delete(name);
11491151
break;
11501152
}
1153+
// If not a peer and not also a regular dependency, the lockfile is stale.
1154+
if (!isOptional && !regularDependencyNames.has(name)) {
1155+
return true;
1156+
}
11511157
// If fall through, there is a chance the package declares an inconsistent version, ignore it.
11521158
isDevDepFallThrough = true;
11531159
}

libraries/rush-lib/src/logic/pnpm/test/PnpmShrinkwrapFile.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,22 @@ snapshots:
487487
).resolves.toBe(false);
488488
});
489489

490+
it('can detect a devDependency that is still listed under dependencies in the importer', async () => {
491+
// Regression: moving a dep from dependencies to devDependencies should be detected as modified.
492+
const project = getMockRushProject();
493+
const pnpmShrinkwrapFile = getPnpmShrinkwrapFileFromFile(
494+
`${__dirname}/yamlFiles/pnpm-lock-v9/stale-dev-in-dependencies.yaml`,
495+
project.rushConfiguration.defaultSubspace
496+
);
497+
await expect(
498+
pnpmShrinkwrapFile.isWorkspaceProjectModifiedAsync(
499+
project,
500+
project.rushConfiguration.defaultSubspace,
501+
undefined
502+
)
503+
).resolves.toBe(true);
504+
});
505+
490506
it('sha1 integrity can be handled when disallowInsecureSha1', async () => {
491507
const project = getMockRushProject();
492508
const pnpmShrinkwrapFile = getPnpmShrinkwrapFileFromFile(
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
lockfileVersion: '9.0'
2+
3+
settings:
4+
autoInstallPeers: true
5+
excludeLinksFromLockfile: false
6+
7+
importers:
8+
.: {}
9+
10+
../../apps/foo:
11+
dependencies:
12+
tslib:
13+
specifier: ~2.3.1
14+
version: 2.3.1
15+
typescript:
16+
specifier: ~5.0.4
17+
version: 5.0.4
18+
19+
packages:
20+
tslib@2.3.1:
21+
resolution:
22+
{
23+
integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
24+
}
25+
26+
typescript@5.0.4:
27+
resolution:
28+
{
29+
integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
30+
}
31+
engines: { node: '>=12.20' }
32+
hasBin: true
33+
34+
snapshots:
35+
tslib@2.3.1: {}
36+
37+
typescript@5.0.4: {}

0 commit comments

Comments
 (0)