Skip to content

Commit

Permalink
feat: add no-package-lock mode to npm audit
Browse files Browse the repository at this point in the history
  • Loading branch information
wraithgar committed Aug 24, 2023
1 parent f239540 commit 69ed983
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 3 deletions.
7 changes: 7 additions & 0 deletions docs/lib/content/commands/npm-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ vulnerability is found. It may be useful in CI environments to include the
will cause the command to fail. This option does not filter the report
output, it simply changes the command's failure threshold.

### Package lock

By default npm requires a package-lock or shrinkwrap in order to run the
audit. You can bypass the package lock with `--no-package-lock` but be
aware the results may be different with every run, since npm will
re-build the dependency tree each time.

### Audit Signatures

To ensure the integrity of packages you download from the public npm registry, or any registry that supports signatures, you can verify the registry signatures of downloaded packages using the npm CLI.
Expand Down
1 change: 1 addition & 0 deletions docs/lib/content/commands/npm-query.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ npm query ":type(git)" | jq 'map(.name)' | xargs -I {} npm why {}
},
...
```

### Package lock only mode

If package-lock-only is enabled, only the information in the package
Expand Down
6 changes: 5 additions & 1 deletion lib/commands/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ class Audit extends ArboristWorkspaceCmd {
'force',
'json',
'package-lock-only',
'package-lock',
'omit',
'foreground-scripts',
'ignore-scripts',
Expand Down Expand Up @@ -439,6 +440,10 @@ class Audit extends ArboristWorkspaceCmd {
}

async auditAdvisories (args) {
const fix = args[0] === 'fix'
if (this.npm.config.get('package-lock') === false && fix) {
throw this.usageError('fix can not be used without a package-lock')
}
const reporter = this.npm.config.get('json') ? 'json' : 'detail'
const Arborist = require('@npmcli/arborist')
const opts = {
Expand All @@ -450,7 +455,6 @@ class Audit extends ArboristWorkspaceCmd {
}

const arb = new Arborist(opts)
const fix = args[0] === 'fix'
await arb.audit({ fix })
if (fix) {
await reifyFinish(this.npm, arb)
Expand Down
3 changes: 2 additions & 1 deletion tap-snapshots/test/lib/docs.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2526,7 +2526,7 @@ npm audit [fix|signatures]
Options:
[--audit-level <info|low|moderate|high|critical|none>] [--dry-run] [-f|--force]
[--json] [--package-lock-only]
[--json] [--package-lock-only] [--no-package-lock]
[--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]]
[--foreground-scripts] [--ignore-scripts]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
Expand All @@ -2543,6 +2543,7 @@ npm audit [fix|signatures]
#### \`force\`
#### \`json\`
#### \`package-lock-only\`
#### \`package-lock\`
#### \`omit\`
#### \`foreground-scripts\`
#### \`ignore-scripts\`
Expand Down
12 changes: 12 additions & 0 deletions test/lib/commands/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,18 @@ t.test('audit fix - bulk endpoint', async t => {
)
})

t.test('audit fix no package lock', async t => {
const { npm } = await loadMockNpm(t, {
config: {
'package-lock': false,
},
})
await t.rejects(
npm.exec('audit', ['fix']),
{ code: 'EUSAGE' }
)
})

t.test('completion', async t => {
const { audit } = await loadMockNpm(t, { command: 'audit' })
t.test('fix', async t => {
Expand Down
10 changes: 9 additions & 1 deletion workspaces/arborist/lib/arborist/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ module.exports = cls => class Auditor extends cls {
options = { ...this.options, ...options }

process.emit('time', 'audit')
const tree = await this.loadVirtual()
let tree
if (options.packageLock === false) {
// build ideal tree
await this.loadActual(options)
await this.buildIdealTree()
tree = this.idealTree
} else {
tree = await this.loadVirtual()
}
if (this[_workspaces] && this[_workspaces].length) {
options.filterSet = this.workspaceDependencySet(
tree,
Expand Down
9 changes: 9 additions & 0 deletions workspaces/arborist/test/arborist/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ t.test('audit finds the bad deps', async t => {
t.equal(report.size, 2)
})

t.test('no package lock finds no bad deps', async t => {
const path = resolve(fixtures, 'deprecated-dep')
t.teardown(auditResponse(resolve(fixtures, 'audit-nyc-mkdirp/audit.json')))
const arb = newArb(path, { packageLock: false })
const report = await arb.audit()
t.equal(report.topVulns.size, 0)
t.equal(report.size, 0)
})

t.test('audit fix reifies out the bad deps', async t => {
const path = fixture(t, 'deprecated-dep')
t.teardown(auditResponse(resolve(fixtures, 'audit-nyc-mkdirp/audit.json')))
Expand Down

0 comments on commit 69ed983

Please sign in to comment.