1 | #!/usr/bin/env node
|
2 | "use strict";
|
3 |
|
4 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
5 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
6 | };
|
7 | Object.defineProperty(exports, "__esModule", { value: true });
|
8 |
|
9 | const index_js_1 = require("./index.js");
|
10 | const util_js_1 = require("./util.js");
|
11 |
|
12 | const version_range_1 = __importDefault(require("version-range"));
|
13 | const minimist_1 = __importDefault(require("minimist"));
|
14 | const text_table_1 = __importDefault(require("text-table"));
|
15 | const string_width_1 = __importDefault(require("string-width"));
|
16 | const logger_clearable_1 = __importDefault(require("logger-clearable"));
|
17 | const spinner_title_1 = __importDefault(require("spinner-title"));
|
18 | const fs_readable_1 = require("@bevry/fs-readable");
|
19 | const wait_1 = __importDefault(require("@bevry/wait"));
|
20 | const json_1 = require("@bevry/json");
|
21 | const nodejs_versions_1 = require("@bevry/nodejs-versions");
|
22 | const filedirname_1 = __importDefault(require("filedirname"));
|
23 | const [file, dir] = (0, filedirname_1.default)();
|
24 |
|
25 | const node_process_1 = __importDefault(require("node:process"));
|
26 | const node_path_1 = require("node:path");
|
27 |
|
28 | const spinner = null;
|
29 | async function parse() {
|
30 |
|
31 | const cli = (0, minimist_1.default)(node_process_1.default.argv.slice(2), {
|
32 | '--': true,
|
33 | alias: {
|
34 | h: 'help',
|
35 | j: 'json',
|
36 | n: 'node',
|
37 | s: 'serial',
|
38 | },
|
39 | string: ['node', 'spinner'],
|
40 |
|
41 | });
|
42 | if (cli.help) {
|
43 |
|
44 | node_process_1.default.stdout.write([
|
45 | 'Usage:',
|
46 | '',
|
47 | ' -n/--node [version]: Add a Node.js version to test',
|
48 | ' -s/--serial: Run tests serially, one after the other',
|
49 | ' -j/--json: Output the test results as JSON',
|
50 | ' --spinner [spinner] Which spinner to use in the title bar',
|
51 | ' --verbose: Report details about all statuses, not just failures',
|
52 | ' --version: Output the version of Testen',
|
53 | ' --help: Output this help',
|
54 | ' -- [command]: The test command you expect',
|
55 | '',
|
56 | ].join('\n'));
|
57 | return null;
|
58 | }
|
59 | if (cli.version) {
|
60 |
|
61 | const testenPackage = await (0, json_1.readJSON)((0, node_path_1.join)(dir, 'package.json'));
|
62 | node_process_1.default.stdout.write(testenPackage.version + '\n');
|
63 | return null;
|
64 | }
|
65 |
|
66 | const cliTestenConfig = {};
|
67 | if (cli.node)
|
68 | cliTestenConfig.node =
|
69 | Array.isArray(cli.node) && cli.node.length === 1 ? cli.node[0] : cli.node;
|
70 | if (cli['--'] && cli['--'].join(''))
|
71 | cliTestenConfig.command = cli['--'].join(' ');
|
72 | if (cli.spinner != null)
|
73 | cliTestenConfig.spinner = cli.spinner;
|
74 | if (cli.serial != null)
|
75 | cliTestenConfig.serial = cli.serial;
|
76 | if (cli.json != null)
|
77 | cliTestenConfig.json = cli.json;
|
78 | if (cli.verbose != null)
|
79 | cliTestenConfig.verbose = cli.verbose;
|
80 | return cliTestenConfig;
|
81 | }
|
82 | async function testen(customTestenConfig = {}) {
|
83 |
|
84 | const cwd = node_process_1.default.cwd();
|
85 | const userPackagePath = `${cwd}/package.json`;
|
86 | const userPackage = (await (0, fs_readable_1.isReadable)(userPackagePath))
|
87 | ? await (0, json_1.readJSON)(userPackagePath)
|
88 | : {};
|
89 |
|
90 | const testenConfig = Object.assign({
|
91 | node: (userPackage.engines && userPackage.engines.node) || '',
|
92 | command: 'npm test',
|
93 | spinner: 'monkey',
|
94 | serial: false,
|
95 | json: false,
|
96 | verbose: false,
|
97 | }, userPackage.testen || {}, customTestenConfig);
|
98 |
|
99 | const nodeVersions = [];
|
100 | if (Array.isArray(testenConfig.node) && testenConfig.node.length) {
|
101 |
|
102 | nodeVersions.push(...testenConfig.node);
|
103 | }
|
104 | else if (testenConfig.node && /^[\d\w.-]+$/.test(testenConfig.node)) {
|
105 |
|
106 | nodeVersions.push(testenConfig.node);
|
107 | }
|
108 | else if (testenConfig.node) {
|
109 |
|
110 | await (0, nodejs_versions_1.preloadNodeVersions)();
|
111 | nodeVersions.push(...(0, nodejs_versions_1.filterSignificantNodeVersions)({
|
112 | maintainedOrLTS: true,
|
113 | released: true,
|
114 | }).filter((version) => (0, version_range_1.default)(version, testenConfig.node)));
|
115 | }
|
116 | else {
|
117 | nodeVersions.push('current', 'stable', 'system');
|
118 | }
|
119 | if (!nodeVersions || !nodeVersions.length) {
|
120 | throw new Error('No node versions specified');
|
121 | }
|
122 |
|
123 | const listeners = [];
|
124 | let interval = null;
|
125 | let spinner = null;
|
126 | if (!testenConfig.json) {
|
127 |
|
128 | spinner = new spinner_title_1.default({
|
129 | style: testenConfig.spinner,
|
130 | interval: 1000,
|
131 | });
|
132 | spinner.start();
|
133 |
|
134 | const logger = new logger_clearable_1.default();
|
135 | function table(result) {
|
136 | return (0, text_table_1.default)(result, { stringLength: string_width_1.default });
|
137 | }
|
138 | function refresh(versions) {
|
139 | const messages = [];
|
140 | versions.array.forEach(function (V) {
|
141 | if (V.success === false || testenConfig.verbose) {
|
142 | messages.push(V.message);
|
143 | }
|
144 | });
|
145 | if (messages.length) {
|
146 | return ('\n' + messages.join('\n\n') + '\n\n' + table(versions.table) + '\n\n');
|
147 | }
|
148 | else {
|
149 | return '\n' + table(versions.table) + '\n\n';
|
150 | }
|
151 | }
|
152 |
|
153 | function refresher() {
|
154 |
|
155 | logger.queue(() => refresh(versions));
|
156 | }
|
157 | interval = setInterval(refresher, 1000);
|
158 | listeners.push(refresher);
|
159 | }
|
160 | const versions = new index_js_1.Versions(nodeVersions, listeners);
|
161 |
|
162 | await versions.load();
|
163 | await versions.install();
|
164 | await versions.test(testenConfig.command, testenConfig.serial);
|
165 |
|
166 | if (testenConfig.json) {
|
167 |
|
168 | node_process_1.default.stdout.write(JSON.stringify(versions.json, null, ' '));
|
169 | }
|
170 | else {
|
171 |
|
172 |
|
173 | if (interval) {
|
174 | clearInterval(interval);
|
175 | interval = null;
|
176 | }
|
177 | spinner.stop();
|
178 | await (0, wait_1.default)(0);
|
179 | }
|
180 |
|
181 | return versions;
|
182 | }
|
183 |
|
184 | Promise.resolve()
|
185 | .then(parse)
|
186 | .then(async function (cliTestenConfig = null) {
|
187 | if (cliTestenConfig) {
|
188 | const versions = await testen(cliTestenConfig);
|
189 | node_process_1.default.exitCode = versions.success ? 0 : 1;
|
190 | }
|
191 | })
|
192 | .catch(function (err) {
|
193 | if (spinner)
|
194 | spinner.stop();
|
195 | node_process_1.default.stderr.write((err.stack || err.message || err).toString());
|
196 | node_process_1.default.exitCode = (0, util_js_1.parseExitCode)(err.code) || 2;
|
197 | });
|