diff --git a/common/changes/@microsoft/rush/bmiddha-resolver-cache-pnpm-10_2026-04-07-06-16.json b/common/changes/@microsoft/rush/bmiddha-resolver-cache-pnpm-10_2026-04-07-06-16.json new file mode 100644 index 00000000000..813779a5a3c --- /dev/null +++ b/common/changes/@microsoft/rush/bmiddha-resolver-cache-pnpm-10_2026-04-07-06-16.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush", + "comment": "rush-resolver-cache-plugin: add pnpm 10 / lockfile v9 compatibility", + "type": "none" + } + ], + "packageName": "@microsoft/rush" +} \ No newline at end of file diff --git a/common/config/subspaces/default/pnpm-lock.yaml b/common/config/subspaces/default/pnpm-lock.yaml index af1789b7858..3df81a5c536 100644 --- a/common/config/subspaces/default/pnpm-lock.yaml +++ b/common/config/subspaces/default/pnpm-lock.yaml @@ -5151,6 +5151,9 @@ importers: ../../../rush-plugins/rush-resolver-cache-plugin: dependencies: + '@pnpm/dependency-path': + specifier: 1000.0.9 + version: 1000.0.9 '@rushstack/rush-sdk': specifier: workspace:* version: link:../../libraries/rush-sdk diff --git a/rush-plugins/rush-resolver-cache-plugin/package.json b/rush-plugins/rush-resolver-cache-plugin/package.json index 5ed67092bde..e6d40861d87 100644 --- a/rush-plugins/rush-resolver-cache-plugin/package.json +++ b/rush-plugins/rush-resolver-cache-plugin/package.json @@ -17,6 +17,7 @@ "_phase:test": "heft run --only test -- --clean" }, "dependencies": { + "@pnpm/dependency-path": "1000.0.9", "@rushstack/rush-sdk": "workspace:*" }, "devDependencies": { diff --git a/rush-plugins/rush-resolver-cache-plugin/src/afterInstallAsync.ts b/rush-plugins/rush-resolver-cache-plugin/src/afterInstallAsync.ts index 9c675ca96b8..71e752a8260 100644 --- a/rush-plugins/rush-resolver-cache-plugin/src/afterInstallAsync.ts +++ b/rush-plugins/rush-resolver-cache-plugin/src/afterInstallAsync.ts @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. +import { existsSync, readdirSync } from 'node:fs'; + import type { RushSession, RushConfiguration, @@ -79,7 +81,12 @@ export async function afterInstallAsync( const lockFilePath: string = subspace.getCommittedShrinkwrapFilePath(variant); - const pnpmStoreDir: string = `${rushConfiguration.pnpmOptions.pnpmStorePath}/v3/files/`; + const pnpmStorePath: string = rushConfiguration.pnpmOptions.pnpmStorePath; + // pnpm 10 uses v10/index/ for index files; pnpm 8 uses v3/files/ + const pnpmStoreV10IndexDir: string = `${pnpmStorePath}/v10/index/`; + const pnpmStoreV3FilesDir: string = `${pnpmStorePath}/v3/files/`; + const useV10Store: boolean = existsSync(pnpmStoreV10IndexDir); + const pnpmStoreDir: string = useV10Store ? pnpmStoreV10IndexDir : pnpmStoreV3FilesDir; terminal.writeLine(`Using pnpm-lock from: ${lockFilePath}`); terminal.writeLine(`Using pnpm store folder: ${pnpmStoreDir}`); @@ -136,6 +143,42 @@ export async function afterInstallAsync( // Ignore } + /** + * Computes the pnpm store index file path for a given package integrity hash. + */ + function getStoreIndexPath(context: IResolverContext, hash: string): string { + if (!useV10Store) { + return `${pnpmStoreDir}${hash.slice(0, 2)}/${hash.slice(2)}-index.json`; + } + + // pnpm 10 truncates integrity hashes to 32 bytes (64 hex chars) for index paths. + const truncHash: string = hash.length > 64 ? hash.slice(0, 64) : hash; + const hashDir: string = truncHash.slice(0, 2); + const hashRest: string = truncHash.slice(2); + // pnpm 10 index path format: /-@.json + const pkgName: string = (context.name || '').replace(/\//g, '+'); + const nameVer: string = context.version ? `${pkgName}@${context.version}` : pkgName; + let indexPath: string = `${pnpmStoreDir}${hashDir}/${hashRest}-${nameVer}.json`; + // For truncated/hashed folder names, nameVer from the key may be wrong. + // Fallback: scan the directory for a file matching the hash prefix. + if (!existsSync(indexPath)) { + const dir: string = `${pnpmStoreDir}${hashDir}/`; + const filePrefix: string = `${hashRest}-`; + try { + const entries: import('node:fs').Dirent[] = readdirSync(dir, { withFileTypes: true }); + const match: import('node:fs').Dirent | undefined = entries.find( + (e) => e.isFile() && e.name.startsWith(filePrefix) + ); + if (match) { + indexPath = dir + match.name; + } + } catch { + // ignore + } + } + return indexPath; + } + async function afterExternalPackagesAsync( contexts: Map, missingOptionalDependencies: Set @@ -166,10 +209,7 @@ export async function afterInstallAsync( const prefixIndex: number = descriptionFileHash.indexOf('-'); const hash: string = Buffer.from(descriptionFileHash.slice(prefixIndex + 1), 'base64').toString('hex'); - // The pnpm store directory has index files of package contents at paths: - // /v3/files//-index.json - // See https://github.com/pnpm/pnpm/blob/f394cfccda7bc519ceee8c33fc9b68a0f4235532/store/cafs/src/getFilePathInCafs.ts#L33 - const indexPath: string = `${pnpmStoreDir}${hash.slice(0, 2)}/${hash.slice(2)}-index.json`; + const indexPath: string = getStoreIndexPath(context, hash); try { const indexContent: string = await FileSystem.readFileAsync(indexPath); diff --git a/rush-plugins/rush-resolver-cache-plugin/src/computeResolverCacheFromLockfileAsync.ts b/rush-plugins/rush-resolver-cache-plugin/src/computeResolverCacheFromLockfileAsync.ts index e0aff3acbf3..2e5eb6e1d3d 100644 --- a/rush-plugins/rush-resolver-cache-plugin/src/computeResolverCacheFromLockfileAsync.ts +++ b/rush-plugins/rush-resolver-cache-plugin/src/computeResolverCacheFromLockfileAsync.ts @@ -9,7 +9,12 @@ import type { } from '@rushstack/webpack-workspace-resolve-plugin'; import type { PnpmShrinkwrapFile } from './externals'; -import { getDescriptionFileRootFromKey, resolveDependencies, createContextSerializer } from './helpers'; +import { + getDescriptionFileRootFromKey, + resolveDependencies, + createContextSerializer, + extractNameAndVersionFromKey +} from './helpers'; import type { IResolverContext } from './types'; /** @@ -182,9 +187,12 @@ export async function computeResolverCacheFromLockfileAsync( const integrity: string | undefined = pack.resolution?.integrity; - if (!name && key.startsWith('/')) { - const versionIndex: number = key.indexOf('@', 2); - name = key.slice(1, versionIndex); + // Extract name and version from the key if not already provided + const parsed: { name: string; version: string } | undefined = extractNameAndVersionFromKey(key); + if (parsed) { + if (!name) { + name = parsed.name; + } } if (!name) { @@ -196,6 +204,7 @@ export async function computeResolverCacheFromLockfileAsync( descriptionFileHash: integrity, isProject: false, name, + version: parsed?.version, deps: new Map(), ordinal: -1, optional: pack.optional @@ -204,10 +213,10 @@ export async function computeResolverCacheFromLockfileAsync( contexts.set(descriptionFileRoot, context); if (pack.dependencies) { - resolveDependencies(workspaceRoot, pack.dependencies, context); + resolveDependencies(workspaceRoot, pack.dependencies, context, lockfile.packages); } if (pack.optionalDependencies) { - resolveDependencies(workspaceRoot, pack.optionalDependencies, context); + resolveDependencies(workspaceRoot, pack.optionalDependencies, context, lockfile.packages); } } @@ -248,13 +257,13 @@ export async function computeResolverCacheFromLockfileAsync( contexts.set(descriptionFileRoot, context); if (importer.dependencies) { - resolveDependencies(workspaceRoot, importer.dependencies, context); + resolveDependencies(workspaceRoot, importer.dependencies, context, lockfile.packages); } if (importer.devDependencies) { - resolveDependencies(workspaceRoot, importer.devDependencies, context); + resolveDependencies(workspaceRoot, importer.devDependencies, context, lockfile.packages); } if (importer.optionalDependencies) { - resolveDependencies(workspaceRoot, importer.optionalDependencies, context); + resolveDependencies(workspaceRoot, importer.optionalDependencies, context, lockfile.packages); } } diff --git a/rush-plugins/rush-resolver-cache-plugin/src/helpers.ts b/rush-plugins/rush-resolver-cache-plugin/src/helpers.ts index 99ade3da188..895e5b3ca84 100644 --- a/rush-plugins/rush-resolver-cache-plugin/src/helpers.ts +++ b/rush-plugins/rush-resolver-cache-plugin/src/helpers.ts @@ -1,58 +1,15 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { createHash } from 'node:crypto'; import * as path from 'node:path'; +import { depPathToFilename } from '@pnpm/dependency-path'; + import type { ISerializedResolveContext } from '@rushstack/webpack-workspace-resolve-plugin'; import type { IDependencyEntry, IResolverContext } from './types'; -const MAX_LENGTH_WITHOUT_HASH: number = 120 - 26 - 1; -const BASE32: string[] = 'abcdefghijklmnopqrstuvwxyz234567'.split(''); - -// https://github.com/swansontec/rfc4648.js/blob/ead9c9b4b68e5d4a529f32925da02c02984e772c/src/codec.ts#L82-L118 -export function createBase32Hash(input: string): string { - const data: Buffer = createHash('md5').update(input).digest(); - - const mask: 0x1f = 0x1f; - let out: string = ''; - - let bits: number = 0; // Number of bits currently in the buffer - let buffer: number = 0; // Bits waiting to be written out, MSB first - for (let i: number = 0; i < data.length; ++i) { - // eslint-disable-next-line no-bitwise - buffer = (buffer << 8) | (0xff & data[i]); - bits += 8; - - // Write out as much as we can: - while (bits > 5) { - bits -= 5; - // eslint-disable-next-line no-bitwise - out += BASE32[mask & (buffer >> bits)]; - } - } - - // Partial character: - if (bits) { - // eslint-disable-next-line no-bitwise - out += BASE32[mask & (buffer << (5 - bits))]; - } - - return out; -} - -// https://github.com/pnpm/pnpm/blob/f394cfccda7bc519ceee8c33fc9b68a0f4235532/packages/dependency-path/src/index.ts#L167-L189 -export function depPathToFilename(depPath: string): string { - let filename: string = depPathToFilenameUnescaped(depPath).replace(/[\\/:*?"<>|]/g, '+'); - if (filename.includes('(')) { - filename = filename.replace(/(\)\()|\(/g, '_').replace(/\)$/, ''); - } - if (filename.length > 120 || (filename !== filename.toLowerCase() && !filename.startsWith('file+'))) { - return `${filename.substring(0, MAX_LENGTH_WITHOUT_HASH)}_${createBase32Hash(filename)}`; - } - return filename; -} +const PNPM_STORE_DIR_MAX_LENGTH: number = 120; /** * Computes the root folder for a dependency from a reference to it in another package @@ -66,11 +23,10 @@ export function resolveDependencyKey( lockfileFolder: string, key: string, specifier: string, - context: IResolverContext + context: IResolverContext, + packageKeys?: { has(key: string): boolean } ): string { - if (specifier.startsWith('/')) { - return getDescriptionFileRootFromKey(lockfileFolder, specifier); - } else if (specifier.startsWith('link:')) { + if (specifier.startsWith('link:')) { if (context.isProject) { return path.posix.join(context.descriptionFileRoot, specifier.slice(5)); } else { @@ -78,8 +34,13 @@ export function resolveDependencyKey( } } else if (specifier.startsWith('file:')) { return getDescriptionFileRootFromKey(lockfileFolder, specifier, key); + } else if (packageKeys?.has(specifier)) { + // The specifier is a full package key + return getDescriptionFileRootFromKey(lockfileFolder, specifier); } else { - return getDescriptionFileRootFromKey(lockfileFolder, `/${key}@${specifier}`); + // Construct the full dependency key from package name and version specifier. + const fullKey: string = `${key}@${specifier}`; + return getDescriptionFileRootFromKey(lockfileFolder, fullKey); } } @@ -91,14 +52,15 @@ export function resolveDependencyKey( * @returns The physical path to the dependency */ export function getDescriptionFileRootFromKey(lockfileFolder: string, key: string, name?: string): string { - if (!key.startsWith('file:')) { - name = key.slice(1, key.indexOf('@', 2)); + if (!key.startsWith('file:') && !name) { + const offset: number = key.startsWith('/') ? 1 : 0; + name = key.slice(offset, key.indexOf('@', offset + 1)); } if (!name) { throw new Error(`Missing package name for ${key}`); } - const originFolder: string = `${lockfileFolder}/node_modules/.pnpm/${depPathToFilename(key)}/node_modules`; + const originFolder: string = `${lockfileFolder}/node_modules/.pnpm/${depPathToFilename(key, PNPM_STORE_DIR_MAX_LENGTH)}/node_modules`; const descriptionFileRoot: string = `${originFolder}/${name}`; return descriptionFileRoot; } @@ -106,29 +68,36 @@ export function getDescriptionFileRootFromKey(lockfileFolder: string, key: strin export function resolveDependencies( lockfileFolder: string, collection: Record, - context: IResolverContext + context: IResolverContext, + packageKeys?: { has(key: string): boolean } ): void { for (const [key, value] of Object.entries(collection)) { const version: string = typeof value === 'string' ? value : value.version; - const resolved: string = resolveDependencyKey(lockfileFolder, key, version, context); + const resolved: string = resolveDependencyKey(lockfileFolder, key, version, context, packageKeys); context.deps.set(key, resolved); } } /** - * - * @param depPath - The path to the dependency - * @returns The folder name for the dependency + * Extracts the package name and version from a lockfile package key. + * @param key - The lockfile package key (e.g. '/autoprefixer\@9.8.8', '\@scope/name\@1.0.0(peer\@2.0.0)') + * @returns The extracted name and version, or undefined for file: keys */ -export function depPathToFilenameUnescaped(depPath: string): string { - if (depPath.indexOf('file:') !== 0) { - if (depPath.startsWith('/')) { - depPath = depPath.slice(1); - } - return depPath; +export function extractNameAndVersionFromKey(key: string): { name: string; version: string } | undefined { + if (key.startsWith('file:')) { + return undefined; + } + const offset: number = key.startsWith('/') ? 1 : 0; + const versionAtIndex: number = key.indexOf('@', offset + 1); + if (versionAtIndex === -1) { + return undefined; } - return depPath.replace(':', '+'); + const name: string = key.slice(offset, versionAtIndex); + const parenIndex: number = key.indexOf('(', versionAtIndex); + const version: string = + parenIndex !== -1 ? key.slice(versionAtIndex + 1, parenIndex) : key.slice(versionAtIndex + 1); + return { name, version }; } /** diff --git a/rush-plugins/rush-resolver-cache-plugin/src/test/__snapshots__/computeResolverCacheFromLockfileAsync.test.ts.snap b/rush-plugins/rush-resolver-cache-plugin/src/test/__snapshots__/computeResolverCacheFromLockfileAsync.test.ts.snap index 401d0b21317..e1a0932ae3d 100644 --- a/rush-plugins/rush-resolver-cache-plugin/src/test/__snapshots__/computeResolverCacheFromLockfileAsync.test.ts.snap +++ b/rush-plugins/rush-resolver-cache-plugin/src/test/__snapshots__/computeResolverCacheFromLockfileAsync.test.ts.snap @@ -6609,7 +6609,7 @@ Object { "constructs": 1048, }, "name": "@aws-cdk/aws-apigatewayv2-authorizers-alpha", - "root": "common/temp/default/node_modules/.pnpm/@aws-cdk+aws-apigatewayv2-authorizers-alpha@2.50.0-alpha.0_@aws-cdk+aws-apigatewayv2-alpha@2._2zjvdar6ml6w5rggykpucquwre/node_modules/@aws-cdk/aws-apigatewayv2-authorizers-alpha", + "root": "common/temp/default/node_modules/.pnpm/@aws-cdk+aws-apigatewayv2-authorizers-alpha@2.50.0-alpha.0_@aws-cdk+aws-apigatewayv2-al_767b83692d7cf4a6fac54c8e887397fb/node_modules/@aws-cdk/aws-apigatewayv2-authorizers-alpha", }, Object { "deps": Object { @@ -6618,7 +6618,7 @@ Object { "constructs": 1048, }, "name": "@aws-cdk/aws-apigatewayv2-integrations-alpha", - "root": "common/temp/default/node_modules/.pnpm/@aws-cdk+aws-apigatewayv2-integrations-alpha@2.50.0-alpha.0_@aws-cdk+aws-apigatewayv2-alpha@2_3hg7emzhhnzrnhew65j6d7q5ca/node_modules/@aws-cdk/aws-apigatewayv2-integrations-alpha", + "root": "common/temp/default/node_modules/.pnpm/@aws-cdk+aws-apigatewayv2-integrations-alpha@2.50.0-alpha.0_@aws-cdk+aws-apigatewayv2-a_ce351ac5742febe75c59346283737abf/node_modules/@aws-cdk/aws-apigatewayv2-integrations-alpha", }, Object { "deps": Object { @@ -9039,7 +9039,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-accordion", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-accordion@9.3.46_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0_3ny3g4kjxzahs6hhtn3wibkv6q/node_modules/@fluentui/react-accordion", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-accordion@9.3.46_@types+react-dom@17.0.25_@types+react@17.0.74_react-do_b71c344d9dc9dcb3c409830a4400f894/node_modules/@fluentui/react-accordion", }, Object { "deps": Object { @@ -9058,7 +9058,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-alert", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-alert@9.0.0-beta.63_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@1_mmbfibu2ulsox3tppd6lp5wbdm/node_modules/@fluentui/react-alert", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-alert@9.0.0-beta.63_@types+react-dom@17.0.25_@types+react@17.0.74_react_4c81f6da4726ebd5bbb0e65b18bd972f/node_modules/@fluentui/react-alert", }, Object { "deps": Object { @@ -9096,7 +9096,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-avatar", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-avatar@9.6.19_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2__h75vrb2iuccv4p2nlckeeute2y/node_modules/@fluentui/react-avatar", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-avatar@9.6.19_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@1_27a426bb76185e504b4fdeb701ad22ea/node_modules/@fluentui/react-avatar", }, Object { "deps": Object { @@ -9170,7 +9170,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-checkbox", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-checkbox@9.2.17_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0._6kdnysrlrg7gdc3chketcwjram/node_modules/@fluentui/react-checkbox", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-checkbox@9.2.17_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom_3fbeb3e0d1563cf978000f0d75ed4e36/node_modules/@fluentui/react-checkbox", }, Object { "deps": Object { @@ -9194,7 +9194,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-combobox", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-combobox@9.9.3_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2_k7vu2hkzucfaym7g4rveom44pu/node_modules/@fluentui/react-combobox", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-combobox@9.9.3_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@_53a75bfe6e677dab55db85cb40821abd/node_modules/@fluentui/react-combobox", }, Object { "deps": Object { @@ -9252,7 +9252,7 @@ Object { "scheduler": 2223, }, "name": "@fluentui/react-components", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-components@9.27.4_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17._rrc4dsgm5xlhpm2l2xvbhfv7ia/node_modules/@fluentui/react-components", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-components@9.27.4_@types+react-dom@17.0.25_@types+react@17.0.74_react-d_5f3451f05354e82e8cad62dc5fbb112a/node_modules/@fluentui/react-components", }, Object { "deps": Object { @@ -9265,7 +9265,7 @@ Object { "scheduler": 2223, }, "name": "@fluentui/react-context-selector", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-context-selector@9.1.56_@types+react-dom@17.0.25_@types+react@17.0.74_react-d_wlqzfltfi3vnmsbcjghtdc44yy/node_modules/@fluentui/react-context-selector", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-context-selector@9.1.56_@types+react-dom@17.0.25_@types+react@17.0.74_r_57d085b13b99ef72e3084b02a4170958/node_modules/@fluentui/react-context-selector", }, Object { "deps": Object { @@ -9288,7 +9288,7 @@ Object { "react-transition-group": 2118, }, "name": "@fluentui/react-dialog", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-dialog@9.9.15_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2__noytcrubbkx7t4ib2lltclb64m/node_modules/@fluentui/react-dialog", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-dialog@9.9.15_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@1_373f47b6901c33b74be299faf7ee4042/node_modules/@fluentui/react-dialog", }, Object { "deps": Object { @@ -9321,7 +9321,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-drawer", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-drawer@9.0.0-beta.12_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@_uvgv6vqgvzadd73d2xfo4yq2ie/node_modules/@fluentui/react-drawer", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-drawer@9.0.0-beta.12_@types+react-dom@17.0.25_@types+react@17.0.74_reac_66a8490b60c89bf3ff2f05a03b0912cf/node_modules/@fluentui/react-drawer", }, Object { "deps": Object { @@ -9339,7 +9339,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-field", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-field@9.1.58_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2_r_7tl65itnv6wduaxb7kvdbzmaf4/node_modules/@fluentui/react-field", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-field@9.1.58_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17_1d9dfe4007037db45102ca4eef2106cf/node_modules/@fluentui/react-field", }, Object { "deps": Object { @@ -9409,7 +9409,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-infobutton", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-infobutton@9.0.0-beta.47_@types+react-dom@17.0.25_@types+react@17.0.74_react-_akgxb7tovm7amtemx5vkxfmqau/node_modules/@fluentui/react-infobutton", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-infobutton@9.0.0-beta.47_@types+react-dom@17.0.25_@types+react@17.0.74__5344e9f74ff3c8a97cc32f0a35884769/node_modules/@fluentui/react-infobutton", }, Object { "deps": Object { @@ -9426,7 +9426,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-input", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-input@9.4.68_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2_r_iazqepwia3pya3wqujvfwc4ukm/node_modules/@fluentui/react-input", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-input@9.4.68_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17_271e0b44b7a95c2476e2819b7834004c/node_modules/@fluentui/react-input", }, Object { "deps": Object { @@ -9520,7 +9520,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-overflow", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-overflow@9.1.15_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0._uycc7uxxwhw6jgermro2bjuwf4/node_modules/@fluentui/react-overflow", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-overflow@9.1.15_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom_daf1e6830761ded1a694d6006f42dd92/node_modules/@fluentui/react-overflow", }, Object { "deps": Object { @@ -9538,7 +9538,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-persona", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-persona@9.2.78_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2_gwb2xsnjxwaw2yb4y4nx7q42dy/node_modules/@fluentui/react-persona", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-persona@9.2.78_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@_b6ca28010a44cce0a61119ec15fd9356/node_modules/@fluentui/react-persona", }, Object { "deps": Object { @@ -9560,7 +9560,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-popover", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-popover@9.9.2_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2__pyflnqu5iah7662njgikihywyy/node_modules/@fluentui/react-popover", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-popover@9.9.2_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@1_f965a1d06e7ff27f4fe85adb301227fa/node_modules/@fluentui/react-popover", }, Object { "deps": Object { @@ -9619,7 +9619,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-progress", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-progress@9.1.68_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0._4ddokn6i6qzorspkjr3c2mpx6y/node_modules/@fluentui/react-progress", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-progress@9.1.68_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom_71f10c73876613f9a5d001e6190ec4e0/node_modules/@fluentui/react-progress", }, Object { "deps": Object { @@ -9657,7 +9657,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-radio", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-radio@9.2.12_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2_r_mo4hkpmyd7oumz2d6i6qdjqtwy/node_modules/@fluentui/react-radio", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-radio@9.2.12_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17_96113638025aea78f54d39c550eae425/node_modules/@fluentui/react-radio", }, Object { "deps": Object { @@ -9675,7 +9675,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-select", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-select@9.1.68_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2__k3knfgz6zpux6raexbwvyzdvwa/node_modules/@fluentui/react-select", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-select@9.1.68_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@1_58a6dccf36774a9ff17b6ac5bab0aada/node_modules/@fluentui/react-select", }, Object { "deps": Object { @@ -9702,7 +9702,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-skeleton", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-skeleton@9.0.56_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0._sfeb7yrhm2jlx4aheiz6uzqvkm/node_modules/@fluentui/react-skeleton", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-skeleton@9.0.56_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom_e25a1878ea749cf675477c45e4fbcd5f/node_modules/@fluentui/react-skeleton", }, Object { "deps": Object { @@ -9720,7 +9720,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-slider", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-slider@9.1.74_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2__got4evyigylsgol63s3tpoea2e/node_modules/@fluentui/react-slider", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-slider@9.1.74_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@1_216d81f259a68daefa27fcaf031801d9/node_modules/@fluentui/react-slider", }, Object { "deps": Object { @@ -9739,7 +9739,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-spinbutton", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-spinbutton@9.2.68_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17._54ylukac4izqz4g7veps3e77au/node_modules/@fluentui/react-spinbutton", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-spinbutton@9.2.68_@types+react-dom@17.0.25_@types+react@17.0.74_react-d_99b3278bd6bf3c4a338cc1867e5406b4/node_modules/@fluentui/react-spinbutton", }, Object { "deps": Object { @@ -9776,7 +9776,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-switch", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-switch@9.1.74_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2__bg3pcrh5kphefx5yqxdilpmufy/node_modules/@fluentui/react-switch", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-switch@9.1.74_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@1_ac087ab18e00753d54a8501c66f43426/node_modules/@fluentui/react-switch", }, Object { "deps": Object { @@ -9800,7 +9800,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-table", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-table@9.11.15_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2__4v6kpkif65ljt5aoerrbkek2ka/node_modules/@fluentui/react-table", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-table@9.11.15_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@1_4132706b27e132c2074c2d0389240754/node_modules/@fluentui/react-table", }, Object { "deps": Object { @@ -9868,7 +9868,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-textarea", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-textarea@9.3.68_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0._kzu73p535aaha7hycnv6cocfry/node_modules/@fluentui/react-textarea", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-textarea@9.3.68_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom_4e1db323ad742e7f1dbfdf78e7bc8aa8/node_modules/@fluentui/react-textarea", }, Object { "deps": Object { @@ -9919,7 +9919,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-toolbar", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-toolbar@9.1.75_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17.0.2_jmftdxha3zk5e2tghf6ehgwk5a/node_modules/@fluentui/react-toolbar", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-toolbar@9.1.75_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@_bf79a59e60f1e943a86a1ea6681a9faf/node_modules/@fluentui/react-toolbar", }, Object { "deps": Object { @@ -9965,7 +9965,7 @@ Object { "react-dom": 2099, }, "name": "@fluentui/react-tree", - "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-tree@9.0.0-beta.30_@types+react-dom@17.0.25_@types+react@17.0.74_react-dom@17_ekkwm54xwaasnfnesistyhtkhu/node_modules/@fluentui/react-tree", + "root": "common/temp/default/node_modules/.pnpm/@fluentui+react-tree@9.0.0-beta.30_@types+react-dom@17.0.25_@types+react@17.0.74_react-_c2379e1579767f7ceb9ca2d8cd1ddf2f/node_modules/@fluentui/react-tree", }, Object { "deps": Object { @@ -11442,7 +11442,7 @@ Object { "lodash": 1760, }, "name": "@rushstack/heft-jest-plugin", - "root": "common/temp/default/node_modules/.pnpm/@rushstack+heft-jest-plugin@0.11.38_@rushstack+heft@..+..+apps+heft_@types+node@18.17.15_jest_d4nwoquxsq3lena3jdncul4h6e/node_modules/@rushstack/heft-jest-plugin", + "root": "common/temp/default/node_modules/.pnpm/@rushstack+heft-jest-plugin@0.11.38_@rushstack+heft@..+..+apps+heft_@types+node@18.17.1_6b7ba8200f133ff5d0afcb8104308861/node_modules/@rushstack/heft-jest-plugin", }, Object { "deps": Object { @@ -11460,7 +11460,7 @@ Object { "lodash": 1760, }, "name": "@rushstack/heft-jest-plugin", - "root": "common/temp/default/node_modules/.pnpm/@rushstack+heft-jest-plugin@0.11.38_@rushstack+heft@0.66.17_@types+node@18.17.15_jest-environ_udyctmgs62iwhfjdgfh4tutvge/node_modules/@rushstack/heft-jest-plugin", + "root": "common/temp/default/node_modules/.pnpm/@rushstack+heft-jest-plugin@0.11.38_@rushstack+heft@0.66.17_@types+node@18.17.15_jest-e_5af72ff8d344dc65f255348b2dddc1d5/node_modules/@rushstack/heft-jest-plugin", }, Object { "deps": Object { @@ -12254,7 +12254,7 @@ Object { "webpack": 2558, }, "name": "@storybook/addon-docs", - "root": "common/temp/default/node_modules/.pnpm/@storybook+addon-docs@6.4.22_@storybook+react@6.4.22_@types+react@17.0.74_react-dom@17.0.2_re_cyh2kl4oxqqjzzvuae6ks2n4ji/node_modules/@storybook/addon-docs", + "root": "common/temp/default/node_modules/.pnpm/@storybook+addon-docs@6.4.22_@storybook+react@6.4.22_@types+react@17.0.74_react-dom@17._27e2daf1fedb051068d3de366f85f9ad/node_modules/@storybook/addon-docs", }, Object { "deps": Object { @@ -12279,7 +12279,7 @@ Object { "webpack": 2558, }, "name": "@storybook/addon-essentials", - "root": "common/temp/default/node_modules/.pnpm/@storybook+addon-essentials@6.4.22_@babel+core@7.20.12_@storybook+react@6.4.22_@types+react@1_dbhp3ql5ql4kiy4ubyky74xexq/node_modules/@storybook/addon-essentials", + "root": "common/temp/default/node_modules/.pnpm/@storybook+addon-essentials@6.4.22_@babel+core@7.20.12_@storybook+react@6.4.22_@types+r_04b8c5b92686db8c9b4e8e4e4c6540cd/node_modules/@storybook/addon-essentials", }, Object { "deps": Object { @@ -12971,7 +12971,7 @@ Object { "webpack": 2558, }, "name": "@storybook/react", - "root": "common/temp/default/node_modules/.pnpm/@storybook+react@6.4.22_@babel+core@7.20.12_@types+node@18.17.15_@types+react@17.0.74_eslint@_z6zmlpizzl5plaxmf6nthuwe34/node_modules/@storybook/react", + "root": "common/temp/default/node_modules/.pnpm/@storybook+react@6.4.22_@babel+core@7.20.12_@types+node@18.17.15_@types+react@17.0.74_e_c454de8dbcd6e438f211590f7ad1aeb0/node_modules/@storybook/react", }, Object { "deps": Object { @@ -13938,7 +13938,7 @@ Object { "typescript": 2459, }, "name": "@typescript-eslint/eslint-plugin", - "root": "common/temp/default/node_modules/.pnpm/@typescript-eslint+eslint-plugin@6.19.1_@typescript-eslint+parser@6.19.1_eslint@8.57.0_suppor_cdfp35n6xmy2avdo2soai22xhi/node_modules/@typescript-eslint/eslint-plugin", + "root": "common/temp/default/node_modules/.pnpm/@typescript-eslint+eslint-plugin@6.19.1_@typescript-eslint+parser@6.19.1_eslint@8.57.0__e1b210c04ffa5a358c3b24883ff74fff/node_modules/@typescript-eslint/eslint-plugin", }, Object { "deps": Object { @@ -24687,7 +24687,7 @@ Object { "use-sync-external-store": 2506, }, "name": "react-redux", - "root": "common/temp/default/node_modules/.pnpm/react-redux@8.0.7_@reduxjs+toolkit@1.8.6_@types+react-dom@17.0.25_@types+react@17.0.74_react-_fxbgebfgcimhtvtdsot4e7klsa/node_modules/react-redux", + "root": "common/temp/default/node_modules/.pnpm/react-redux@8.0.7_@reduxjs+toolkit@1.8.6_@types+react-dom@17.0.25_@types+react@17.0.74__fd6f85f05c0168c5ee0570fcb3a7e266/node_modules/react-redux", }, Object { "name": "react-refresh", diff --git a/rush-plugins/rush-resolver-cache-plugin/src/test/__snapshots__/helpers.test.ts.snap b/rush-plugins/rush-resolver-cache-plugin/src/test/__snapshots__/helpers.test.ts.snap index 7c4d7cb6eb6..1592d18dca9 100644 --- a/rush-plugins/rush-resolver-cache-plugin/src/test/__snapshots__/helpers.test.ts.snap +++ b/rush-plugins/rush-resolver-cache-plugin/src/test/__snapshots__/helpers.test.ts.snap @@ -1,39 +1,15 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`createBase32Hash hashes: (eslint@8.57.0)(typescript@5.4.5) 1`] = `"2nt7x5y4npubskzl4nixybkqqi"`; +exports[`getDescriptionFileRootFromKey parses : "@some/package@1.2.3(@azure/msal-browser@2.28.1)(@azure/msal-common@6.4.0)", 1`] = `"/$/node_modules/.pnpm/@some+package@1.2.3_@azure+msal-browser@2.28.1_@azure+msal-common@6.4.0/node_modules/@some/package"`; -exports[`createBase32Hash hashes: a 1`] = `"btaxlooa6g3kqmodthrgs5zgme"`; +exports[`getDescriptionFileRootFromKey parses : "@typescript-eslint/utils@6.19.1(eslint@7.7.0)(typescript@5.4.2)", 1`] = `"/$/node_modules/.pnpm/@typescript-eslint+utils@6.19.1_eslint@7.7.0_typescript@5.4.2/node_modules/@typescript-eslint/utils"`; -exports[`createBase32Hash hashes: abracadabra 1`] = `"5rjiprc7bzyoyiwvf2f4x3vwia"`; +exports[`getDescriptionFileRootFromKey parses : "autoprefixer@9.8.8", 1`] = `"/$/node_modules/.pnpm/autoprefixer@9.8.8/node_modules/autoprefixer"`; -exports[`depPathToFilename formats: /@some/package@1.2.3(@azure/msal-browser@2.28.1)(@azure/msal-common@6.4.0)(@fluentui/merge-styles@8.6.2)(@fluentui/react@8.117.5)(@fluentui/theme@2.6.45)(@fluentui/utilities@8.15.2)(chart.js@2.9.4)(lodash@4.17.21)(moment@2.29.4)(prop-types@15.8.1)(react-dnd-html5-backend@14.1.0)(react-dnd@14.0.5)(react-dom@17.0.1)(react-intersection-observer@8.34.0)(react@17.0.1) 1`] = `"@some+package@1.2.3_@azure+msal-browser@2.28.1_@azure+msal-common@6.4.0_@fluentui+merge-style_yt7yh6tpppbzu7nx3lzx3f3ife"`; +exports[`getDescriptionFileRootFromKey parses : "autoprefixer@10.4.18(postcss@8.4.36)", 1`] = `"/$/node_modules/.pnpm/autoprefixer@10.4.18_postcss@8.4.36/node_modules/autoprefixer"`; -exports[`depPathToFilename formats: /@storybook/core@6.5.15(@storybook/builder-webpack5@6.5.15)(@storybook/manager-webpack5@6.5.15)(eslint@8.57.0)(react-dom@17.0.1)(react@17.0.1)(typescript@5.3.3)(webpack@5.88.1) 1`] = `"@storybook+core@6.5.15_@storybook+builder-webpack5@6.5.15_@storybook+manager-webpack5@6.5.15__wnqw6tyxzeiksxiymflshxscdq"`; +exports[`getDescriptionFileRootFromKey parses : "file:../../../libraries/ts-command-line(@types/node@18.17.15)",@rushstack/ts-command-line 1`] = `"/$/node_modules/.pnpm/file+..+..+..+libraries+ts-command-line_@types+node@18.17.15/node_modules/@rushstack/ts-command-line"`; -exports[`depPathToFilename formats: /@typescript-eslint/utils@6.19.1(eslint@7.7.0)(typescript@5.4.2) 1`] = `"@typescript-eslint+utils@6.19.1_eslint@7.7.0_typescript@5.4.2"`; +exports[`getDescriptionFileRootFromKey parses : "file:../../../rigs/local-node-rig",local-node-rig 1`] = `"/$/node_modules/.pnpm/file+..+..+..+rigs+local-node-rig/node_modules/local-node-rig"`; -exports[`depPathToFilename formats: /autoprefixer@9.8.8 1`] = `"autoprefixer@9.8.8"`; - -exports[`depPathToFilename formats: /autoprefixer@10.4.18(postcss@8.4.36) 1`] = `"autoprefixer@10.4.18_postcss@8.4.36"`; - -exports[`depPathToFilename formats: /react-transition-group@4.4.5(react-dom@17.0.2)(react@17.0.2) 1`] = `"react-transition-group@4.4.5_react-dom@17.0.2_react@17.0.2"`; - -exports[`depPathToFilename formats: file:../../../libraries/ts-command-line(@types/node@18.17.15) 1`] = `"file+..+..+..+libraries+ts-command-line_@types+node@18.17.15"`; - -exports[`depPathToFilename formats: file:../../../rigs/local-node-rig 1`] = `"file+..+..+..+rigs+local-node-rig"`; - -exports[`getDescriptionFileRootFromKey parses: "/@some/package@1.2.3(@azure/msal-browser@2.28.1)(@azure/msal-common@6.4.0)(@fluentui/merge-styles@8.6.2)(@fluentui/react@8.117.5)(@fluentui/theme@2.6.45)(@fluentui/utilities@8.15.2)(chart.js@2.9.4)(lodash@4.17.21)(moment@2.29.4)(prop-types@15.8.1)(react-dnd-html5-backend@14.1.0)(react-dnd@14.0.5)(react-dom@17.0.1)(react-intersection-observer@8.34.0)(react@17.0.1)",undefined 1`] = `"/$/node_modules/.pnpm/@some+package@1.2.3_@azure+msal-browser@2.28.1_@azure+msal-common@6.4.0_@fluentui+merge-style_yt7yh6tpppbzu7nx3lzx3f3ife/node_modules/@some/package"`; - -exports[`getDescriptionFileRootFromKey parses: "/@storybook/core@6.5.15(@storybook/builder-webpack5@6.5.15)(@storybook/manager-webpack5@6.5.15)(eslint@8.57.0)(react-dom@17.0.1)(react@17.0.1)(typescript@5.3.3)(webpack@5.88.1)",undefined 1`] = `"/$/node_modules/.pnpm/@storybook+core@6.5.15_@storybook+builder-webpack5@6.5.15_@storybook+manager-webpack5@6.5.15__wnqw6tyxzeiksxiymflshxscdq/node_modules/@storybook/core"`; - -exports[`getDescriptionFileRootFromKey parses: "/@typescript-eslint/utils@6.19.1(eslint@7.7.0)(typescript@5.4.2)",undefined 1`] = `"/$/node_modules/.pnpm/@typescript-eslint+utils@6.19.1_eslint@7.7.0_typescript@5.4.2/node_modules/@typescript-eslint/utils"`; - -exports[`getDescriptionFileRootFromKey parses: "/autoprefixer@9.8.8",undefined 1`] = `"/$/node_modules/.pnpm/autoprefixer@9.8.8/node_modules/autoprefixer"`; - -exports[`getDescriptionFileRootFromKey parses: "/autoprefixer@10.4.18(postcss@8.4.36)",undefined 1`] = `"/$/node_modules/.pnpm/autoprefixer@10.4.18_postcss@8.4.36/node_modules/autoprefixer"`; - -exports[`getDescriptionFileRootFromKey parses: "/react-transition-group@4.4.5(react-dom@17.0.2)(react@17.0.2)",undefined 1`] = `"/$/node_modules/.pnpm/react-transition-group@4.4.5_react-dom@17.0.2_react@17.0.2/node_modules/react-transition-group"`; - -exports[`getDescriptionFileRootFromKey parses: "file:../../../libraries/ts-command-line(@types/node@18.17.15)",@rushstack/ts-command-line 1`] = `"/$/node_modules/.pnpm/file+..+..+..+libraries+ts-command-line_@types+node@18.17.15/node_modules/@rushstack/ts-command-line"`; - -exports[`getDescriptionFileRootFromKey parses: "file:../../../rigs/local-node-rig",local-node-rig 1`] = `"/$/node_modules/.pnpm/file+..+..+..+rigs+local-node-rig/node_modules/local-node-rig"`; +exports[`getDescriptionFileRootFromKey parses : "react-transition-group@4.4.5(react-dom@17.0.2)(react@17.0.2)", 1`] = `"/$/node_modules/.pnpm/react-transition-group@4.4.5_react-dom@17.0.2_react@17.0.2/node_modules/react-transition-group"`; diff --git a/rush-plugins/rush-resolver-cache-plugin/src/test/helpers.test.ts b/rush-plugins/rush-resolver-cache-plugin/src/test/helpers.test.ts index c26e3eba9b6..d153d3ed10a 100644 --- a/rush-plugins/rush-resolver-cache-plugin/src/test/helpers.test.ts +++ b/rush-plugins/rush-resolver-cache-plugin/src/test/helpers.test.ts @@ -1,54 +1,58 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { createBase32Hash, depPathToFilename, getDescriptionFileRootFromKey } from '../helpers'; - -describe(createBase32Hash.name, () => { - it('hashes', () => { - for (const input of ['a', 'abracadabra', '(eslint@8.57.0)(typescript@5.4.5)']) { - expect(createBase32Hash(input)).toMatchSnapshot(input); - } - }); -}); - -describe(depPathToFilename.name, () => { - it('formats', () => { - for (const input of [ - '/autoprefixer@9.8.8', - '/autoprefixer@10.4.18(postcss@8.4.36)', - '/react-transition-group@4.4.5(react-dom@17.0.2)(react@17.0.2)', - '/@some/package@1.2.3(@azure/msal-browser@2.28.1)(@azure/msal-common@6.4.0)(@fluentui/merge-styles@8.6.2)(@fluentui/react@8.117.5)(@fluentui/theme@2.6.45)(@fluentui/utilities@8.15.2)(chart.js@2.9.4)(lodash@4.17.21)(moment@2.29.4)(prop-types@15.8.1)(react-dnd-html5-backend@14.1.0)(react-dnd@14.0.5)(react-dom@17.0.1)(react-intersection-observer@8.34.0)(react@17.0.1)', - '/@storybook/core@6.5.15(@storybook/builder-webpack5@6.5.15)(@storybook/manager-webpack5@6.5.15)(eslint@8.57.0)(react-dom@17.0.1)(react@17.0.1)(typescript@5.3.3)(webpack@5.88.1)', - '/@typescript-eslint/utils@6.19.1(eslint@7.7.0)(typescript@5.4.2)', - 'file:../../../rigs/local-node-rig', - 'file:../../../libraries/ts-command-line(@types/node@18.17.15)' - ]) { - expect(depPathToFilename(input)).toMatchSnapshot(input); - } - }); -}); +import { getDescriptionFileRootFromKey, extractNameAndVersionFromKey } from '../helpers'; describe(getDescriptionFileRootFromKey.name, () => { - it('parses', () => { + it('parses ', () => { const lockfileRoot: string = '/$'; for (const { key, name } of [ - { key: '/autoprefixer@9.8.8' }, - { key: '/autoprefixer@10.4.18(postcss@8.4.36)' }, - { key: '/react-transition-group@4.4.5(react-dom@17.0.2)(react@17.0.2)' }, - { - key: '/@some/package@1.2.3(@azure/msal-browser@2.28.1)(@azure/msal-common@6.4.0)(@fluentui/merge-styles@8.6.2)(@fluentui/react@8.117.5)(@fluentui/theme@2.6.45)(@fluentui/utilities@8.15.2)(chart.js@2.9.4)(lodash@4.17.21)(moment@2.29.4)(prop-types@15.8.1)(react-dnd-html5-backend@14.1.0)(react-dnd@14.0.5)(react-dom@17.0.1)(react-intersection-observer@8.34.0)(react@17.0.1)' - }, + { key: 'autoprefixer@9.8.8' }, + { key: 'autoprefixer@10.4.18(postcss@8.4.36)' }, + { key: 'react-transition-group@4.4.5(react-dom@17.0.2)(react@17.0.2)' }, { - key: '/@storybook/core@6.5.15(@storybook/builder-webpack5@6.5.15)(@storybook/manager-webpack5@6.5.15)(eslint@8.57.0)(react-dom@17.0.1)(react@17.0.1)(typescript@5.3.3)(webpack@5.88.1)' + key: '@some/package@1.2.3(@azure/msal-browser@2.28.1)(@azure/msal-common@6.4.0)' }, - { key: '/@typescript-eslint/utils@6.19.1(eslint@7.7.0)(typescript@5.4.2)' }, + { key: '@typescript-eslint/utils@6.19.1(eslint@7.7.0)(typescript@5.4.2)' }, { key: 'file:../../../rigs/local-node-rig', name: 'local-node-rig' }, { key: 'file:../../../libraries/ts-command-line(@types/node@18.17.15)', name: '@rushstack/ts-command-line' } ]) { - expect(getDescriptionFileRootFromKey(lockfileRoot, key, name)).toMatchSnapshot(`"${key}",${name}`); + expect(getDescriptionFileRootFromKey(lockfileRoot, key, name)).toMatchSnapshot( + `"${key}",${name || ''}` + ); } }); }); + +describe(extractNameAndVersionFromKey.name, () => { + it('extracts name and version from', () => { + expect(extractNameAndVersionFromKey('autoprefixer@9.8.8')).toEqual({ + name: 'autoprefixer', + version: '9.8.8' + }); + expect(extractNameAndVersionFromKey('autoprefixer@10.4.18(postcss@8.4.36)')).toEqual({ + name: 'autoprefixer', + version: '10.4.18' + }); + expect(extractNameAndVersionFromKey('@some/package@1.2.3(@azure/msal-browser@2.28.1)')).toEqual({ + name: '@some/package', + version: '1.2.3' + }); + expect( + extractNameAndVersionFromKey('@typescript-eslint/utils@6.19.1(eslint@7.7.0)(typescript@5.4.2)') + ).toEqual({ + name: '@typescript-eslint/utils', + version: '6.19.1' + }); + }); + + it('returns undefined for file: keys', () => { + expect(extractNameAndVersionFromKey('file:../../../rigs/local-node-rig')).toBeUndefined(); + expect( + extractNameAndVersionFromKey('file:../../../libraries/ts-command-line(@types/node@18.17.15)') + ).toBeUndefined(); + }); +}); diff --git a/rush-plugins/rush-resolver-cache-plugin/src/types.ts b/rush-plugins/rush-resolver-cache-plugin/src/types.ts index c58938042d4..f32953fd67b 100644 --- a/rush-plugins/rush-resolver-cache-plugin/src/types.ts +++ b/rush-plugins/rush-resolver-cache-plugin/src/types.ts @@ -5,6 +5,7 @@ export interface IResolverContext { descriptionFileRoot: string; descriptionFileHash: string | undefined; name: string; + version?: string; deps: Map; isProject: boolean; ordinal: number;