monocart-coverage-reports 2.5.9 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/cli.js CHANGED
@@ -1,216 +1,216 @@
1
1
  #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const EC = require('eight-colors');
6
- const { fileURLToPath, pathToFileURL } = require('url');
7
- const {
8
- foregroundChild,
9
- program
10
- } = require('./packages/monocart-coverage-vendor.js');
11
-
12
- const MCR = require('./index.js');
13
- const Util = require('./utils/util.js');
14
- const defaultOptions = require('./default/options.js');
15
- const { resolveSourceMap } = require('./converter/collect-source-maps.js');
16
-
17
- const version = require('../package.json').version;
18
-
19
- const cleanDir = (dir) => {
20
- Util.rmSync(dir);
21
- };
22
-
23
- const resolveConfigPath = (customConfigPath) => {
24
-
25
- const configList = [
26
- '.mcrrc',
27
- 'mcr.config.json',
28
- 'mcr.config.mjs',
29
- 'mcr.config.cjs',
30
- 'mcr.config.js'
31
- ];
32
-
33
- if (customConfigPath) {
34
- configList.push(customConfigPath);
35
- }
36
-
37
- const existsList = configList.filter((p) => fs.existsSync(p));
38
- if (!existsList.length) {
39
- return;
40
- }
41
-
42
- // last one
43
- const configPath = existsList.pop();
44
- Util.logInfo(`Config: ${EC.cyan(configPath)}`);
45
-
46
- return configPath;
47
- };
48
-
49
- const resolveConfigOptions = async (configPath) => {
50
-
51
- // json format
52
- const ext = path.extname(configPath);
53
- if (ext === '.json' || configPath.slice(-2) === 'rc') {
54
- return JSON.parse(Util.readFileSync(configPath));
55
- }
56
-
57
- let configOptions;
58
- let err;
59
- try {
60
- configOptions = await import(pathToFileURL(configPath));
61
- } catch (ee) {
62
- err = ee;
63
- }
64
-
65
- if (!configOptions) {
66
- Util.logError(err.message);
67
- return;
68
- }
69
-
70
- configOptions = configOptions.default || configOptions;
71
-
72
- return configOptions;
73
- };
74
-
75
- const initOptions = async (cliOptions) => {
76
-
77
- const configPath = resolveConfigPath(cliOptions.config);
78
- if (configPath) {
79
- const configOptions = await resolveConfigOptions(configPath);
80
- if (configOptions) {
81
- cliOptions = {
82
- ... configOptions,
83
- ... cliOptions
84
- };
85
- }
86
- }
87
-
88
- // report options
89
- const options = {
90
- ... defaultOptions
91
- };
92
- Object.keys(cliOptions).forEach((k) => {
93
- if (Util.hasOwn(options, k)) {
94
- options[k] = cliOptions[k];
95
- }
96
- });
97
-
98
- return options;
99
- };
100
-
101
- const executeCommand = async (command, cliOptions) => {
102
-
103
- const options = await initOptions(cliOptions);
104
-
105
- Util.logInfo(`Execute: ${EC.cyan(command)}`);
106
- // console.log(options);
107
-
108
- const nodeV8CoverageDir = path.resolve(options.outputDir, '.v8-coverage');
109
- process.env.NODE_V8_COVERAGE = nodeV8CoverageDir;
110
-
111
- cleanDir(nodeV8CoverageDir);
112
-
113
- // console.log('nodeV8CoverageDir', nodeV8CoverageDir);
114
-
115
- const coverageReport = MCR(options);
116
- coverageReport.cleanCache();
117
-
118
- // on start hook
119
- const onStart = cliOptions.onStart;
120
- if (typeof onStart === 'function') {
121
- await onStart(coverageReport);
122
- }
123
-
124
- foregroundChild(command, {
125
- shell: true
126
- }, async () => {
127
-
128
- if (!fs.existsSync(nodeV8CoverageDir)) {
129
- EC.logRed(`Not found coverage data: ${Util.relativePath(nodeV8CoverageDir)}`);
130
- return 1;
131
- }
132
-
133
- const files = fs.readdirSync(nodeV8CoverageDir);
134
- for (const filename of files) {
135
- const content = fs.readFileSync(path.resolve(nodeV8CoverageDir, filename)).toString('utf-8');
136
- const json = JSON.parse(content);
137
- let coverageList = json.result;
138
-
139
- // for node sourcemap
140
- const sourceMapCache = json['source-map-cache'] || {};
141
-
142
- // filter node internal files
143
- coverageList = coverageList.filter((entry) => entry.url && entry.url.startsWith('file:'));
144
-
145
- if (!coverageList.length) {
146
- continue;
147
- }
148
- // attached source content
149
- coverageList.forEach((entry) => {
150
- // source content
151
- const filePath = fileURLToPath(entry.url);
152
- if (fs.existsSync(filePath)) {
153
- entry.source = fs.readFileSync(filePath).toString('utf8');
154
- }
155
-
156
- // sourcemap data
157
- const sourcemapData = sourceMapCache[entry.url];
158
- if (sourcemapData) {
159
- if (sourcemapData.data) {
160
- entry.sourceMap = resolveSourceMap(sourcemapData.data, entry.url);
161
- }
162
- // sourcemapData.lineLengths just for fake source file (can not parse to AST)
163
- if (!entry.source && sourcemapData.lineLengths) {
164
- // get runtime code with ts-node
165
- let source = '';
166
- sourcemapData.lineLengths.forEach((length) => {
167
- source += `${''.padEnd(length, '*')}\n`;
168
- });
169
- entry.fake = true;
170
- entry.source = source;
171
- }
172
- }
173
- });
174
-
175
- await coverageReport.add(coverageList);
176
- }
177
-
178
- await coverageReport.generate();
179
-
180
- // remove nodeV8CoverageDir
181
- if (options.logging !== 'debug') {
182
- cleanDir(nodeV8CoverageDir);
183
- }
184
-
185
- return process.exitCode;
186
- });
187
-
188
- };
189
-
190
- program
191
- .name('mcr')
192
- .description('CLI to generate coverage reports')
193
- .version(version)
194
- .argument('<command>', 'command to execute')
195
- .option('-c, --config <path>', 'custom config path')
196
- .option('-o, --outputDir <dir>', 'output dir for reports')
197
- .option('-r, --reports <name[,name]>', 'coverage reports to use')
198
- .option('-n, --name <name>', 'report name for title')
199
- .option('-i, --inputDir <dir>', 'input dir for merging raw files')
200
-
201
- .option('--entryFilter <pattern>', 'entry url filter')
202
- .option('--sourceFilter <pattern>', 'source path filter')
203
-
204
- .option('--outputFile <path>', 'output file for v8 report')
205
- .option('--inline', 'inline html for v8 report')
206
- .option('--assetsPath <path>', 'assets path if not inline')
207
-
208
- .option('--lcov', 'generate lcov.info file')
209
-
210
- .option('--logging <logging>', 'off, error, info, debug')
211
-
212
- .action((command, cliOptions) => {
213
- executeCommand(command, cliOptions);
214
- });
215
-
216
- program.parse();
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const EC = require('eight-colors');
6
+ const { fileURLToPath, pathToFileURL } = require('url');
7
+ const {
8
+ foregroundChild,
9
+ program
10
+ } = require('./packages/monocart-coverage-vendor.js');
11
+
12
+ const MCR = require('./index.js');
13
+ const Util = require('./utils/util.js');
14
+ const defaultOptions = require('./default/options.js');
15
+ const { resolveSourceMap } = require('./converter/collect-source-maps.js');
16
+
17
+ const version = require('../package.json').version;
18
+
19
+ const cleanDir = (dir) => {
20
+ Util.rmSync(dir);
21
+ };
22
+
23
+ const resolveConfigPath = (customConfigPath) => {
24
+
25
+ const configList = [
26
+ '.mcrrc',
27
+ 'mcr.config.json',
28
+ 'mcr.config.mjs',
29
+ 'mcr.config.cjs',
30
+ 'mcr.config.js'
31
+ ];
32
+
33
+ if (customConfigPath) {
34
+ configList.push(customConfigPath);
35
+ }
36
+
37
+ const existsList = configList.filter((p) => fs.existsSync(p));
38
+ if (!existsList.length) {
39
+ return;
40
+ }
41
+
42
+ // last one
43
+ const configPath = existsList.pop();
44
+ Util.logInfo(`Config: ${EC.cyan(configPath)}`);
45
+
46
+ return configPath;
47
+ };
48
+
49
+ const resolveConfigOptions = async (configPath) => {
50
+
51
+ // json format
52
+ const ext = path.extname(configPath);
53
+ if (ext === '.json' || configPath.slice(-2) === 'rc') {
54
+ return JSON.parse(Util.readFileSync(configPath));
55
+ }
56
+
57
+ let configOptions;
58
+ let err;
59
+ try {
60
+ configOptions = await import(pathToFileURL(configPath));
61
+ } catch (ee) {
62
+ err = ee;
63
+ }
64
+
65
+ if (!configOptions) {
66
+ Util.logError(`ERROR: failed to import "${configPath}" ${err.message} `);
67
+ return;
68
+ }
69
+
70
+ configOptions = configOptions.default || configOptions;
71
+
72
+ return configOptions;
73
+ };
74
+
75
+ const initOptions = async (cliOptions) => {
76
+
77
+ const configPath = resolveConfigPath(cliOptions.config);
78
+ if (configPath) {
79
+ const configOptions = await resolveConfigOptions(configPath);
80
+ if (configOptions) {
81
+ cliOptions = {
82
+ ... configOptions,
83
+ ... cliOptions
84
+ };
85
+ }
86
+ }
87
+
88
+ // report options
89
+ const options = {
90
+ ... defaultOptions
91
+ };
92
+ Object.keys(cliOptions).forEach((k) => {
93
+ if (Util.hasOwn(options, k)) {
94
+ options[k] = cliOptions[k];
95
+ }
96
+ });
97
+
98
+ return options;
99
+ };
100
+
101
+ const executeCommand = async (command, cliOptions) => {
102
+
103
+ const options = await initOptions(cliOptions);
104
+
105
+ Util.logInfo(`Execute: ${EC.cyan(command)}`);
106
+ // console.log(options);
107
+
108
+ const nodeV8CoverageDir = path.resolve(options.outputDir, '.v8-coverage');
109
+ process.env.NODE_V8_COVERAGE = nodeV8CoverageDir;
110
+
111
+ cleanDir(nodeV8CoverageDir);
112
+
113
+ // console.log('nodeV8CoverageDir', nodeV8CoverageDir);
114
+
115
+ const coverageReport = MCR(options);
116
+ coverageReport.cleanCache();
117
+
118
+ // on start hook
119
+ const onStart = cliOptions.onStart;
120
+ if (typeof onStart === 'function') {
121
+ await onStart(coverageReport);
122
+ }
123
+
124
+ foregroundChild(command, {
125
+ shell: true
126
+ }, async () => {
127
+
128
+ if (!fs.existsSync(nodeV8CoverageDir)) {
129
+ EC.logRed(`Not found coverage data: ${Util.relativePath(nodeV8CoverageDir)}`);
130
+ return 1;
131
+ }
132
+
133
+ const files = fs.readdirSync(nodeV8CoverageDir);
134
+ for (const filename of files) {
135
+ const content = fs.readFileSync(path.resolve(nodeV8CoverageDir, filename)).toString('utf-8');
136
+ const json = JSON.parse(content);
137
+ let coverageList = json.result;
138
+
139
+ // for node sourcemap
140
+ const sourceMapCache = json['source-map-cache'] || {};
141
+
142
+ // filter node internal files
143
+ coverageList = coverageList.filter((entry) => entry.url && entry.url.startsWith('file:'));
144
+
145
+ if (!coverageList.length) {
146
+ continue;
147
+ }
148
+ // attached source content
149
+ coverageList.forEach((entry) => {
150
+ // source content
151
+ const filePath = fileURLToPath(entry.url);
152
+ if (fs.existsSync(filePath)) {
153
+ entry.source = fs.readFileSync(filePath).toString('utf8');
154
+ }
155
+
156
+ // sourcemap data
157
+ const sourcemapData = sourceMapCache[entry.url];
158
+ if (sourcemapData) {
159
+ if (sourcemapData.data) {
160
+ entry.sourceMap = resolveSourceMap(sourcemapData.data, entry.url);
161
+ }
162
+ // sourcemapData.lineLengths just for fake source file (can not parse to AST)
163
+ if (!entry.source && sourcemapData.lineLengths) {
164
+ // get runtime code with ts-node
165
+ let source = '';
166
+ sourcemapData.lineLengths.forEach((length) => {
167
+ source += `${''.padEnd(length, '*')}\n`;
168
+ });
169
+ entry.fake = true;
170
+ entry.source = source;
171
+ }
172
+ }
173
+ });
174
+
175
+ await coverageReport.add(coverageList);
176
+ }
177
+
178
+ await coverageReport.generate();
179
+
180
+ // remove nodeV8CoverageDir
181
+ if (options.logging !== 'debug') {
182
+ cleanDir(nodeV8CoverageDir);
183
+ }
184
+
185
+ return process.exitCode;
186
+ });
187
+
188
+ };
189
+
190
+ program
191
+ .name('mcr')
192
+ .description('CLI to generate coverage reports')
193
+ .version(version)
194
+ .argument('<command>', 'command to execute')
195
+ .option('-c, --config <path>', 'custom config path')
196
+ .option('-o, --outputDir <dir>', 'output dir for reports')
197
+ .option('-r, --reports <name[,name]>', 'coverage reports to use')
198
+ .option('-n, --name <name>', 'report name for title')
199
+ .option('-i, --inputDir <dir>', 'input dir for merging raw files')
200
+
201
+ .option('--entryFilter <pattern>', 'entry url filter')
202
+ .option('--sourceFilter <pattern>', 'source path filter')
203
+
204
+ .option('--outputFile <path>', 'output file for v8 report')
205
+ .option('--inline', 'inline html for v8 report')
206
+ .option('--assetsPath <path>', 'assets path if not inline')
207
+
208
+ .option('--lcov', 'generate lcov.info file')
209
+
210
+ .option('--logging <logging>', 'off, error, info, debug')
211
+
212
+ .action((command, cliOptions) => {
213
+ executeCommand(command, cliOptions);
214
+ });
215
+
216
+ program.parse();