Skip to content

Commit 190358b

Browse files
bmiddhaCopilot
andauthored
Address code review feedback
- afterInstallAsync: switch/case with throw on unsupported pnpm versions - computeResolverCacheFromLockfileAsync: hoist backslash regex, use name ||= parsed.name, destructure lockfile.packages - helpers: flatten resolveDependencyKey link: branches into ternary, simplify package key resolution to single getDescriptionFileRootFromKey call - pnpm/index.ts: move types and factory to pnpmVersionHelpers.ts, index.ts now only re-exports - pnpm/v8,v9,v10: import from ./pnpmVersionHelpers instead of . - pnpm/store/v10: add Dirent to import, hoist scope separator regex Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8fb0940 commit 190358b

9 files changed

Lines changed: 53 additions & 40 deletions

File tree

rush-plugins/rush-resolver-cache-plugin/src/afterInstallAsync.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ import {
1616
computeResolverCacheFromLockfileAsync,
1717
type IPlatformInfo
1818
} from './computeResolverCacheFromLockfileAsync';
19-
import { type PnpmMajorVersion, type IPnpmVersionHelpers, getPnpmVersionHelpersAsync } from './pnpm';
19+
import {
20+
type PnpmMajorVersion,
21+
type IPnpmVersionHelpers,
22+
getPnpmVersionHelpersAsync
23+
} from './pnpm/pnpmVersionHelpers';
2024
import type { IResolverContext } from './types';
2125

2226
/**
@@ -84,10 +88,17 @@ export async function afterInstallAsync(
8488

8589
const pnpmMajorVersion: PnpmMajorVersion = (() => {
8690
const major: number = parseInt(rushConfiguration.packageManagerToolVersion, 10);
87-
if (major >= 10) return 10;
88-
if (major >= 9) return 9;
89-
return 8;
90-
})() as PnpmMajorVersion;
91+
switch (major) {
92+
case 10:
93+
return 10;
94+
case 9:
95+
return 9;
96+
case 8:
97+
return 8;
98+
default:
99+
throw new Error(`Unsupported pnpm major version: ${major}`);
100+
}
101+
})();
91102

92103
const pnpmHelpers: IPnpmVersionHelpers = await getPnpmVersionHelpersAsync(pnpmMajorVersion);
93104

rush-plugins/rush-resolver-cache-plugin/src/computeResolverCacheFromLockfileAsync.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ import {
1515
createContextSerializer,
1616
extractNameAndVersionFromKey
1717
} from './helpers';
18-
import { type PnpmMajorVersion, type IPnpmVersionHelpers, getPnpmVersionHelpersAsync } from './pnpm';
18+
import {
19+
type PnpmMajorVersion,
20+
type IPnpmVersionHelpers,
21+
getPnpmVersionHelpersAsync
22+
} from './pnpm/pnpmVersionHelpers';
1923
import type { IResolverContext } from './types';
2024

2125
/**
@@ -112,7 +116,7 @@ function extractBundledDependencies(
112116
}
113117

114118
// Re-export for downstream consumers
115-
export type { PnpmMajorVersion, IPnpmVersionHelpers } from './pnpm';
119+
export type { PnpmMajorVersion, IPnpmVersionHelpers } from './pnpm/pnpmVersionHelpers';
116120

117121
/**
118122
* Options for computing the resolver cache from a lockfile.
@@ -157,13 +161,15 @@ export interface IComputeResolverCacheFromLockfileOptions {
157161
) => Promise<void>;
158162
}
159163

164+
const BACKSLASH_REGEX: RegExp = /\\/g;
165+
160166
/**
161167
* Copied from `@rushstack/node-core-library/src/Path.ts` to avoid expensive dependency
162168
* @param path - Path using backslashes as path separators
163169
* @returns The same string using forward slashes as path separators
164170
*/
165171
function convertToSlashes(path: string): string {
166-
return path.replace(/\\/g, '/');
172+
return path.replace(BACKSLASH_REGEX, '/');
167173
}
168174

