Skip to content

Commit 709bf95

Browse files
authored
Add --extra-args to fix #298 (#300)
1 parent 7673dd4 commit 709bf95

File tree

8 files changed

+91
-5
lines changed

8 files changed

+91
-5
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ scripts:
271271
| | --retry-count | The number of attempts audit-ci calls an unavailable registry before failing (default `5`) |
272272
| | --config | Path to the audit-ci configuration file |
273273
| | --skip-dev | Skip auditing devDependencies (default `false`) |
274+
| | --extra-args | Extra arguments to pass to the underlying audit command (default: `[]`) |
274275

275276
### Config file specification
276277

@@ -385,6 +386,23 @@ Or, with the CLI:
385386
npx audit-ci@^6 --report-type summary
386387
```
387388

389+
### Pass additional args to Yarn to exclude a certain package from audit
390+
391+
With a `JSONC` config file, in a project on Yarn v3.3.0 or later:
392+
393+
```jsonc
394+
{
395+
"$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
396+
"extra-args": ["--exclude", "example"]
397+
}
398+
```
399+
400+
Or, with the CLI:
401+
402+
```sh
403+
npx audit-ci@^6 --extra-args '\--exclude' example
404+
```
405+
388406
### Example config file and different directory usage
389407

390408
#### test/npm-config-file/audit-ci.jsonc

docs/schema.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,11 @@ export interface Schema {
112112
* @default false
113113
*/
114114
"skip-dev"?: boolean;
115+
116+
/**
117+
* Extra arguments to pass to the underlying audit command.
118+
*
119+
* @default []
120+
*/
121+
"extra-args"?: string[];
115122
}

docs/schema.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@
5858
"description": "The directory containing the package.json to audit.",
5959
"type": "string"
6060
},
61+
"extra-args": {
62+
"default": [],
63+
"description": "Extra arguments to pass to the underlying audit command.",
64+
"items": {
65+
"type": "string"
66+
},
67+
"type": "array"
68+
},
6169
"high": {
6270
"default": false,
6371
"description": "Prevent integration with high or higher vulnerabilities.",

lib/config.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ function mapReportTypeInput(
2525
}
2626
}
2727

28+
function mapExtraArgumentsInput(
29+
config: Pick<AuditCiPreprocessedConfig, "extra-args">
30+
) {
31+
// These args will often be flags for another command, so we
32+
// want to have some way of escaping args that start with a -.
33+
// We'll look for and remove a single backslash at the start, if present.
34+
return config["extra-args"].map((a) => a.replace(/^\\/, ""));
35+
}
36+
2837
export type AuditCiPreprocessedConfig = {
2938
/** Exit for low or above vulnerabilities */
3039
l: boolean;
@@ -78,6 +87,8 @@ export type AuditCiPreprocessedConfig = {
7887
"pass-enoaudit": boolean;
7988
/** skip devDependencies */
8089
"skip-dev": boolean;
90+
/** extra positional args for underlying audit command */
91+
"extra-args": string[];
8192
};
8293

8394
// Rather than exporting a weird union type, we resolve the type to a simple object.
@@ -163,6 +174,7 @@ function mapArgvToAuditCiConfig(argv: AuditCiPreprocessedConfig) {
163174
}),
164175
"report-type": mapReportTypeInput(argv),
165176
allowlist: allowlist,
177+
"extra-args": mapExtraArgumentsInput(argv),
166178
};
167179
return result;
168180
}
@@ -276,6 +288,11 @@ export async function runYargs(): Promise<AuditCiConfig> {
276288
describe: "Skip devDependencies",
277289
type: "boolean",
278290
},
291+
"extra-args": {
292+
default: [],
293+
describe: "Pass additional arguments to the underlying audit command",
294+
type: "array",
295+
},
279296
})
280297
.help("help");
281298

lib/npm-auditer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ async function runNpmAudit(
1212
registry,
1313
_npm,
1414
"skip-dev": skipDevelopmentDependencies,
15+
"extra-args": extraArguments,
1516
} = config;
1617
const npmExec = _npm || "npm";
1718

@@ -32,6 +33,9 @@ async function runNpmAudit(
3233
if (skipDevelopmentDependencies) {
3334
arguments_.push("--production");
3435
}
36+
if (extraArguments) {
37+
arguments_.push(...extraArguments);
38+
}
3539
const options = { cwd: directory };
3640
await runProgram(npmExec, arguments_, options, outListener, errorListener);
3741
if (stderrBuffer.length > 0) {

lib/pnpm-auditer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ async function runPnpmAudit(
1616
registry,
1717
_pnpm,
1818
"skip-dev": skipDevelopmentDependencies,
19+
"extra-args": extraArguments,
1920
} = config;
2021
const pnpmExec = _pnpm || "pnpm";
2122

@@ -45,6 +46,9 @@ async function runPnpmAudit(
4546
if (skipDevelopmentDependencies) {
4647
arguments_.push("--prod");
4748
}
49+
if (extraArguments) {
50+
arguments_.push(...extraArguments);
51+
}
4852
const options = { cwd: directory };
4953
await runProgram(pnpmExec, arguments_, options, outListener, errorListener);
5054
if (stderrBuffer.length > 0) {

lib/yarn-auditer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export async function audit(
5959
"output-format": outputFormat,
6060
_yarn,
6161
directory,
62+
"extra-args": extraArguments,
6263
} = config;
6364
const yarnExec = _yarn || "yarn";
6465
let missingLockFile = false;
@@ -210,6 +211,9 @@ export async function audit(
210211
);
211212
}
212213
}
214+
if (extraArguments) {
215+
arguments_.push(...extraArguments);
216+
}
213217
await runProgram(yarnExec, arguments_, options, outListener, errorListener);
214218
if (missingLockFile) {
215219
console.warn(

test/yarn-auditer.spec.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,10 +372,10 @@ describe("yarn-auditer", function testYarnAuditer() {
372372
expect(summary).to.eql(
373373
summaryWithDefault({
374374
failedLevelsFound: ["high", "moderate"],
375-
advisoriesFound: ["GHSA-rvg8-pwq2-xj7q", "GHSA-38f5-ghc2-fcmv"],
375+
advisoriesFound: ["GHSA-38f5-ghc2-fcmv", "GHSA-rvg8-pwq2-xj7q"],
376376
advisoryPathsFound: [
377-
"GHSA-rvg8-pwq2-xj7q|audit-ci-yarn-workspace-moderate-vulnerability>base64url",
378377
"GHSA-38f5-ghc2-fcmv|audit-ci-yarn-workspace-high-vulnerability>cryo",
378+
"GHSA-rvg8-pwq2-xj7q|audit-ci-yarn-workspace-moderate-vulnerability>base64url",
379379
],
380380
})
381381
);
@@ -409,14 +409,14 @@ describe("yarn-auditer", function testYarnAuditer() {
409409
summaryWithDefault({
410410
failedLevelsFound: ["critical", "high", "moderate"],
411411
advisoriesFound: [
412-
"GHSA-rvg8-pwq2-xj7q",
413412
"GHSA-28xh-wpgr-7fm8",
414413
"GHSA-38f5-ghc2-fcmv",
414+
"GHSA-rvg8-pwq2-xj7q",
415415
],
416416
advisoryPathsFound: [
417-
"GHSA-rvg8-pwq2-xj7q|base64url",
418417
"GHSA-28xh-wpgr-7fm8|open",
419418
"GHSA-38f5-ghc2-fcmv|cryo",
419+
"GHSA-rvg8-pwq2-xj7q|base64url",
420420
],
421421
})
422422
);
@@ -437,10 +437,34 @@ describe("yarn-auditer", function testYarnAuditer() {
437437
expect(summary).to.eql(
438438
summaryWithDefault({
439439
failedLevelsFound: ["high", "moderate"],
440-
advisoriesFound: ["GHSA-rvg8-pwq2-xj7q", "GHSA-38f5-ghc2-fcmv"],
440+
advisoriesFound: ["GHSA-38f5-ghc2-fcmv", "GHSA-rvg8-pwq2-xj7q"],
441441
advisoryPathsFound: [
442+
"GHSA-38f5-ghc2-fcmv|cryo",
442443
"GHSA-rvg8-pwq2-xj7q|base64url",
444+
],
445+
})
446+
);
447+
}
448+
);
449+
(canRunYarnBerry ? it : it.skip)(
450+
"reports summary with vulnerabilities in yarn berry workspaces with extra-args: --environment production",
451+
async () => {
452+
const summary = await audit(
453+
config({
454+
directory: testDirectory("yarn-berry-workspace"),
455+
levels: { moderate: true },
456+
"extra-args": ["--environment", "production"],
457+
"report-type": "important",
458+
}),
459+
(_summary) => _summary
460+
);
461+
expect(summary).to.eql(
462+
summaryWithDefault({
463+
failedLevelsFound: ["high", "moderate"],
464+
advisoriesFound: ["GHSA-38f5-ghc2-fcmv", "GHSA-rvg8-pwq2-xj7q"],
465+
advisoryPathsFound: [
443466
"GHSA-38f5-ghc2-fcmv|cryo",
467+
"GHSA-rvg8-pwq2-xj7q|base64url",
444468
],
445469
})
446470
);

0 commit comments

Comments
 (0)