Skip to content

Commit

Permalink
fix(core): ensure correct package name matching when parsing pnpm loc…
Browse files Browse the repository at this point in the history
…k file (#17613)
  • Loading branch information
meeroslav authored Jun 21, 2023
1 parent e01df1c commit 53a37d4
Showing 1 changed file with 53 additions and 39 deletions.
92 changes: 53 additions & 39 deletions packages/nx/src/plugins/js/lock-file/pnpm-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
ProjectGraph,
ProjectGraphExternalNode,
} from '../../../config/project-graph';
import { fileHasher, hashArray } from '../../../hasher/file-hasher';
import { hashArray } from '../../../hasher/file-hasher';

export function parsePnpmLockfile(
lockFileContent: string,
Expand All @@ -43,39 +43,40 @@ function addNodes(
const nodes: Map<string, Map<string, ProjectGraphExternalNode>> = new Map();

Object.entries(data.packages).forEach(([key, snapshot]) => {
const packageName = findPackageName(key, snapshot, data);
const rawVersion = findVersion(key, packageName);
const version = parseBaseVersion(rawVersion, isV6);

// we don't need to keep duplicates, we can just track the keys
const existingNode = nodes.get(packageName)?.get(version);
if (existingNode) {
keyMap.set(key, existingNode);
return;
}
findPackageNames(key, snapshot, data).forEach((packageName) => {
const rawVersion = findVersion(key, packageName);
const version = parseBaseVersion(rawVersion, isV6);

// we don't need to keep duplicates, we can just track the keys
const existingNode = nodes.get(packageName)?.get(version);
if (existingNode) {
keyMap.set(key, existingNode);
return;
}

const node: ProjectGraphExternalNode = {
type: 'npm',
name: version ? `npm:${packageName}@${version}` : `npm:${packageName}`,
data: {
version,
packageName,
hash:
snapshot.resolution?.['integrity'] ||
hashArray(
snapshot.resolution?.['tarball']
? [snapshot.resolution['tarball']]
: [packageName, version]
),
},
};

keyMap.set(key, node);
if (!nodes.has(packageName)) {
nodes.set(packageName, new Map([[version, node]]));
} else {
nodes.get(packageName).set(version, node);
}
const node: ProjectGraphExternalNode = {
type: 'npm',
name: version ? `npm:${packageName}@${version}` : `npm:${packageName}`,
data: {
version,
packageName,
hash:
snapshot.resolution?.['integrity'] ||
hashArray(
snapshot.resolution?.['tarball']
? [snapshot.resolution['tarball']]
: [packageName, version]
),
},
};

keyMap.set(key, node);
if (!nodes.has(packageName)) {
nodes.set(packageName, new Map([[version, node]]));
} else {
nodes.get(packageName).set(version, node);
}
});
});

const hoistedDeps = loadPnpmHoistedDepsDefinition();
Expand Down Expand Up @@ -280,11 +281,14 @@ function findVersion(key: string, packageName: string): string {
return key;
}

function findPackageName(
function findPackageNames(
key: string,
snapshot: PackageSnapshot,
data: Lockfile
): string {
): string[] {
const packageNames = new Set<string>();
const originalPackageName = extractNameFromKey(key);

const matchPropValue = (record: Record<string, string>): string => {
if (!record) {
return undefined;
Expand All @@ -293,6 +297,13 @@ function findPackageName(
if (index > -1) {
return Object.keys(record)[index];
}
// check if non aliased name is found
if (
record[originalPackageName] &&
key.startsWith(`/${originalPackageName}/${record[originalPackageName]}`)
) {
return originalPackageName;
}
};

const matchedDependencyName = (
Expand All @@ -307,25 +318,28 @@ function findPackageName(

// snapshot already has a name
if (snapshot.name) {
return snapshot.name;
packageNames.add(snapshot.name);
}
// it'a a root dependency
const rootDependencyName =
matchedDependencyName(data.importers['.']) ||
// only root importers have devDependencies
matchPropValue(data.importers['.'].devDependencies);
if (rootDependencyName) {
return rootDependencyName;
packageNames.add(rootDependencyName);
}
// find a snapshot that has a dependency that points to this snapshot
const snapshots = Object.values(data.packages);
for (let i = 0; i < snapshots.length; i++) {
const dependencyName = matchedDependencyName(snapshots[i]);
if (dependencyName) {
return dependencyName;
packageNames.add(dependencyName);
}
}
return extractNameFromKey(key);
if (packageNames.size === 0) {
packageNames.add(originalPackageName);
}
return Array.from(packageNames);
}

function getVersion(key: string, packageName: string): string {
Expand Down

1 comment on commit 53a37d4

@vercel
Copy link

@vercel vercel bot commented on 53a37d4 Jun 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-nrwl.vercel.app
nx-dev-git-master-nrwl.vercel.app
nx-five.vercel.app
nx.dev

Please sign in to comment.