169175
/**
@@ -183,12 +189,12 @@ export async function computeResolverCacheFromLockfileAsync(
183189
const contexts: Map<string, IResolverContext> = new Map();
184190
const missingOptionalDependencies: Set<string> = new Set();
185191

186-
const pnpmVersion: PnpmMajorVersion = params.pnpmVersion;
192+
const helpers: IPnpmVersionHelpers = await getPnpmVersionHelpersAsync(params.pnpmVersion);
187193

188-
const helpers: IPnpmVersionHelpers = await getPnpmVersionHelpersAsync(pnpmVersion);
194+
const { packages } = lockfile;
189195

190196
// Enumerate external dependencies first, to simplify looping over them for store data
191-
for (const [key, pack] of lockfile.packages) {
197+
for (const [key, pack] of packages) {
192198
let name: string | undefined = pack.name;
193199
const descriptionFileRoot: string = getDescriptionFileRootFromKey(
194200
workspaceRoot,
@@ -208,9 +214,7 @@ export async function computeResolverCacheFromLockfileAsync(
208214
// Extract name and version from the key if not already provided
209215
const parsed: { name: string; version: string } | undefined = extractNameAndVersionFromKey(key);
210216
if (parsed) {
211-
if (!name) {
212-
name = parsed.name;
213-
}
217+
name ||= parsed.name;
214218
}
215219

216220
if (!name) {
@@ -231,10 +235,10 @@ export async function computeResolverCacheFromLockfileAsync(
231235
contexts.set(descriptionFileRoot, context);
232236

233237
if (pack.dependencies) {
234-
resolveDependencies(workspaceRoot, pack.dependencies, context, helpers, lockfile.packages);
238+
resolveDependencies(workspaceRoot, pack.dependencies, context, helpers, packages);
235239
}
236240
if (pack.optionalDependencies) {
237-
resolveDependencies(workspaceRoot, pack.optionalDependencies, context, helpers, lockfile.packages);
241+
resolveDependencies(workspaceRoot, pack.optionalDependencies, context, helpers, packages);
238242
}
239243
}
240244

@@ -275,13 +279,13 @@ export async function computeResolverCacheFromLockfileAsync(
275279
contexts.set(descriptionFileRoot, context);
276280

277281
if (importer.dependencies) {
278-
resolveDependencies(workspaceRoot, importer.dependencies, context, helpers, lockfile.packages);
282+
resolveDependencies(workspaceRoot, importer.dependencies, context, helpers, packages);
279283
}
280284
if (importer.devDependencies) {
281-
resolveDependencies(workspaceRoot, importer.devDependencies, context, helpers, lockfile.packages);
285+
resolveDependencies(workspaceRoot, importer.devDependencies, context, helpers, packages);
282286
}
283287
if (importer.optionalDependencies) {
284-
resolveDependencies(workspaceRoot, importer.optionalDependencies, context, helpers, lockfile.packages);
288+
resolveDependencies(workspaceRoot, importer.optionalDependencies, context, helpers, packages);
285289
}
286290
}
287291

rush-plugins/rush-resolver-cache-plugin/src/helpers.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as path from 'node:path';
66
import type { ISerializedResolveContext } from '@rushstack/webpack-workspace-resolve-plugin';
77

88
import type { IDependencyEntry, IResolverContext } from './types';
9-
import type { IPnpmVersionHelpers } from './pnpm';
9+
import type { IPnpmVersionHelpers } from './pnpm/pnpmVersionHelpers';
1010

1111
/**
1212
* Computes the root folder for a dependency from a reference to it in another package
@@ -26,19 +26,17 @@ export function resolveDependencyKey(
2626
packageKeys?: { has(key: string): boolean }
2727
): string {
2828
if (specifier.startsWith('link:')) {
29-
if (context.isProject) {
30-
return path.posix.join(context.descriptionFileRoot, specifier.slice(5));
31-
} else {
32-
return path.posix.join(lockfileFolder, specifier.slice(5));
33-
}
29+
return path.posix.join(
30+
context.isProject ? context.descriptionFileRoot : lockfileFolder,
31+
specifier.slice(5)
32+
);
3433
} else if (specifier.startsWith('file:')) {
3534
return getDescriptionFileRootFromKey(lockfileFolder, specifier, helpers.depPathToFilename, key);
36-
} else if (packageKeys?.has(specifier)) {
37-
// The specifier is a full package key (v6: '/pkg@ver', v9: 'pkg@ver')
38-
return getDescriptionFileRootFromKey(lockfileFolder, specifier, helpers.depPathToFilename);
3935
} else {
40-
const fullKey: string = helpers.buildDependencyKey(key, specifier);
41-
return getDescriptionFileRootFromKey(lockfileFolder, fullKey, helpers.depPathToFilename);
36+
const resolvedKey: string = packageKeys?.has(specifier)
37+
? specifier
38+
: helpers.buildDependencyKey(key, specifier);
39+
return getDescriptionFileRootFromKey(lockfileFolder, resolvedKey, helpers.depPathToFilename);
4240
}
4341
}
4442

rush-plugins/rush-resolver-cache-plugin/src/pnpm/index.ts renamed to rush-plugins/rush-resolver-cache-plugin/src/pnpm/pnpmVersionHelpers.ts

File renamed without changes.

rush-plugins/rush-resolver-cache-plugin/src/pnpm/store/v10.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@
55
// {storeDir}/v10/index/{hash[0:2]}/{hash[2:64]}-{name}@{version}.json
66
// Falls back to directory scan when the primary path doesn't exist.
77

8-
import { existsSync, readdirSync } from 'node:fs';
8+
import { type Dirent, existsSync, readdirSync } from 'node:fs';
99

1010
import type { IResolverContext } from '../../types';
1111

12+
const SCOPE_SEPARATOR_REGEX: RegExp = /\//g;
13+
1214
export function getStoreIndexPath(pnpmStorePath: string, context: IResolverContext, hash: string): string {
1315
// pnpm 10 truncates integrity hashes to 32 bytes (64 hex chars) for index paths.
1416
const truncHash: string = hash.length > 64 ? hash.slice(0, 64) : hash;
1517
const hashDir: string = truncHash.slice(0, 2);
1618
const hashRest: string = truncHash.slice(2);
1719
// pnpm 10 index path format: <hash (0-2)>/<hash (2-64)>-<name>@<version>.json
18-
const pkgName: string = (context.name || '').replace(/\//g, '+');
20+
const pkgName: string = (context.name || '').replace(SCOPE_SEPARATOR_REGEX, '+');
1921
const nameVer: string = context.version ? `${pkgName}@${context.version}` : pkgName;
2022
let indexPath: string = `${pnpmStorePath}/v10/index/${hashDir}/${hashRest}-${nameVer}.json`;
2123
// For truncated/hashed folder names, nameVer from the key may be wrong.
@@ -24,10 +26,8 @@ export function getStoreIndexPath(pnpmStorePath: string, context: IResolverConte
2426
const dir: string = `${pnpmStorePath}/v10/index/${hashDir}/`;
2527
const filePrefix: string = `${hashRest}-`;
2628
try {
27-
const entries: import('node:fs').Dirent[] = readdirSync(dir, { withFileTypes: true });
28-
const match: import('node:fs').Dirent | undefined = entries.find(
29-
(e) => e.isFile() && e.name.startsWith(filePrefix)
30-
);
29+
const entries: Dirent[] = readdirSync(dir, { withFileTypes: true });
30+
const match: Dirent | undefined = entries.find((e) => e.isFile() && e.name.startsWith(filePrefix));
3131
if (match) {
3232
indexPath = dir + match.name;
3333
}

rush-plugins/rush-resolver-cache-plugin/src/pnpm/v10.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
// pnpm 10: lockfile v9 (keys have no leading '/'), store v10, SHA-256 hex hash
55

6-
import type { IPnpmVersionHelpers } from '.';
6+
import type { IPnpmVersionHelpers } from './pnpmVersionHelpers';
77
import { depPathToFilename } from './depPath/v10';
88
import { buildDependencyKey } from './keys/v9';
99
import { getStoreIndexPath } from './store/v10';

rush-plugins/rush-resolver-cache-plugin/src/pnpm/v8.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
// pnpm 8: lockfile v6 (keys start with '/'), store v3, MD5 base32 hash
55

6-
import type { IPnpmVersionHelpers } from '.';
6+
import type { IPnpmVersionHelpers } from './pnpmVersionHelpers';
77
import { depPathToFilename } from './depPath/v8';
88
import { buildDependencyKey } from './keys/v6';
99
import { getStoreIndexPath } from './store/v3';

rush-plugins/rush-resolver-cache-plugin/src/pnpm/v9.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
// pnpm 9: lockfile v9 (keys have no leading '/'), store v3, MD5 base32 hash
55

6-
import type { IPnpmVersionHelpers } from '.';
6+
import type { IPnpmVersionHelpers } from './pnpmVersionHelpers';
77
// pnpm 9 uses the same dep-path hashing algorithm as pnpm 8 (MD5 base32)
88
// but a different depPathToFilenameUnescaped (indexOf('@') vs lastIndexOf('/'))
99
import { depPathToFilename } from './depPath/v9';

rush-plugins/rush-resolver-cache-plugin/src/test/helpers.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
import { helpers as v8Helpers } from '../pnpm/v8';
1414
import { helpers as v9Helpers } from '../pnpm/v9';
1515
import { helpers as v10Helpers } from '../pnpm/v10';
16-
import { getPnpmVersionHelpersAsync, type IPnpmVersionHelpers } from '../pnpm';
16+
import { getPnpmVersionHelpersAsync, type IPnpmVersionHelpers } from '../pnpm/pnpmVersionHelpers';
1717
import type { IResolverContext } from '../types';
1818

1919
describe(createBase32Hash.name, () => {

0 commit comments

Comments
 (0)