Skip to content

Commit 3aad5c6

Browse files
authored
Add files for Yarn 3 (#305)
1 parent bc67ffe commit 3aad5c6

File tree

189 files changed

+154290
-3625
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

189 files changed

+154290
-3625
lines changed

.eslintignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
test/yarn-berry.cjs
1+
test/yarn-*.cjs
22
dist
33
coverage

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
test/yarn-berry.cjs linguist-vendored
1+
test/yarn-*.cjs linguist-vendored

.prettierignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
test/yarn-berry.cjs
21
coverage
2+
test/yarn-*.cjs
33
**/pnpm-lock.yaml
44
**/*-output.json
55
**/.pnp.cjs
6+
test/*/*.json

.vscode/launch.json

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,4 @@
11
{
22
"version": "0.2.0",
3-
"configurations": [
4-
{
5-
"type": "node",
6-
"request": "launch",
7-
"name": "Mocha All",
8-
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
9-
"args": [
10-
"-r",
11-
"ts-node/register",
12-
"--timeout",
13-
"999999",
14-
"--extensions",
15-
"ts",
16-
"--recursive",
17-
"--colors",
18-
"${workspaceFolder}/test/*.spec.ts"
19-
],
20-
"console": "integratedTerminal",
21-
"internalConsoleOptions": "neverOpen"
22-
},
23-
{
24-
"type": "node",
25-
"request": "launch",
26-
"name": "Mocha Current File",
27-
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
28-
"args": [
29-
"-r",
30-
"ts-node/register",
31-
"--timeout",
32-
"999999",
33-
"--extensions",
34-
"ts",
35-
"--recursive",
36-
"--colors",
37-
"${file}"
38-
],
39-
"console": "integratedTerminal",
40-
"internalConsoleOptions": "neverOpen"
41-
}
42-
]
3+
"configurations": []
434
}

README.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ threshold while ignoring allowlisted advisories.
1414
## Requirements
1515

1616
- Node >=16
17-
- _(Optional)_ Yarn ^1.12.3 || Yarn >=2.4.0
17+
- _(Optional)_ Yarn ^1.12.3 || Yarn >=2.4.0 && <4.0.0
1818
- _(Optional)_ PNPM >=4.3.0
19+
- _(Optional)_ Bun
1920

2021
## Limitations
2122

2223
- Yarn Classic workspaces does not audit `devDependencies`. See [this issue](https://github.com/yarnpkg/yarn/issues/7047) for more information.
24+
- Yarn v4 is not supported because it provides similar functionality to `audit-ci`.
25+
For more information, see the [documentation on `yarn npm audit`](https://yarnpkg.com/cli/npm/audit#options).
26+
- Bun is supported by exporting the `bun.lockb` into a Yarn v1 `yarn.lock` file.
27+
Accordingly, it requires Yarn v1 to run `audit-ci` and it has the same limitations as Yarn v1.
2328

2429
## Set up
2530

@@ -40,6 +45,7 @@ The downside of this approach is that the CI may run a `postinstall` script of a
4045
npm install -D audit-ci
4146
yarn add -D audit-ci
4247
pnpm install -D audit-ci
48+
bun install -D audit-ci
4349
```
4450

4551
The next section gives examples using `audit-ci` in various CI environments.
@@ -59,11 +65,21 @@ Also, it suppresses an advisory of `axios` and a transitive advisory of `react-s
5965
// https://github.com/advisories/GHSA-rp65-9cf3-cjxr
6066
// Alternatively, allowlist "GHSA-rp65-9cf3-cjxr" to suppress this nth-check advisory across all paths
6167
// or "*|react-scripts>*" to suppress advisories for all transitive dependencies of "react-scripts".
62-
"GHSA-rp65-9cf3-cjxr|react-scripts>@svgr/webpack>@svgr/plugin-svgo>svgo>css-select>nth-check"
63-
]
68+
"GHSA-rp65-9cf3-cjxr|react-scripts>@svgr/webpack>@svgr/plugin-svgo>svgo>css-select>nth-check",
69+
],
6470
}
6571
```
6672

73+
### Bun
74+
75+
Bun supports exporting the `bun.lockb` into a Yarn v1 `yarn.lock` file.
76+
77+
```sh
78+
bun install -y
79+
```
80+
81+
Afterwards, you can run `audit-ci` with the `yarn` package manager.
82+
6783
### Allowlisting
6884

6985
Allowlists are a mechanism to suppress an advisory warning from the audit. A team may want to suppress an advisory when:
@@ -320,8 +336,8 @@ With a `JSONC` config file, execute with `npx audit-ci --config ./audit-ci.jsonc
320336
// https://github.com/advisories/GHSA-rp65-9cf3-cjxr
321337
// Alternatively, allowlist "GHSA-rp65-9cf3-cjxr" to suppress this nth-check advisory across all paths
322338
// or "*|react-scripts>*" to suppress advisories for all transitive dependencies of "react-scripts".
323-
"GHSA-rp65-9cf3-cjxr|react-scripts>@svgr/webpack>@svgr/plugin-svgo>svgo>css-select>nth-check"
324-
]
339+
"GHSA-rp65-9cf3-cjxr|react-scripts>@svgr/webpack>@svgr/plugin-svgo>svgo>css-select>nth-check",
340+
],
325341
}
326342
```
327343

@@ -359,7 +375,7 @@ With a `JSONC` config file:
359375
{
360376
"$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
361377
"critical": true,
362-
"report-type": "full"
378+
"report-type": "full",
363379
}
364380
```
365381

@@ -376,7 +392,7 @@ With a `JSONC` config file:
376392
```jsonc
377393
{
378394
"$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
379-
"report-type": "summary"
395+
"report-type": "summary",
380396
}
381397
```
382398

@@ -393,7 +409,7 @@ With a `JSONC` config file, in a project on Yarn Berry v3.3.0 or later:
393409
```jsonc
394410
{
395411
"$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
396-
"extra-args": ["--exclude", "example"]
412+
"extra-args": ["--exclude", "example"],
397413
}
398414
```
399415

@@ -420,9 +436,9 @@ npx audit-ci@^7 --extra-args '\--exclude' example
420436
"GHSA-6354-6mhv-mvv5|example3",
421437
"GHSA-42xw-2xvc-qx8m|example4",
422438
"GHSA-42xw-2xvc-qx8m|example5>example4",
423-
"*|example6>*"
439+
"*|example6>*",
424440
],
425-
"registry": "https://registry.npmjs.org"
441+
"registry": "https://registry.npmjs.org",
426442
}
427443
```
428444

lib/config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,8 @@ export function mapAuditCiConfigToAuditCiFullConfig(
293293
}
294294

295295
export async function runYargs(): Promise<AuditCiFullConfig> {
296-
const { argv } = yargs().config("config", (configPath) =>
296+
const { argv } = yargs()
297+
.config("config", (configPath) =>
297298
// Supports JSON, JSONC, & JSON5
298299
jju.parse(readFileSync(configPath, "utf8"), {
299300
// When passing an allowlist using NSRecord syntax, yargs will throw an error

lib/yarn-auditor.ts

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import type { YarnAudit, YarnBerryAuditReport } from "audit-types";
2-
import { execSync } from "child_process";
3-
import * as semver from "semver";
1+
import type { YarnAudit, Yarn2And3AuditReport } from "audit-types";
42
import { blue, red, yellow } from "./colors.js";
53
import { reportAudit, runProgram } from "./common.js";
64
import {
@@ -9,38 +7,14 @@ import {
97
type AuditCiFullConfig,
108
} from "./config.js";
119
import Model, { type Summary } from "./model.js";
12-
13-
const MINIMUM_YARN_CLASSIC_VERSION = "1.12.3";
14-
const MINIMUM_YARN_BERRY_VERSION = "2.4.0";
15-
/**
16-
* Change this to the appropriate version when
17-
* yarn audit --registry is supported:
18-
* @see https://github.com/yarnpkg/yarn/issues/7012
19-
*/
20-
const MINIMUM_YARN_AUDIT_REGISTRY_VERSION = "99.99.99";
21-
22-
function getYarnVersion(cwd?: string) {
23-
const version = execSync("yarn -v", { cwd }).toString().replace("\n", "");
24-
return version;
25-
}
26-
27-
function yarnSupportsClassicAudit(yarnVersion: string | semver.SemVer) {
28-
return semver.satisfies(yarnVersion, `^${MINIMUM_YARN_CLASSIC_VERSION}`);
29-
}
30-
31-
function yarnSupportsBerryAudit(yarnVersion: string | semver.SemVer) {
32-
return semver.gte(yarnVersion, MINIMUM_YARN_BERRY_VERSION);
33-
}
34-
35-
function yarnSupportsAudit(yarnVersion: string | semver.SemVer) {
36-
return (
37-
yarnSupportsClassicAudit(yarnVersion) || yarnSupportsBerryAudit(yarnVersion)
38-
);
39-
}
40-
41-
function yarnAuditSupportsRegistry(yarnVersion: string | semver.SemVer) {
42-
return semver.gte(yarnVersion, MINIMUM_YARN_AUDIT_REGISTRY_VERSION);
43-
}
10+
import {
11+
MINIMUM_YARN_BERRY_VERSION,
12+
MINIMUM_YARN_CLASSIC_VERSION,
13+
getYarnVersion,
14+
yarnAuditSupportsRegistry,
15+
yarnSupportsAudit,
16+
yarnSupportsClassicAudit,
17+
} from "./yarn-version.js";
4418

4519
const printJson = (data: unknown) => {
4620
console.log(JSON.stringify(data, undefined, 2));
@@ -83,7 +57,7 @@ export async function auditWithFullConfig(
8357
let missingLockFile = false;
8458
const model = new Model(config);
8559

86-
const yarnVersion = getYarnVersion(directory);
60+
const yarnVersion = getYarnVersion(yarnExec, directory);
8761
const isYarnVersionSupported = yarnSupportsAudit(yarnVersion);
8862
if (!isYarnVersionSupported) {
8963
throw new Error(
@@ -94,7 +68,7 @@ export async function auditWithFullConfig(
9468
const yarnName = isYarnClassic ? `Yarn` : `Yarn Berry`;
9569

9670
function isClassicGuard(
97-
response: YarnAudit.AuditResponse | YarnBerryAuditReport.AuditResponse,
71+
response: YarnAudit.AuditResponse | Yarn2And3AuditReport.AuditResponse,
9872
): response is YarnAudit.AuditResponse {
9973
return isYarnClassic;
10074
}
@@ -147,7 +121,7 @@ export async function auditWithFullConfig(
147121
printJson(data);
148122
}
149123
}
150-
: ({ metadata }: { metadata: YarnBerryAuditReport.AuditMetadata }) => {
124+
: ({ metadata }: { metadata: Yarn2And3AuditReport.AuditMetadata }) => {
151125
printJson(metadata);
152126
};
153127
break;
@@ -159,7 +133,7 @@ export async function auditWithFullConfig(
159133
printJson(data);
160134
}
161135
}
162-
: ({ metadata }: { metadata: YarnBerryAuditReport.AuditMetadata }) => {
136+
: ({ metadata }: { metadata: Yarn2And3AuditReport.AuditMetadata }) => {
163137
printJson(metadata);
164138
};
165139
break;
@@ -172,7 +146,7 @@ export async function auditWithFullConfig(
172146
}
173147

174148
function outListener(
175-
line: YarnAudit.AuditResponse | YarnBerryAuditReport.AuditResponse,
149+
line: YarnAudit.AuditResponse | Yarn2And3AuditReport.AuditResponse,
176150
) {
177151
try {
178152
if (isClassicGuard(line)) {
@@ -193,7 +167,7 @@ export async function auditWithFullConfig(
193167
printAuditData(line);
194168

195169
if ("advisories" in line) {
196-
for (const advisory of Object.values<YarnBerryAuditReport.Advisory>(
170+
for (const advisory of Object.values<Yarn2And3AuditReport.Advisory>(
197171
line.advisories,
198172
)) {
199173
model.process(advisory);

lib/yarn-version.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { execSync } from "child_process";
2+
import semver from "semver";
3+
4+
export const MINIMUM_YARN_CLASSIC_VERSION = "1.12.3";
5+
export const MINIMUM_YARN_BERRY_VERSION = "2.4.0";
6+
/**
7+
* Change this to the appropriate version when
8+
* yarn audit --registry is supported:
9+
* @see https://github.com/yarnpkg/yarn/issues/7012
10+
*/
11+
const MINIMUM_YARN_AUDIT_REGISTRY_VERSION = "99.99.99";
12+
13+
export function yarnSupportsClassicAudit(yarnVersion: string | semver.SemVer) {
14+
return semver.satisfies(yarnVersion, `^${MINIMUM_YARN_CLASSIC_VERSION}`);
15+
}
16+
17+
export function yarnSupportsBerryAudit(yarnVersion: string | semver.SemVer) {
18+
return semver.gte(yarnVersion, MINIMUM_YARN_BERRY_VERSION);
19+
}
20+
21+
export function yarnSupportsAudit(yarnVersion: string | semver.SemVer) {
22+
return (
23+
yarnSupportsClassicAudit(yarnVersion) || yarnSupportsBerryAudit(yarnVersion)
24+
);
25+
}
26+
27+
export function yarnAuditSupportsRegistry(yarnVersion: string | semver.SemVer) {
28+
return semver.gte(yarnVersion, MINIMUM_YARN_AUDIT_REGISTRY_VERSION);
29+
}
30+
31+
const versionMap = new Map<string, string>();
32+
export function getYarnVersion(yarnExec = "yarn", cwd?: string) {
33+
const key = `${yarnExec}:${cwd}`;
34+
let version = versionMap.get(key);
35+
if (version) return version;
36+
version = execSync(`${yarnExec} -v`, { cwd }).toString().replace("\n", "");
37+
versionMap.set(key, version);
38+
return version;
39+
}

0 commit comments

Comments
 (0)