Skip to content

Commit 0c68f7f

Browse files
authored
Merge pull request #258 from snyk/fix/OSM-2329/handle-peer-deps-in-dep-path
fix: [OSM-2329] handle peers deps in dep path for git protocol deps
2 parents 9ff8fc9 + 2ccc03f commit 0c68f7f

File tree

14 files changed

+4034
-25
lines changed

14 files changed

+4034
-25
lines changed

lib/dep-graph-builders/pnpm/lockfile-parser/lockfile-parser.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ export abstract class PnpmLockfileParser {
5050
// name and version are optional in version data - if they don't show up in version data, they can be deducted from the dependency path
5151
const { name, version } = versionData;
5252
let parsedPath: ParsedDepPath = {};
53+
54+
// Exclude transitive peer deps from depPath
55+
56+
depPath = this.excludeTransPeerDepsVersions(depPath);
57+
5358
if (!(version && name)) {
5459
parsedPath = this.parseDepPath(depPath);
5560
}
@@ -123,7 +128,7 @@ export abstract class PnpmLockfileParser {
123128
] as PnpmProject;
124129
this.extractedPackages[`${name}@${version}`] = {
125130
id: `${name}@${version}`,
126-
name: version,
131+
name: name,
127132
version: version,
128133
dependencies: this.topLevelDepsToNormalizedPkgs(prodDeps),
129134
devDependencies: this.topLevelDepsToNormalizedPkgs(devDeps),

lib/dep-graph-builders/pnpm/lockfile-parser/lockfile-v5.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,17 @@ export class LockfileV5Parser extends PnpmLockfileParser {
6969
// '/@babel/preset-typescript/7.12.13_@[email protected]'
7070
// https://github.com/pnpm/spec/blob/master/dependency-path.md
7171
public excludeTransPeerDepsVersions(fullVersionStr: string): string {
72-
return fullVersionStr.split('_')[0];
72+
if (!fullVersionStr.includes('/')) {
73+
return fullVersionStr.split('_')[0];
74+
}
75+
// When dealing with dependency paths, the dependency name can include '_'
76+
// so we need to make sure the '_' we split by is after '/'
77+
const splitSlashes = fullVersionStr.split('/');
78+
const stringAfterLastSlash = splitSlashes[splitSlashes.length - 1];
79+
const stringBeforeLastSlash = fullVersionStr.split(stringAfterLastSlash)[0];
80+
const stringBetweenLastSlashAndUnderscore =
81+
stringAfterLastSlash.split('_')[0];
82+
return `${stringBeforeLastSlash}${stringBetweenLastSlashAndUnderscore}`;
7383
}
7484

7585
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types

lib/dep-graph-builders/pnpm/lockfile-parser/lockfile-v6.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,31 @@ export class LockfileV6Parser extends PnpmLockfileParser {
1111
}
1212

1313
public parseDepPath(depPath: string): ParsedDepPath {
14-
// Exclude transitive peer deps from depPath
15-
16-
depPath = this.excludeTransPeerDepsVersions(depPath);
17-
1814
// Check if path is absolute (doesn't start with '/')
1915
// If it's not absolute, omit first '/'
2016
depPath = LockfileV6Parser.isAbsoluteDepenencyPath(depPath)
2117
? depPath
2218
: depPath.substring(1);
2319

24-
// Next, get version based on the last occurence of '@' separator
25-
// e.g. @babel/[email protected] -> name: @babel/code-frame and version: 7.24.2
26-
const sepIndex = depPath.lastIndexOf('@');
27-
if (sepIndex === -1) {
28-
return {};
20+
// This is the case for scoped packages, get version based on the last occurence of '@' separator
21+
// to include the '@' in the name
22+
if (depPath.startsWith('@')) {
23+
// e.g. @babel/[email protected] -> name: @babel/code-frame and version: 7.24.2
24+
const sepIndex = depPath.lastIndexOf('@');
25+
if (sepIndex === -1) {
26+
return {};
27+
}
28+
const name = depPath.substring(0, sepIndex);
29+
const version = depPath.substring(sepIndex + 1);
30+
return {
31+
name,
32+
version,
33+
};
2934
}
30-
const name = depPath.substring(0, sepIndex);
31-
const version = depPath.substring(sepIndex + 1);
35+
36+
// For non-scoped packages, the dependency specifier should contain only
37+
// one '@', separating the name and version
38+
const [name, version] = depPath.split('@');
3239
return {
3340
name,
3441
version,

lib/dep-graph-builders/pnpm/utils.ts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { LockfileType } from '../..';
44
import { getGraphDependencies } from '../util';
55
import { PnpmLockfileParser } from './lockfile-parser/lockfile-parser';
66
import { NormalisedPnpmPkgs, PnpmNode } from './types';
7-
import { valid } from 'semver';
87
import { OpenSourceEcosystems } from '@snyk/error-catalog-nodejs-public';
98
import {
109
INSTALL_COMMAND,
@@ -23,18 +22,14 @@ export const getPnpmChildNode = (
2322
includeDevDeps: boolean,
2423
lockfileParser: PnpmLockfileParser,
2524
): PnpmNode => {
26-
let resolvedVersion =
27-
valid(depInfo.version) || depInfo.version === undefined
28-
? depInfo.version
29-
: lockfileParser.excludeTransPeerDepsVersions(depInfo.version);
25+
const resolvedVersion = lockfileParser.excludeTransPeerDepsVersions(
26+
depInfo.version,
27+
);
3028
let childNodeKey = `${name}@${resolvedVersion}`;
3129
// For aliases, the version is the dependency path that
3230
// shows up in the packages section of lockfiles
33-
if (lockfileParser.resolvedPackages[depInfo.version]) {
34-
childNodeKey = lockfileParser.resolvedPackages[depInfo.version];
35-
const pkgData = pkgs[childNodeKey];
36-
name = pkgData.name;
37-
resolvedVersion = pkgData.version;
31+
if (lockfileParser.resolvedPackages[resolvedVersion]) {
32+
childNodeKey = lockfileParser.resolvedPackages[resolvedVersion];
3833
}
3934
if (!pkgs[childNodeKey]) {
4035
if (strictOutOfSync && !/^file:/.test(depInfo.version)) {
@@ -70,8 +65,8 @@ export const getPnpmChildNode = (
7065
? getGraphDependencies(depData.optionalDependencies || {}, depInfo.isDev)
7166
: {};
7267
return {
73-
id: `${name}@${depData.version}`,
74-
name: name,
68+
id: `${depData.name}@${depData.version}`,
69+
name: depData.name,
7570
version: depData.version || UNDEFINED_VERSION,
7671
dependencies: {
7772
...dependencies,

0 commit comments

Comments
 (0)