fix(audit): project versions (#5661)

This commit is contained in:
Zoltan Kochan
2022-11-20 04:35:27 +02:00
committed by GitHub
parent c216a4ed76
commit 3801d2fa29
10 changed files with 62 additions and 21 deletions

View File

@@ -0,0 +1,5 @@
---
"pnpm": patch
---
`pnpm audit` should send the versions of workspace projects for audit.

View File

@@ -0,0 +1,5 @@
---
"@pnpm/audit": major
---
New required option added: lockfileDir.

View File

@@ -33,6 +33,7 @@
"@pnpm/audit": "workspace:*",
"@pnpm/constants": "workspace:*",
"@pnpm/lockfile-file": "workspace:*",
"@pnpm/test-fixtures": "workspace:*",
"@types/ramda": "0.28.15",
"nock": "13.2.9"
},
@@ -43,6 +44,7 @@
"@pnpm/lockfile-types": "workspace:*",
"@pnpm/lockfile-utils": "workspace:*",
"@pnpm/lockfile-walker": "workspace:*",
"@pnpm/read-project-manifest": "workspace:*",
"@pnpm/types": "workspace:*",
"ramda": "npm:@pnpm/ramda@0.28.1"
},

View File

@@ -14,12 +14,13 @@ export async function audit (
opts: {
agentOptions?: AgentOptions
include?: { [dependenciesField in DependenciesField]: boolean }
lockfileDir: string
registry: string
retry?: RetryTimeoutOptions
timeout?: number
}
) {
const auditTree = lockfileToAuditTree(lockfile, { include: opts.include })
const auditTree = await lockfileToAuditTree(lockfile, { include: opts.include, lockfileDir: opts.lockfileDir })
const registry = opts.registry.endsWith('/') ? opts.registry : `${opts.registry}/`
const auditUrl = `${registry}-/npm/v1/security/audits`
const authHeaderValue = getAuthHeader(registry)

View File

@@ -1,7 +1,9 @@
import path from 'path'
import { Lockfile } from '@pnpm/lockfile-types'
import { nameVerFromPkgSnapshot } from '@pnpm/lockfile-utils'
import { lockfileWalkerGroupImporterSteps, LockfileWalkerStep } from '@pnpm/lockfile-walker'
import { DependenciesField } from '@pnpm/types'
import { readProjectManifest } from '@pnpm/read-project-manifest'
import mapValues from 'ramda/src/map'
export interface AuditNode {
@@ -19,25 +21,29 @@ export type AuditTree = AuditNode & {
metadata: Object
}
export function lockfileToAuditTree (
export async function lockfileToAuditTree (
lockfile: Lockfile,
opts?: {
opts: {
include?: { [dependenciesField in DependenciesField]: boolean }
lockfileDir: string
}
): AuditTree {
): Promise<AuditTree> {
const importerWalkers = lockfileWalkerGroupImporterSteps(lockfile, Object.keys(lockfile.importers), { include: opts?.include })
const dependencies = {}
importerWalkers.forEach((importerWalker) => {
const importerDeps = lockfileToAuditNode(importerWalker.step)
// For some reason the registry responds with 500 if the keys in dependencies have slashes
// see issue: https://github.com/pnpm/pnpm/issues/2848
const depName = importerWalker.importerId.replace(/\//g, '__')
dependencies[depName] = {
dependencies: importerDeps,
requires: toRequires(importerDeps),
version: '0.0.0',
}
})
await Promise.all(
importerWalkers.map(async (importerWalker) => {
const importerDeps = lockfileToAuditNode(importerWalker.step)
// For some reason the registry responds with 500 if the keys in dependencies have slashes
// see issue: https://github.com/pnpm/pnpm/issues/2848
const depName = importerWalker.importerId.replace(/\//g, '__')
const { manifest } = await readProjectManifest(path.join(opts.lockfileDir, importerWalker.importerId))
dependencies[depName] = {
dependencies: importerDeps,
requires: toRequires(importerDeps),
version: manifest.version,
}
})
)
const auditTree: AuditTree = {
name: undefined,
version: undefined,

View File

@@ -0,0 +1,4 @@
{
"name": "pkg",
"version": "1.0.0"
}

View File

@@ -1,12 +1,15 @@
import { audit } from '@pnpm/audit'
import { LOCKFILE_VERSION } from '@pnpm/constants'
import { PnpmError } from '@pnpm/error'
import { fixtures } from '@pnpm/test-fixtures'
import nock from 'nock'
import { lockfileToAuditTree } from '../lib/lockfileToAuditTree'
const f = fixtures(__dirname)
describe('audit', () => {
test('lockfileToAuditTree()', () => {
expect(lockfileToAuditTree({
test('lockfileToAuditTree()', async () => {
expect(await lockfileToAuditTree({
importers: {
'.': {
dependencies: {
@@ -33,7 +36,7 @@ describe('audit', () => {
},
},
},
})).toEqual({
}, { lockfileDir: f.find('one-project') })).toEqual({
name: undefined,
version: undefined,
@@ -59,7 +62,7 @@ describe('audit', () => {
requires: {
foo: '1.0.0',
},
version: '0.0.0',
version: '1.0.0',
},
},
dev: false,
@@ -67,7 +70,7 @@ describe('audit', () => {
integrity: undefined,
metadata: {},
remove: [],
requires: { '.': '0.0.0' },
requires: { '.': '1.0.0' },
})
})
@@ -88,6 +91,7 @@ describe('audit', () => {
},
getAuthHeader,
{
lockfileDir: f.find('one-project'),
registry,
retry: {
retries: 0,

View File

@@ -9,6 +9,9 @@
"../../__typings__/**/*.d.ts"
],
"references": [
{
"path": "../../__utils__/test-fixtures"
},
{
"path": "../../network/fetch"
},
@@ -24,6 +27,9 @@
{
"path": "../../packages/types"
},
{
"path": "../../pkg-manifest/read-project-manifest"
},
{
"path": "../lockfile-file"
},

View File

@@ -130,7 +130,8 @@ export async function handler (
| 'rootProjectManifest'
>
) {
const lockfile = await readWantedLockfile(opts.lockfileDir ?? opts.dir, { ignoreIncompatible: true })
const lockfileDir = opts.lockfileDir ?? opts.dir
const lockfile = await readWantedLockfile(lockfileDir, { ignoreIncompatible: true })
if (lockfile == null) {
throw new PnpmError('AUDIT_NO_LOCKFILE', `No ${WANTED_LOCKFILE} found: Cannot audit a project without a lockfile`)
}
@@ -156,6 +157,7 @@ export async function handler (
timeout: opts.fetchTimeout,
},
include,
lockfileDir,
registry: opts.registries.default,
retry: {
factor: opts.fetchRetryFactor,

6
pnpm-lock.yaml generated
View File

@@ -1576,6 +1576,9 @@ importers:
'@pnpm/lockfile-walker':
specifier: workspace:*
version: link:../lockfile-walker
'@pnpm/read-project-manifest':
specifier: workspace:*
version: link:../../pkg-manifest/read-project-manifest
'@pnpm/types':
specifier: workspace:*
version: link:../../packages/types
@@ -1592,6 +1595,9 @@ importers:
'@pnpm/lockfile-file':
specifier: workspace:*
version: link:../lockfile-file
'@pnpm/test-fixtures':
specifier: workspace:*
version: link:../../__utils__/test-fixtures
'@types/ramda':
specifier: 0.28.15
version: 0.28.15