From 298e0ea6cea3ab8a610cabf28de3fdf8e7fa8d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Vicente?= Date: Sun, 17 Mar 2019 21:56:42 +0000 Subject: [PATCH] feat(audit): add filtering by severity level (#6716) **Summary** Adds a `--level` flag to the `audit` command allowing to filter the audit output by severity greater than or equal to the provided value which can be (info, low, moderate, high or critical). fixes #6668 --- CHANGELOG.md | 4 ++++ __tests__/commands/audit.js | 14 ++++++++++++++ src/cli/commands/audit.js | 22 ++++++++++++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ccd8829f51..c0355a7b51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ Please add one entry in this file for each change in Yarn's behavior. Use the sa ## Master +- Implements `yarn audit --level [severity]` flag to filter the audit command's output. + +[#6716](https://github.com/yarnpkg/yarn/pull/6716) - [**Rogério Vicente**](https://twitter.com/rogeriopvl) + - Implements `yarn audit --groups group_name [group_name ...]`. [#6724](https://github.com/yarnpkg/yarn/pull/6724) - [**Tom Milligan**](https://github.com/tommilligan) diff --git a/__tests__/commands/audit.js b/__tests__/commands/audit.js index 15a478ac67..931d1639e3 100644 --- a/__tests__/commands/audit.js +++ b/__tests__/commands/audit.js @@ -214,6 +214,20 @@ test('audit groups only devDependencies omits dependencies from requires', () => }); }); +test('calls reporter auditAdvisory when using --level high flag', () => { + return runAudit([], {level: 'high'}, 'single-vulnerable-dep-installed', (config, reporter) => { + const apiResponse = getAuditResponse(config); + expect(reporter.auditAdvisory).toBeCalledWith(apiResponse.actions[0].resolves[0], apiResponse.advisories['118']); + }); +}); + +test(`doesn't call reporter auditAdvisory when using --level critical flag`, () => { + return runAudit([], {level: 'critical'}, 'single-vulnerable-dep-installed', (config, reporter) => { + getAuditResponse(config); + expect(reporter.auditAdvisory).not.toHaveBeenCalled(); + }); +}); + test('calls reporter auditAdvisory with correct data', () => { return runAudit([], {}, 'single-vulnerable-dep-installed', (config, reporter) => { const apiResponse = getAuditResponse(config); diff --git a/src/cli/commands/audit.js b/src/cli/commands/audit.js index acfbdafed0..7f2d92ebf7 100644 --- a/src/cli/commands/audit.js +++ b/src/cli/commands/audit.js @@ -18,6 +18,7 @@ const gzip = promisify(zlib.gzip); export type AuditOptions = { groups: Array, + level?: string, }; export type AuditNode = { @@ -127,6 +128,12 @@ export function setFlags(commander: Object) { groups => groups.split(' '), OWNED_DEPENDENCY_TYPES, ); + commander.option( + '--level ', + `Only print advisories with severity greater than or equal to one of the following: \ + info|low|moderate|high|critical. Default: info`, + 'info', + ); } export function hasWrapper(commander: Object, args: Array): boolean { @@ -134,7 +141,11 @@ export function hasWrapper(commander: Object, args: Array): boolean { } export async function run(config: Config, reporter: Reporter, flags: Object, args: Array): Promise { - const audit = new Audit(config, reporter, {groups: flags.groups || OWNED_DEPENDENCY_TYPES}); + const DEFAULT_LOG_LEVEL = 'info'; + const audit = new Audit(config, reporter, { + groups: flags.groups || OWNED_DEPENDENCY_TYPES, + level: flags.level || DEFAULT_LOG_LEVEL, + }); const lockfile = await Lockfile.fromDirectory(config.lockfileFolder, reporter); const install = new Install({}, config, reporter, lockfile); const {manifest, requests, patterns, workspaceLayout} = await install.fetchRequestFromCwd(); @@ -167,6 +178,8 @@ export async function run(config: Config, reporter: Reporter, flags: Object, arg } export default class Audit { + severityLevels = ['info', 'low', 'moderate', 'high', 'critical']; + constructor(config: Config, reporter: Reporter, options: AuditOptions) { this.config = config; this.reporter = reporter; @@ -292,9 +305,14 @@ export default class Audit { return; } + const startLoggingAt: number = Math.max(0, this.severityLevels.indexOf(this.options.level)); + const reportAdvisory = (resolution: AuditResolution) => { const advisory = this.auditData.advisories[resolution.id.toString()]; - this.reporter.auditAdvisory(resolution, advisory); + + if (this.severityLevels.indexOf(advisory.severity) >= startLoggingAt) { + this.reporter.auditAdvisory(resolution, advisory); + } }; if (Object.keys(this.auditData.advisories).length !== 0) {