UNPKG

2.62 kBJavaScriptView Raw
1#!/usr/bin/env node
2// @ts-check
3
4import { spawn } from "child_process";
5import disposableDirectory from "disposable-directory";
6import { yellow } from "kleur/colors";
7
8import analyseCoverage from "./analyseCoverage.mjs";
9import childProcessPromise from "./childProcessPromise.mjs";
10import CliError from "./CliError.mjs";
11import coverageSupported from "./coverageSupported.mjs";
12import minNodeVersion from "./coverageSupportedMinNodeVersion.mjs";
13import reportCliError from "./reportCliError.mjs";
14import reportCoverage from "./reportCoverage.mjs";
15
16/**
17 * Powers the `coverage-node` CLI. Runs Node.js with the given arguments and
18 * coverage enabled. An analysis of the coverage is reported to the console, and
19 * if coverage is incomplete and there isn’t a truthy `ALLOW_MISSING_COVERAGE`
20 * environment variable the process exits with code `1`.
21 * @returns {Promise<void>} Resolves when all work is complete.
22 */
23async function coverageNode() {
24 try {
25 const [, , ...nodeArgs] = process.argv;
26
27 if (!nodeArgs.length)
28 throw new CliError("Node.js CLI arguments are required.");
29
30 // eslint-disable-next-line curly
31 if (coverageSupported) {
32 await disposableDirectory(async (tempDirPath) => {
33 const { exitCode } = await childProcessPromise(
34 spawn("node", nodeArgs, {
35 stdio: "inherit",
36 env: { ...process.env, NODE_V8_COVERAGE: tempDirPath },
37 })
38 );
39
40 // Only show a code coverage report if the Node.js script didn’t error,
41 // to reduce distraction from the priority to solve errors.
42 if (exitCode === 0) {
43 const analysis = await analyseCoverage(tempDirPath);
44 reportCoverage(analysis);
45 if (analysis.uncovered.length && !process.env.ALLOW_MISSING_COVERAGE)
46 process.exitCode = 1;
47 } else if (exitCode !== null) process.exitCode = exitCode;
48 });
49 // coverage ignore next line
50 } else {
51 const { exitCode } = await childProcessPromise(
52 spawn("node", nodeArgs, { stdio: "inherit" })
53 );
54
55 if (exitCode === 0)
56 console.info(
57 `\n${yellow(
58 `Skipped code coverage as Node.js is ${process.version}, v${minNodeVersion.major}.${minNodeVersion.minor}.${minNodeVersion.patch}+ is supported.`
59 )}\n`
60 );
61 else if (exitCode !== null) process.exitCode = exitCode;
62 }
63 } catch (error) {
64 reportCliError(
65 `Node.js${
66 // coverage ignore next line
67 coverageSupported ? " with coverage" : ""
68 }`,
69 error
70 );
71
72 process.exitCode = 1;
73 }
74}
75
76coverageNode();