Skip to content

Commit b898b53

Browse files
larixermerceyz
andauthored
fix(nm): takes into account scoped packages during syncing tree with disk (#4266)
* Takes into account scoped packages during syncing tree with disk * Update packages/acceptance-tests/pkg-tests-specs/sources/node-modules.test.ts Co-authored-by: Kristoffer K. <[email protected]> Co-authored-by: Kristoffer K. <[email protected]>
1 parent ea699bc commit b898b53

File tree

3 files changed

+56
-7
lines changed

3 files changed

+56
-7
lines changed

.yarn/versions/9aaf86c6.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
releases:
2+
"@yarnpkg/cli": patch
3+
"@yarnpkg/plugin-nm": patch
4+
5+
declined:
6+
- "@yarnpkg/plugin-compat"
7+
- "@yarnpkg/plugin-constraints"
8+
- "@yarnpkg/plugin-dlx"
9+
- "@yarnpkg/plugin-essentials"
10+
- "@yarnpkg/plugin-init"
11+
- "@yarnpkg/plugin-interactive-tools"
12+
- "@yarnpkg/plugin-npm-cli"
13+
- "@yarnpkg/plugin-pack"
14+
- "@yarnpkg/plugin-patch"
15+
- "@yarnpkg/plugin-pnp"
16+
- "@yarnpkg/plugin-pnpm"
17+
- "@yarnpkg/plugin-stage"
18+
- "@yarnpkg/plugin-typescript"
19+
- "@yarnpkg/plugin-version"
20+
- "@yarnpkg/plugin-workspace-tools"
21+
- "@yarnpkg/builder"
22+
- "@yarnpkg/core"
23+
- "@yarnpkg/doctor"

packages/acceptance-tests/pkg-tests-specs/sources/node-modules.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,32 @@ describe(`Node_Modules`, () => {
16491649
),
16501650
);
16511651

1652+
it(`should only reinstall scoped dependencies deleted by the user on the next install`,
1653+
makeTemporaryEnv(
1654+
{
1655+
dependencies: {
1656+
[`@types/no-deps`]: `1.0.0`,
1657+
[`@types/is-number`]: `1.0.0`,
1658+
},
1659+
},
1660+
{
1661+
nodeLinker: `node-modules`,
1662+
},
1663+
async ({path, run}) => {
1664+
await run(`install`);
1665+
1666+
await xfs.removePromise(`${path}/node_modules/@types/is-number` as PortablePath);
1667+
const inode = (await xfs.statPromise(`${path}/node_modules/@types/no-deps/package.json` as PortablePath)).ino;
1668+
1669+
await run(`install`);
1670+
const nextInode = (await xfs.statPromise(`${path}/node_modules/@types/no-deps/package.json` as PortablePath)).ino;
1671+
1672+
await expect(xfs.existsPromise(`${path}/node_modules/@types/is-number` as PortablePath));
1673+
expect(nextInode).toEqual(inode);
1674+
},
1675+
),
1676+
);
1677+
16521678
it(`should support portals to external workspaces`,
16531679
makeTemporaryEnv(
16541680
{

packages/plugin-nm/sources/NodeModulesLinker.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -842,12 +842,12 @@ function syncPreinstallStateWithDisk(locationTree: LocationTree, binSymlinks: Bi
842842
const locatorLocations = new Map();
843843
let installChangedByUser = false;
844844

845-
const syncNodeWithDisk = (parentPath: PortablePath, entry: Filename, parentNode: LocationNode, refinedNode: LocationNode, nodeModulesDiskEntries: Set<Filename>) => {
845+
const syncNodeWithDisk = (parentPath: PortablePath, entry: Filename, parentNode: LocationNode, refinedNode: LocationNode, parentDiskEntries: Set<Filename>) => {
846846
let doesExistOnDisk = true;
847847
const entryPath = ppath.join(parentPath, entry);
848-
let childNodeModulesDiskEntries = new Set<Filename>();
848+
let childDiskEntries = new Set<Filename>();
849849

850-
if (entry === NODE_MODULES) {
850+
if (entry === NODE_MODULES || entry.startsWith(`@`)) {
851851
let stats;
852852
try {
853853
stats = xfs.statSync(entryPath);
@@ -860,9 +860,9 @@ function syncPreinstallStateWithDisk(locationTree: LocationTree, binSymlinks: Bi
860860
installChangedByUser = true;
861861
} else if (stats.mtimeMs > stateMtimeMs) {
862862
installChangedByUser = true;
863-
childNodeModulesDiskEntries = new Set(xfs.readdirSync(entryPath));
863+
childDiskEntries = new Set(xfs.readdirSync(entryPath));
864864
} else {
865-
childNodeModulesDiskEntries = new Set(parentNode.children.get(NODE_MODULES)!.children.keys());
865+
childDiskEntries = new Set(parentNode.children.get(entry)!.children.keys());
866866
}
867867

868868
const binarySymlinks = binSymlinks.get(parentPath);
@@ -893,7 +893,7 @@ function syncPreinstallStateWithDisk(locationTree: LocationTree, binSymlinks: Bi
893893
}
894894
}
895895
} else {
896-
doesExistOnDisk = nodeModulesDiskEntries.has(entry);
896+
doesExistOnDisk = parentDiskEntries.has(entry);
897897
}
898898

899899
const node = parentNode.children.get(entry)!;
@@ -908,7 +908,7 @@ function syncPreinstallStateWithDisk(locationTree: LocationTree, binSymlinks: Bi
908908
}
909909

910910
for (const childEntry of node.children.keys()) {
911-
syncNodeWithDisk(entryPath, childEntry, node, childRefinedNode, childNodeModulesDiskEntries);
911+
syncNodeWithDisk(entryPath, childEntry, node, childRefinedNode, childDiskEntries);
912912
}
913913
} else if (node.locator) {
914914
project.storedBuildState.delete(structUtils.parseLocator(node.locator).locatorHash);

0 commit comments

Comments
 (0)