Skip to content

Commit

Permalink
Merge pull request #252 from snyk/fix/fix-empty-lockfile
Browse files Browse the repository at this point in the history
fix: handle pnpm empty lockfiles
  • Loading branch information
gemaxim committed Sep 2, 2024
2 parents 5133a51 + 45d6de9 commit a5cb8b6
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 10 deletions.
8 changes: 7 additions & 1 deletion lib/dep-graph-builders/pnpm/lockfile-parser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ import { OpenSourceEcosystems } from '@snyk/error-catalog-nodejs-public';
import { NodeLockfileVersion } from '../../../utils';

export function getPnpmLockfileParser(
pnpmLockContent: string,
pnpmLockContent: string | undefined,
lockfileVersion?: NodeLockfileVersion,
workspaceArgs?: PnpmWorkspaceArgs,
): PnpmLockfileParser {
// In case of no dependencies, pnpm@7 (lokfile version 5)
// does not create a lockfile at `pnpm install`
// so if there is no lockfile content, default to lockfile version 5
if (!pnpmLockContent) {
return new LockfileV5Parser(pnpmLockContent, workspaceArgs);
}
const rawPnpmLock = load(pnpmLockContent, {
json: true,
schema: FAILSAFE_SCHEMA,
Expand Down
7 changes: 7 additions & 0 deletions lib/dep-graph-builders/pnpm/lockfile-parser/lockfile-v5.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import { PnpmWorkspaceArgs } from '../../types';

export class LockfileV5Parser extends PnpmLockfileParser {
public constructor(rawPnpmLock: any, workspaceArgs?: PnpmWorkspaceArgs) {
// In case of no dependencies, pnpm@7 (lokfile version 5)
// does not create a lockfile at `pnpm install`
if (!rawPnpmLock) {
rawPnpmLock = {
lockfileVersion: '5',
};
}
super(rawPnpmLock, workspaceArgs);
}

Expand Down
3 changes: 2 additions & 1 deletion lib/dep-graph-builders/pnpm/lockfile-parser/lockfile-v9.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export class LockfileV9Parser extends LockfileV6Parser {
super(rawPnpmLock, workspaceArgs);
this.settings = rawPnpmLock.settings;
this.packages = {};
Object.entries(rawPnpmLock.snapshots).forEach(
this.snapshots = rawPnpmLock.snapshots || {};
Object.entries(this.snapshots).forEach(
([depPath, versionData]: [string, any]) => {
const normalizedDepPath = this.excludeTransPeerDepsVersions(depPath);
this.packages[normalizedDepPath] = {
Expand Down
2 changes: 1 addition & 1 deletion lib/dep-graph-builders/pnpm/parse-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { NodeLockfileVersion } from '../../utils';

export const parsePnpmProject = async (
pkgJsonContent: string,
pnpmLockContent: string,
pnpmLockContent: string | undefined,
options: PnpmProjectParseOptions,
lockfileVersion?: NodeLockfileVersion,
): Promise<DepGraph> => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"schemaVersion": "1.3.0",
"pkgManager": {
"name": "pnpm"
},
"pkgs": [
{
"id": "[email protected]",
"info": {
"name": "empty-project",
"version": "1.0.0"
}
}
],
"graph": {
"rootNodeId": "root-node",
"nodes": [
{
"nodeId": "root-node",
"pkgId": "[email protected]",
"deps": []
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "empty-project",
"version": "1.0.0"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"schemaVersion": "1.3.0",
"pkgManager": {
"name": "pnpm"
},
"pkgs": [
{
"id": "[email protected]",
"info": {
"name": "empty-project",
"version": "1.0.0"
}
}
],
"graph": {
"rootNodeId": "root-node",
"nodes": [
{
"nodeId": "root-node",
"pkgId": "[email protected]",
"deps": []
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "empty-project",
"version": "1.0.0"
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"schemaVersion": "1.3.0",
"pkgManager": {
"name": "pnpm"
},
"pkgs": [
{
"id": "[email protected]",
"info": {
"name": "empty-project",
"version": "1.0.0"
}
}
],
"graph": {
"rootNodeId": "root-node",
"nodes": [
{
"nodeId": "root-node",
"pkgId": "[email protected]",
"deps": []
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "empty-project",
"version": "1.0.0"
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 9 additions & 7 deletions test/jest/dep-graph-builders/pnpm-lock.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { join } from 'path';
import { readFileSync } from 'fs';
import { existsSync, readFileSync } from 'fs';
import { parsePnpmProject } from '../../../lib/dep-graph-builders';
import { OpenSourceEcosystems } from '@snyk/error-catalog-nodejs-public';
import { InvalidUserInputError } from '../../../lib';
Expand All @@ -24,6 +24,7 @@ describe.each(['pnpm-lock-v5', 'pnpm-lock-v6', 'pnpm-lock-v9'])(
'npm-protocol',
'scoped-override',
'alias-sub-dependency',
'empty-project',
])('[simple tests] project: %s ', (fixtureName) => {
jest.setTimeout(50 * 1000);
it('matches expected', async () => {
Expand All @@ -34,13 +35,14 @@ describe.each(['pnpm-lock-v5', 'pnpm-lock-v6', 'pnpm-lock-v9'])(
),
'utf8',
);
const pkgLockContent = readFileSync(
join(
__dirname,
`./fixtures/${lockFileVersionPath}/${fixtureName}/pnpm-lock.yaml`,
),
'utf8',
const lockfilePath = join(
__dirname,
`./fixtures/${lockFileVersionPath}/${fixtureName}/pnpm-lock.yaml`,
);
let pkgLockContent: string | undefined = undefined;
if (existsSync(lockfilePath)) {
pkgLockContent = readFileSync(lockfilePath, 'utf8');
}

const newDepGraph = await parsePnpmProject(
pkgJsonContent,
Expand Down

0 comments on commit a5cb8b6

Please sign in to comment.