@naturalcycles/dev-lib 20.18.2 → 20.20.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/cfg/summaryOnlyReporter.js +26 -0
- package/cfg/vitest.config.d.ts +4 -1
- package/cfg/vitest.config.js +40 -24
- package/dist/bin/dev-lib.js +25 -17
- package/dist/lint.util.d.ts +3 -1
- package/dist/lint.util.js +14 -10
- package/package.json +5 -4
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { _ms } from '@naturalcycles/js-lib/datetime'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A minimal reporter that only shows failures and the final summary.
|
|
5
|
+
* No per-test, no per-file output - just failures and final summary.
|
|
6
|
+
*
|
|
7
|
+
* Use via: VITEST_REPORTER=summary vitest run
|
|
8
|
+
*/
|
|
9
|
+
export class SummaryOnlyReporter {
|
|
10
|
+
onTestRunEnd(testModules) {
|
|
11
|
+
let files = 0
|
|
12
|
+
let duration = 0
|
|
13
|
+
|
|
14
|
+
for (const mod of testModules) {
|
|
15
|
+
files++
|
|
16
|
+
duration += mod.diagnostic().duration
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
console.log()
|
|
20
|
+
console.log(` Files: ${files}`)
|
|
21
|
+
console.log(` Duration: ${_ms(duration)}`)
|
|
22
|
+
console.log()
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default SummaryOnlyReporter
|
package/cfg/vitest.config.d.ts
CHANGED
|
@@ -21,4 +21,7 @@ export function defineVitestConfig(config?: Partial<ViteUserConfig>, cwd?: strin
|
|
|
21
21
|
export function getSharedConfig(cwd?: string): InlineConfig
|
|
22
22
|
|
|
23
23
|
export const CollectReporter: any
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
export class SummaryReporter {}
|
|
26
|
+
|
|
27
|
+
export class SummaryOnlyReporter {}
|
package/cfg/vitest.config.js
CHANGED
|
@@ -2,8 +2,10 @@ import fs from 'node:fs'
|
|
|
2
2
|
import { VitestAlphabeticSequencer } from './vitestAlphabeticSequencer.js'
|
|
3
3
|
import { defineConfig } from 'vitest/config'
|
|
4
4
|
import { SummaryReporter } from './summaryReporter.js'
|
|
5
|
+
import { SummaryOnlyReporter } from './summaryOnlyReporter.js'
|
|
5
6
|
export { SummaryReporter } from './summaryReporter.js'
|
|
6
7
|
export { CollectReporter } from './collectReporter.js'
|
|
8
|
+
export { SummaryOnlyReporter } from './summaryOnlyReporter.js'
|
|
7
9
|
|
|
8
10
|
const runsInIDE = doesItRunInIDE()
|
|
9
11
|
const testType = getTestType(runsInIDE)
|
|
@@ -47,19 +49,19 @@ export function defineVitestConfig(config, cwd) {
|
|
|
47
49
|
|
|
48
50
|
const { silent, pool, maxWorkers, isolate } = mergedConfig.test
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
52
|
+
// In workspace mode, cwd differs from process.cwd() (which is the monorepo root)
|
|
53
|
+
const isWorkspaceMode = cwd && process.cwd() !== cwd
|
|
54
|
+
if (!isWorkspaceMode) {
|
|
55
|
+
console.log({
|
|
56
|
+
testType,
|
|
57
|
+
silent,
|
|
58
|
+
isCI,
|
|
59
|
+
runsInIDE,
|
|
60
|
+
pool,
|
|
61
|
+
isolate,
|
|
62
|
+
maxWorkers,
|
|
63
|
+
})
|
|
64
|
+
}
|
|
63
65
|
|
|
64
66
|
return mergedConfig
|
|
65
67
|
}
|
|
@@ -90,17 +92,7 @@ export function getSharedConfig(cwd) {
|
|
|
90
92
|
},
|
|
91
93
|
include,
|
|
92
94
|
exclude,
|
|
93
|
-
reporters:
|
|
94
|
-
'default',
|
|
95
|
-
new SummaryReporter(),
|
|
96
|
-
junitReporterEnabled && [
|
|
97
|
-
'junit',
|
|
98
|
-
{
|
|
99
|
-
suiteName: `${testType} tests`,
|
|
100
|
-
// classNameTemplate: '{filename} - {classname}',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
103
|
-
].filter(Boolean),
|
|
95
|
+
reporters: getReporters(junitReporterEnabled, testType),
|
|
104
96
|
// outputFile location is specified for compatibility with the previous jest config
|
|
105
97
|
outputFile: junitReporterEnabled ? `./tmp/jest/${testType}.xml` : undefined,
|
|
106
98
|
coverage: {
|
|
@@ -130,6 +122,30 @@ export function getSharedConfig(cwd) {
|
|
|
130
122
|
}
|
|
131
123
|
}
|
|
132
124
|
|
|
125
|
+
function getReporters(junitReporterEnabled, testType) {
|
|
126
|
+
// VITEST_REPORTER env var allows overriding the default reporter
|
|
127
|
+
// e.g., VITEST_REPORTER=summary for minimal output
|
|
128
|
+
const { VITEST_REPORTER, CLAUDE_CODE } = process.env
|
|
129
|
+
|
|
130
|
+
if (VITEST_REPORTER === 'summary' || CLAUDE_CODE) {
|
|
131
|
+
return [new SummaryOnlyReporter()]
|
|
132
|
+
}
|
|
133
|
+
if (VITEST_REPORTER === 'dot') {
|
|
134
|
+
return ['dot']
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return [
|
|
138
|
+
'default',
|
|
139
|
+
new SummaryReporter(),
|
|
140
|
+
junitReporterEnabled && [
|
|
141
|
+
'junit',
|
|
142
|
+
{
|
|
143
|
+
suiteName: `${testType} tests`,
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
].filter(Boolean)
|
|
147
|
+
}
|
|
148
|
+
|
|
133
149
|
function doesItRunInIDE() {
|
|
134
150
|
// example command line below:
|
|
135
151
|
// /usr/local/bin/node /Users/some/Idea/some/node_modules/vitest/vitest.mjs --run --reporter /Users/some/Library/Application Support/JetBrains/IntelliJIdea2025.2/plugins/javascript-plugin/helpers/vitest-intellij/node_modules/vitest-intellij-reporter-safe.js --testNamePattern=^ ?case 001: empty data$ /Users/some/Idea/some/src/some/some.integration.test.ts
|
package/dist/bin/dev-lib.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { select, Separator } from '@inquirer/prompts';
|
|
3
2
|
import { _by } from '@naturalcycles/js-lib/array/array.util.js';
|
|
4
3
|
import { _assert } from '@naturalcycles/js-lib/error/assert.js';
|
|
5
4
|
import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
|
|
@@ -9,8 +8,12 @@ import { runCommitlint } from '../commitlint.js';
|
|
|
9
8
|
import { eslintAll, lintAllCommand, lintStagedCommand, requireOxlintConfig, runBiome, runOxlint, runPrettier, stylelintAll, } from '../lint.util.js';
|
|
10
9
|
import { runTest } from '../test.util.js';
|
|
11
10
|
const commands = [
|
|
12
|
-
new Separator(), // build
|
|
13
11
|
{ name: 'check', fn: check, desc: '"Run all possible checks": lint, typecheck, then test.' },
|
|
12
|
+
{
|
|
13
|
+
name: 'quick-check',
|
|
14
|
+
fn: quickCheck,
|
|
15
|
+
desc: 'Like check, but without slow parts, to perform preliminary checks',
|
|
16
|
+
},
|
|
14
17
|
{ name: 'bt', fn: bt, desc: 'Build & Test: run "typecheck" (via oxlint) and then "test".' },
|
|
15
18
|
{
|
|
16
19
|
name: 'typecheck',
|
|
@@ -42,7 +45,6 @@ const commands = [
|
|
|
42
45
|
fn: cleanBuild,
|
|
43
46
|
desc: 'Cleans ./dist, then runs the build.',
|
|
44
47
|
},
|
|
45
|
-
new Separator(), // test
|
|
46
48
|
{ name: 'test', fn: runTest, desc: 'Run vitest for *.test.ts files.' },
|
|
47
49
|
{
|
|
48
50
|
name: 'test-integration',
|
|
@@ -59,7 +61,6 @@ const commands = [
|
|
|
59
61
|
fn: () => runTest({ leaks: true }),
|
|
60
62
|
desc: 'Run vitest --detectLeaks for *.test.ts files.',
|
|
61
63
|
},
|
|
62
|
-
new Separator(), // lint
|
|
63
64
|
{
|
|
64
65
|
name: 'lint',
|
|
65
66
|
fn: lintAllCommand,
|
|
@@ -107,7 +108,6 @@ const commands = [
|
|
|
107
108
|
},
|
|
108
109
|
{ name: 'stylelint-no-fix', cliOnly: true, fn: () => stylelintAll(false) },
|
|
109
110
|
{ name: 'commitlint', fn: runCommitlint, desc: 'Run commitlint.', cliOnly: true },
|
|
110
|
-
new Separator(), // interactive-only
|
|
111
111
|
{
|
|
112
112
|
name: 'exit',
|
|
113
113
|
fn: () => console.log('see you!'),
|
|
@@ -127,27 +127,31 @@ const commands = [
|
|
|
127
127
|
// })
|
|
128
128
|
// },
|
|
129
129
|
];
|
|
130
|
-
const commandMap = _by(commands
|
|
130
|
+
const commandMap = _by(commands, c => c.name);
|
|
131
131
|
const { CI } = process.env;
|
|
132
132
|
runScript(async () => {
|
|
133
133
|
let cmd = process.argv.find(s => commandMap[s] && !commandMap[s].interactiveOnly);
|
|
134
134
|
if (!cmd) {
|
|
135
135
|
// interactive mode
|
|
136
136
|
_assert(!CI, 'interactive dev-lib should not be run in CI');
|
|
137
|
-
|
|
137
|
+
const { default: prompts } = await import('prompts');
|
|
138
|
+
const response = await prompts({
|
|
139
|
+
type: 'select',
|
|
140
|
+
name: 'cmd',
|
|
138
141
|
message: 'Select command',
|
|
139
|
-
|
|
142
|
+
// @ts-expect-error types are wrong
|
|
143
|
+
optionsPerPage: 30,
|
|
140
144
|
choices: commands
|
|
141
|
-
.filter(c =>
|
|
142
|
-
.map(c => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
description: c.desc,
|
|
148
|
-
};
|
|
149
|
-
}),
|
|
145
|
+
.filter(c => !c.cliOnly)
|
|
146
|
+
.map(c => ({
|
|
147
|
+
title: c.name,
|
|
148
|
+
value: c.name,
|
|
149
|
+
description: c.desc,
|
|
150
|
+
})),
|
|
150
151
|
});
|
|
152
|
+
cmd = response.cmd;
|
|
153
|
+
if (!cmd)
|
|
154
|
+
return; // user cancelled
|
|
151
155
|
}
|
|
152
156
|
await commandMap[cmd].fn();
|
|
153
157
|
});
|
|
@@ -155,6 +159,10 @@ async function check() {
|
|
|
155
159
|
await lintAllCommand();
|
|
156
160
|
runTest();
|
|
157
161
|
}
|
|
162
|
+
async function quickCheck() {
|
|
163
|
+
await lintAllCommand(false);
|
|
164
|
+
runTest();
|
|
165
|
+
}
|
|
158
166
|
async function bt() {
|
|
159
167
|
await typecheckWithOxlint();
|
|
160
168
|
runTest();
|
package/dist/lint.util.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { SemVerString } from '@naturalcycles/js-lib/types';
|
|
2
2
|
/**
|
|
3
3
|
* Run all linters.
|
|
4
|
+
*
|
|
5
|
+
* If full=false - the "slow" linters are skipped.
|
|
4
6
|
*/
|
|
5
|
-
export declare function lintAllCommand(): Promise<void>;
|
|
7
|
+
export declare function lintAllCommand(full?: boolean): Promise<void>;
|
|
6
8
|
interface EslintAllOptions {
|
|
7
9
|
ext?: string;
|
|
8
10
|
fix?: boolean;
|
package/dist/lint.util.js
CHANGED
|
@@ -16,8 +16,10 @@ import { cfgDir } from './paths.js';
|
|
|
16
16
|
const { CI, ESLINT_CONCURRENCY } = process.env;
|
|
17
17
|
/**
|
|
18
18
|
* Run all linters.
|
|
19
|
+
*
|
|
20
|
+
* If full=false - the "slow" linters are skipped.
|
|
19
21
|
*/
|
|
20
|
-
export async function lintAllCommand() {
|
|
22
|
+
export async function lintAllCommand(full = true) {
|
|
21
23
|
const started = Date.now();
|
|
22
24
|
// const { commitOnChanges, failOnChanges } = _yargs().options({
|
|
23
25
|
// commitOnChanges: {
|
|
@@ -44,16 +46,18 @@ export async function lintAllCommand() {
|
|
|
44
46
|
runBiome(fix);
|
|
45
47
|
runOxlint(fix);
|
|
46
48
|
// From this point we start the "slow" linters, with ESLint leading the way
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
existsSync(`node_modules/stylelint
|
|
53
|
-
|
|
49
|
+
if (full) {
|
|
50
|
+
// We run eslint BEFORE Prettier, because eslint can delete e.g unused imports.
|
|
51
|
+
eslintAll({
|
|
52
|
+
fix,
|
|
53
|
+
});
|
|
54
|
+
if (existsSync(`node_modules/stylelint`) &&
|
|
55
|
+
existsSync(`node_modules/stylelint-config-standard-scss`)) {
|
|
56
|
+
stylelintAll(fix);
|
|
57
|
+
}
|
|
58
|
+
runPrettier({ fix });
|
|
59
|
+
await runKTLint(fix);
|
|
54
60
|
}
|
|
55
|
-
runPrettier({ fix });
|
|
56
|
-
await runKTLint(fix);
|
|
57
61
|
console.log(`${check(true)}${white(`lint-all`)} ${dimGrey(`took ` + _since(started))}`);
|
|
58
62
|
// if (needToTrackChanges) {
|
|
59
63
|
// const gitStatusAfter = gitStatus()
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/dev-lib",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "20.
|
|
4
|
+
"version": "20.20.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@biomejs/biome": "^2",
|
|
7
7
|
"@eslint/js": "^9",
|
|
8
|
-
"
|
|
8
|
+
"prompts": "^2",
|
|
9
9
|
"@naturalcycles/js-lib": "^15",
|
|
10
10
|
"@naturalcycles/nodejs-lib": "^15",
|
|
11
11
|
"@vitest/coverage-v8": "^4",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"eslint-plugin-simple-import-sort": "^12",
|
|
17
17
|
"eslint-plugin-unicorn": "^62",
|
|
18
18
|
"eslint-plugin-vue": "^10",
|
|
19
|
-
"globals": "^
|
|
19
|
+
"globals": "^17",
|
|
20
20
|
"lint-staged": "^16",
|
|
21
21
|
"micromatch": "^4",
|
|
22
22
|
"mitm": "^1",
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/mitm": "^1",
|
|
45
|
-
"@types/node": "^25"
|
|
45
|
+
"@types/node": "^25",
|
|
46
|
+
"@types/prompts": "^2"
|
|
46
47
|
},
|
|
47
48
|
"exports": {
|
|
48
49
|
"./cfg/": "./cfg/",
|