@vitest-agent/plugin 5.6.2 → 6.0.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/index.d.ts +58 -113
- package/index.js +1 -2
- package/layers/CoverageAnalyzerLive.js +3 -3
- package/package.json +20 -11
- package/plugin.js +13 -36
- package/reporter.js +123 -25
- package/utils/collect-performance-hints.js +205 -0
- package/utils/discover-projects.js +13 -47
- package/utils/discover-strategy.js +7 -15
- package/utils/failure-summary.js +78 -0
- package/utils/find-test-files.js +65 -82
- package/utils/is-test-shaped-package.js +4 -3
- package/utils/resolve-coverage-dir-isolation.js +1 -1
- package/utils/run-diagnostics.js +24 -0
- package/utils/run-script-lock.js +77 -233
- package/utils/runs-in-ci.js +15 -0
- package/utils/stray-output-capture.js +27 -127
- package/utils/vitest-diagnostics.js +173 -0
- package/utils/walker-fs.js +8 -23
- package/version.js +1 -1
package/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { AgentPluginOptions, AgentReporterOptions, ConsoleMode, CoverageBaseline
|
|
|
4
4
|
import { Context, Effect, Layer, Option } from "effect";
|
|
5
5
|
import { TestProjectInlineConfiguration, TestTagDefinition } from "vitest/config";
|
|
6
6
|
import { ResolvedConfig, VitestPluginContext } from "vitest/node";
|
|
7
|
+
import { WalkerSyncOps, WalkerSyncOps as WalkerSyncOps$1 } from "@effected/walker";
|
|
7
8
|
import { WorkspacesSyncOptions } from "@effected/workspaces/node-sync";
|
|
8
9
|
import { SourceMap } from "magic-string";
|
|
9
10
|
/**
|
|
@@ -29,83 +30,6 @@ export declare class Tag {
|
|
|
29
30
|
*/
|
|
30
31
|
static make(name: string, options?: TagOptions): Tag;
|
|
31
32
|
}
|
|
32
|
-
/**
|
|
33
|
-
* The filesystem operations the discovery walkers need, supplied by the
|
|
34
|
-
* caller. Node's built-ins satisfy it directly via {@link nodeWalkerFs}, which
|
|
35
|
-
* is what every production call site uses.
|
|
36
|
-
*
|
|
37
|
-
* The port exists because the walkers used to call `node:fs/promises` outright,
|
|
38
|
-
* which made them untestable against anything but a real temporary directory —
|
|
39
|
-
* a virtual filesystem cannot intercept a direct `node:fs` call. Every test in
|
|
40
|
-
* this package that exercised discovery therefore had to build, populate and
|
|
41
|
-
* tear down a real tmp tree.
|
|
42
|
-
*
|
|
43
|
-
* Deliberately NOT `fs.promises`-shaped: the walkers need exactly two
|
|
44
|
-
* operations, and a wider surface would invite call sites to reach past the
|
|
45
|
-
* port. It is also NOT shaped like `@effected/workspaces`'s `SyncFileSystem`
|
|
46
|
-
* (which this package consumes separately, in `discover-projects.ts`) — that
|
|
47
|
-
* port answers entry *names*, and the walkers need the entry *type* that
|
|
48
|
-
* `readdir({ withFileTypes: true })` returns in the same syscall. Reading names
|
|
49
|
-
* and then stat-ing each one is the syscall-doubling this module exists to
|
|
50
|
-
* avoid; see {@link WalkerEntry}.
|
|
51
|
-
*
|
|
52
|
-
* @packageDocumentation
|
|
53
|
-
*/
|
|
54
|
-
/**
|
|
55
|
-
* One directory entry, carrying the name and type together.
|
|
56
|
-
*
|
|
57
|
-
* A structural subset of Node's `Dirent`, so a real `Dirent` satisfies it
|
|
58
|
-
* verbatim and `readdir({ withFileTypes: true })` needs no adaptation.
|
|
59
|
-
* @public
|
|
60
|
-
*/
|
|
61
|
-
interface WalkerEntry {
|
|
62
|
-
/** The entry's own name, not a path. */
|
|
63
|
-
readonly name: string;
|
|
64
|
-
/** Whether this entry is a regular file. */
|
|
65
|
-
readonly isFile: () => boolean;
|
|
66
|
-
/** Whether this entry is a directory. */
|
|
67
|
-
readonly isDirectory: () => boolean;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* The filesystem operations the discovery walkers need.
|
|
71
|
-
*
|
|
72
|
-
* Both operations may reject; every walker absorbs a rejection as "this path
|
|
73
|
-
* contributes nothing" rather than propagating it, matching the behavior the
|
|
74
|
-
* `node:fs` calls had when they were inline.
|
|
75
|
-
* @public
|
|
76
|
-
*/
|
|
77
|
-
interface WalkerFileSystem {
|
|
78
|
-
/**
|
|
79
|
-
* The entries inside the directory at `dir`, with their types. May reject —
|
|
80
|
-
* a rejection reads as an unreadable directory and skips it.
|
|
81
|
-
*/
|
|
82
|
-
readonly readDirectory: (dir: string) => Promise<ReadonlyArray<WalkerEntry>>;
|
|
83
|
-
/**
|
|
84
|
-
* The type of the entry at `path`, or `null` when it does not exist or
|
|
85
|
-
* cannot be read. Never rejects.
|
|
86
|
-
*/
|
|
87
|
-
readonly statEntry: (path: string) => Promise<WalkerEntryStat | null>;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* What the walkers read off a `stat`: the entry's type, plus the modification
|
|
91
|
-
* time the discovery cache's directory signature is built from.
|
|
92
|
-
* @public
|
|
93
|
-
*/
|
|
94
|
-
interface WalkerEntryStat {
|
|
95
|
-
/** Whether the path holds a regular file. */
|
|
96
|
-
readonly isFile: boolean;
|
|
97
|
-
/** Whether the path holds a directory. */
|
|
98
|
-
readonly isDirectory: boolean;
|
|
99
|
-
/** Modification time in milliseconds since the epoch. */
|
|
100
|
-
readonly mtimeMs: number;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* {@link WalkerFileSystem} over `node:fs/promises` — the binding every
|
|
104
|
-
* production call site uses, and the default when a walker is called without
|
|
105
|
-
* an explicit port.
|
|
106
|
-
* @public
|
|
107
|
-
*/
|
|
108
|
-
export declare const nodeWalkerFs: WalkerFileSystem;
|
|
109
33
|
/**
|
|
110
34
|
* Resolved metadata about a discovered test module.
|
|
111
35
|
* @public
|
|
@@ -148,11 +72,12 @@ interface DiscoverInput {
|
|
|
148
72
|
/** Parsed `package.json` contents, when available. */
|
|
149
73
|
readonly packageJson?: PackageJson;
|
|
150
74
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
75
|
+
* Sync filesystem the walkers read through (`@effected/walker`'s
|
|
76
|
+
* `WalkerSyncOps`). Defaults to its `nodeWalkerSyncOps` when omitted, which
|
|
77
|
+
* is what every production call site does; tests inject a virtual volume
|
|
78
|
+
* instead of building a real temporary directory.
|
|
154
79
|
*/
|
|
155
|
-
readonly fs?:
|
|
80
|
+
readonly fs?: WalkerSyncOps$1;
|
|
156
81
|
}
|
|
157
82
|
/**
|
|
158
83
|
* Context object passed to a `ClassifyFn`.
|
|
@@ -249,10 +174,12 @@ interface DiscoverProjectsOptions {
|
|
|
249
174
|
readonly path: string;
|
|
250
175
|
}>;
|
|
251
176
|
/**
|
|
252
|
-
*
|
|
253
|
-
*
|
|
177
|
+
* Sync filesystem the test-file and signature walks read through
|
|
178
|
+
* (`@effected/walker`'s `WalkerSyncOps`). Defaults to its
|
|
179
|
+
* `nodeWalkerSyncOps`; tests inject a virtual volume instead of a real tmp
|
|
180
|
+
* tree.
|
|
254
181
|
*/
|
|
255
|
-
readonly fs?:
|
|
182
|
+
readonly fs?: WalkerSyncOps$1;
|
|
256
183
|
/**
|
|
257
184
|
* Sync operations `@effected/workspaces` resolves the workspace root and
|
|
258
185
|
* package list through. Defaults to its `nodeSyncOps` binding.
|
|
@@ -532,26 +459,35 @@ export declare namespace AgentPlugin {
|
|
|
532
459
|
configure?: ProjectConfigureMap;
|
|
533
460
|
}): DiscoverBuilder;
|
|
534
461
|
/**
|
|
535
|
-
* Run a
|
|
536
|
-
*
|
|
537
|
-
*
|
|
462
|
+
* Run a build step once, suppressing all output unless it fails. Designed
|
|
463
|
+
* for Vitest `globalSetup` files to run build steps or other preparatory
|
|
464
|
+
* scripts without polluting agent stdout.
|
|
538
465
|
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
* (`DEFAULT_BUILT_RECENTLY_MS`) rather than repeating it.
|
|
466
|
+
* A string `command` runs through the platform shell (`/bin/sh -c`, or
|
|
467
|
+
* `cmd.exe /d /s /c` on Windows), as `execSync` ran it; an argv array runs
|
|
468
|
+
* the executable directly, with no shell. Output is captured to temporary
|
|
469
|
+
* files, so a chatty build never trips a buffer limit; the trailing 1 MiB
|
|
470
|
+
* of each stream is kept for the failure.
|
|
545
471
|
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
472
|
+
* Concurrent invocations of the same command from the same directory (two
|
|
473
|
+
* `vitest` runs started in one checkout at once) serialize through
|
|
474
|
+
* `@effected/commands`' `RunOnce` file lock, keyed by the working directory
|
|
475
|
+
* the command runs in plus the command (issue #191): the first
|
|
476
|
+
* caller runs the command, and a concurrent caller that waited on it skips
|
|
477
|
+
* its own run once that owner succeeds. A previous, sequential run is never
|
|
478
|
+
* trusted, so an edit followed by a re-run always rebuilds, unless
|
|
479
|
+
* `VITEST_AGENT_RUNSCRIPT_BUILT_RECENTLY_MS` opts into trusting a marker
|
|
480
|
+
* that young.
|
|
481
|
+
*
|
|
482
|
+
* Serialization is best-effort by design: a waiter still blocked after the
|
|
483
|
+
* wait timeout (10 minutes), or a caller that cannot create the lock at
|
|
484
|
+
* all, runs the command unserialized rather than hanging or failing.
|
|
485
|
+
* `VITEST_AGENT_RUNSCRIPT_LOCK_STALE_MS`, `_LOCK_WAIT_TIMEOUT_MS` and
|
|
486
|
+
* `_LOCK_POLL_MS` tune the protocol's timings.
|
|
551
487
|
*
|
|
552
488
|
* On failure the captured stderr and stdout are written to their respective
|
|
553
|
-
* streams before
|
|
554
|
-
* surfaced in CI logs.
|
|
489
|
+
* streams before the `CommandFailedError` is thrown, so the error is still
|
|
490
|
+
* visible to humans and surfaced in CI logs.
|
|
555
491
|
*
|
|
556
492
|
* ```ts
|
|
557
493
|
* // vitest.setup.ts
|
|
@@ -561,7 +497,7 @@ export declare namespace AgentPlugin {
|
|
|
561
497
|
* }
|
|
562
498
|
* ```
|
|
563
499
|
*/
|
|
564
|
-
function runScript(command: string): void;
|
|
500
|
+
function runScript(command: string | readonly [string, ...string[]]): void;
|
|
565
501
|
}
|
|
566
502
|
/**
|
|
567
503
|
* Constructor argument shape for {@link AgentReporter}.
|
|
@@ -731,6 +667,12 @@ export declare class AgentReporter {
|
|
|
731
667
|
* (issue #576).
|
|
732
668
|
*/
|
|
733
669
|
private rendered;
|
|
670
|
+
/**
|
|
671
|
+
* `performance.now()` at this run's `onTestRunStart`, for the run's
|
|
672
|
+
* execution time (issue #544). `undefined` when `onTestRunStart` never
|
|
673
|
+
* fired (tests invoking `onTestRunEnd` directly).
|
|
674
|
+
*/
|
|
675
|
+
private runStartedAt;
|
|
734
676
|
/**
|
|
735
677
|
* Stored Vitest instance from {@link AgentReporter.onInit | onInit}.
|
|
736
678
|
*
|
|
@@ -1307,27 +1249,30 @@ export declare function classifyByDirectory(dirMap: Record<string, ReadonlyArray
|
|
|
1307
1249
|
*/
|
|
1308
1250
|
export declare function combineClassifiers(...fns: ReadonlyArray<ClassifyFn>): ClassifyFn;
|
|
1309
1251
|
/**
|
|
1310
|
-
*
|
|
1252
|
+
* File walker that returns matched absolute paths.
|
|
1311
1253
|
*
|
|
1312
|
-
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1316
|
-
*
|
|
1254
|
+
* Expands each pattern under `dir` with `@effected/walker`'s `descendSync`
|
|
1255
|
+
* over `ops` (default: `nodeWalkerSyncOps`). Skips `node_modules`, `.git`, and
|
|
1256
|
+
* `dist` directories, follows symlinked directories (a link loop is cut by
|
|
1257
|
+
* the walker's cycle guard), and does not descend past a nested
|
|
1258
|
+
* `package.json` boundary (any directory other than `dir` itself that has its
|
|
1259
|
+
* own `package.json` is treated as an independent unit — its files belong to
|
|
1260
|
+
* a separate discovery pass, not this one). The package-boundary rule applies
|
|
1317
1261
|
* to every supplied pattern, not just an unanchored `**\/` one — an anchored
|
|
1318
1262
|
* pattern like `"src/**\/*.test.ts"` will not match a test file under a
|
|
1319
1263
|
* nested package.json even though the pattern itself never reaches past
|
|
1320
|
-
* `src
|
|
1321
|
-
*
|
|
1322
|
-
*
|
|
1264
|
+
* `src/`. Matches files against the supplied glob patterns relative to `dir`
|
|
1265
|
+
* (e.g. `"src/**\/*.test.ts"`); a pattern that fails to compile matches
|
|
1266
|
+
* nothing.
|
|
1323
1267
|
*
|
|
1324
1268
|
* Returns an empty array if `dir` does not exist or no files match.
|
|
1325
1269
|
* @param dir - Absolute path to the directory to walk
|
|
1326
1270
|
* @param patterns - Glob patterns to match against (relative to `dir`)
|
|
1327
|
-
* @
|
|
1271
|
+
* @param ops - The sync filesystem the walk reads through
|
|
1272
|
+
* @returns Absolute paths of matched test files, each pattern's matches sorted, deduplicated across patterns
|
|
1328
1273
|
* @public
|
|
1329
1274
|
*/
|
|
1330
|
-
export declare function findTestFiles(dir: string, patterns: ReadonlyArray<string>,
|
|
1275
|
+
export declare function findTestFiles(dir: string, patterns: ReadonlyArray<string>, ops?: WalkerSyncOps$1): Promise<ReadonlyArray<string>>;
|
|
1331
1276
|
/**
|
|
1332
1277
|
* Options passed to `CoverageAnalyzer.process` and `CoverageAnalyzer.processScoped`.
|
|
1333
1278
|
*
|
|
@@ -1598,5 +1543,5 @@ export declare const COVERAGE_AUTOUPDATE: Readonly<{
|
|
|
1598
1543
|
strict: (next: number, previous: number) => number;
|
|
1599
1544
|
lenient: (next: number, previous: number) => number;
|
|
1600
1545
|
}>;
|
|
1601
|
-
export { type AddProjectInput, type AgentPluginConstructorOptions, type AgentReporterConstructorOptions, type ClassifyContext, type ClassifyFn, type CoverageInput, CoverageLevel, type CoverageLevelName, type CoverageLevelPreset, type CoverageOptions, type DiscoverBuilder, type DiscoverInput, type PackageJson as DiscoverPackageJson, type DiscoverProjectsOptions, type DiscoverProjectsResult, type DiscoverResult, type DiscoverStrategyCreateOptions, type DiscoverStrategyExtendOptions, type InjectTagsResult, type ModuleInfo, type ProjectConfigureMap, type ProjectTestOverrides, type TagOptions, type ValidationError, type ValidationInfo, type ValidationInput, type ValidationResult, type ValidationWarning, type VitestErrorLike, type VitestStackFrameLike, type VitestThresholdsInput, type
|
|
1546
|
+
export { type AddProjectInput, type AgentPluginConstructorOptions, type AgentReporterConstructorOptions, type ClassifyContext, type ClassifyFn, type CoverageInput, CoverageLevel, type CoverageLevelName, type CoverageLevelPreset, type CoverageOptions, type DiscoverBuilder, type DiscoverInput, type PackageJson as DiscoverPackageJson, type DiscoverProjectsOptions, type DiscoverProjectsResult, type DiscoverResult, type DiscoverStrategyCreateOptions, type DiscoverStrategyExtendOptions, type InjectTagsResult, type ModuleInfo, type ProjectConfigureMap, type ProjectTestOverrides, type TagOptions, type ValidationError, type ValidationInfo, type ValidationInput, type ValidationResult, type ValidationWarning, type VitestErrorLike, type VitestStackFrameLike, type VitestThresholdsInput, type WalkerSyncOps, resolveCoverageInput, validateCoverageConfig };
|
|
1602
1547
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -9,7 +9,6 @@ import { captureSettings, hashSettings } from "./utils/capture-settings.js";
|
|
|
9
9
|
import { processFailure } from "./utils/process-failure.js";
|
|
10
10
|
import { ConfigurationError } from "./utils/configuration-error.js";
|
|
11
11
|
import { AgentReporter } from "./reporter.js";
|
|
12
|
-
import { nodeWalkerFs } from "./utils/walker-fs.js";
|
|
13
12
|
import { findTestFiles } from "./utils/find-test-files.js";
|
|
14
13
|
import { Tag } from "./utils/tag.js";
|
|
15
14
|
import { DefaultDiscoverStrategy, DiscoverStrategy } from "./utils/discover-strategy.js";
|
|
@@ -30,4 +29,4 @@ const COVERAGE_LEVELS_PER_FILE = AgentPlugin.COVERAGE_LEVELS_PER_FILE;
|
|
|
30
29
|
/** Auto-update tolerance functions for `coverage.thresholds.autoUpdate`. Mirrors `AgentPlugin.COVERAGE_AUTOUPDATE`. @public */
|
|
31
30
|
const COVERAGE_AUTOUPDATE = AgentPlugin.COVERAGE_AUTOUPDATE;
|
|
32
31
|
|
|
33
|
-
export { AgentPlugin, AgentReporter, CONSOLE_REPORTERS, COVERAGE_AUTOUPDATE, COVERAGE_LEVELS, COVERAGE_LEVELS_PER_FILE, CURRENT_PLUGIN_VERSION, ConfigValidation, ConfigValidationLive, ConfigValidationTest, ConfigurationError, CoverageAnalyzer, CoverageAnalyzerLive, CoverageAnalyzerTest, CoverageLevel, DefaultDiscoverStrategy, DiscoverStrategy, ReporterLive, Tag, applyProjectOverrides, captureEnvVars, captureSettings, classifyByDirectory, classifyByFilename, combineClassifiers, discoverProjects, findTestFiles, hashSettings,
|
|
32
|
+
export { AgentPlugin, AgentReporter, CONSOLE_REPORTERS, COVERAGE_AUTOUPDATE, COVERAGE_LEVELS, COVERAGE_LEVELS_PER_FILE, CURRENT_PLUGIN_VERSION, ConfigValidation, ConfigValidationLive, ConfigValidationTest, ConfigurationError, CoverageAnalyzer, CoverageAnalyzerLive, CoverageAnalyzerTest, CoverageLevel, DefaultDiscoverStrategy, DiscoverStrategy, ReporterLive, Tag, applyProjectOverrides, captureEnvVars, captureSettings, classifyByDirectory, classifyByFilename, combineClassifiers, discoverProjects, findTestFiles, hashSettings, processFailure, resolveCoverageInput, resolveThresholds, stripConsoleReporters, validateCoverageConfig };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CoverageAnalyzer } from "../services/CoverageAnalyzer.js";
|
|
2
2
|
import { toPosixPath } from "../utils/to-posix-path.js";
|
|
3
3
|
import { relative } from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import { Fmt } from "@effected/cli";
|
|
5
5
|
import { Effect, Layer, Option, Result } from "effect";
|
|
6
6
|
import { GlobPattern } from "@effected/glob";
|
|
7
7
|
|
|
@@ -253,7 +253,7 @@ function processCoverageInternal(coverageMap, options, testedFiles) {
|
|
|
253
253
|
if (scoped && !testedFileSet?.has(toPosixPath(filePath))) continue;
|
|
254
254
|
const isBelowThreshold = isBelowMetricThresholds(fileStats, resolveEffectivePerFileThresholds(matchPath, options.thresholds) ?? resolveEffectiveThresholds(matchPath, options.thresholds));
|
|
255
255
|
if (isBareZero || isBelowThreshold) {
|
|
256
|
-
const uncoveredLines =
|
|
256
|
+
const uncoveredLines = Fmt.ranges(fileCoverage.getUncoveredLines());
|
|
257
257
|
lowCoverage.push({
|
|
258
258
|
file: filePath,
|
|
259
259
|
summary: fileStats,
|
|
@@ -263,7 +263,7 @@ function processCoverageInternal(coverageMap, options, testedFiles) {
|
|
|
263
263
|
}
|
|
264
264
|
if (options.targets) {
|
|
265
265
|
if (isBelowMetricThresholds(fileStats, resolveEffectivePerFileThresholds(matchPath, options.targets) ?? resolveEffectiveThresholds(matchPath, options.targets))) {
|
|
266
|
-
const uncoveredLines =
|
|
266
|
+
const uncoveredLines = Fmt.ranges(fileCoverage.getUncoveredLines());
|
|
267
267
|
belowTarget.push({
|
|
268
268
|
file: filePath,
|
|
269
269
|
summary: fileStats,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest-agent/plugin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Vitest plugin for the vitest-agent ecosystem: owns persistence, classification, baselines, trends, and dispatches rendering to a configurable reporter.",
|
|
6
6
|
"keywords": [
|
|
@@ -44,16 +44,17 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@effect/platform-node": "^4.0.6",
|
|
47
|
-
"@effected/cli": "^0.
|
|
48
|
-
"@effected/
|
|
49
|
-
"@effected/
|
|
50
|
-
"@effected/
|
|
51
|
-
"@effected/
|
|
52
|
-
"@
|
|
53
|
-
"@vitest-agent/
|
|
54
|
-
"@vitest-agent/
|
|
55
|
-
"@vitest-agent/
|
|
56
|
-
"@vitest-agent/
|
|
47
|
+
"@effected/cli": "^0.23.0",
|
|
48
|
+
"@effected/commands": "^0.17.0",
|
|
49
|
+
"@effected/env": "^0.6.0",
|
|
50
|
+
"@effected/glob": "^0.15.0",
|
|
51
|
+
"@effected/walker": "^0.21.0",
|
|
52
|
+
"@effected/workspaces": "^0.39.1",
|
|
53
|
+
"@vitest-agent/cli": "4.1.4",
|
|
54
|
+
"@vitest-agent/engine": "3.0.0",
|
|
55
|
+
"@vitest-agent/mcp": "6.0.0",
|
|
56
|
+
"@vitest-agent/reporter": "6.1.0",
|
|
57
|
+
"@vitest-agent/sdk": "9.0.0",
|
|
57
58
|
"effect": "^4.0.6",
|
|
58
59
|
"magic-string": "^1.4.3"
|
|
59
60
|
},
|
|
@@ -62,6 +63,14 @@
|
|
|
62
63
|
"@vitest/coverage-v8": "^5.0.0",
|
|
63
64
|
"vitest": "^5.0.0"
|
|
64
65
|
},
|
|
66
|
+
"peerDependenciesMeta": {
|
|
67
|
+
"@vitest/coverage-istanbul": {
|
|
68
|
+
"optional": true
|
|
69
|
+
},
|
|
70
|
+
"@vitest/coverage-v8": {
|
|
71
|
+
"optional": true
|
|
72
|
+
}
|
|
73
|
+
},
|
|
65
74
|
"engines": {
|
|
66
75
|
"node": ">=24.11.0"
|
|
67
76
|
}
|
package/plugin.js
CHANGED
|
@@ -14,20 +14,21 @@ import { injectTags } from "./utils/inject-tags.js";
|
|
|
14
14
|
import { isBenignViteSourceMapWarning } from "./utils/is-benign-vite-source-map-warning.js";
|
|
15
15
|
import { resolveCoverageDirIsolation } from "./utils/resolve-coverage-dir-isolation.js";
|
|
16
16
|
import { PERSIST_ENV_VAR, resolvePersistence } from "./utils/resolve-persistence.js";
|
|
17
|
-
import {
|
|
17
|
+
import { runScriptOptions, shellCommand } from "./utils/run-script-lock.js";
|
|
18
18
|
import { stripConsoleReporters } from "./utils/strip-console-reporters.js";
|
|
19
19
|
import { makeTagCacheKeyGenerator } from "./utils/tag-cache-key.js";
|
|
20
20
|
import { readVitestVersion, vitestPeerVersionMismatchMessage } from "./utils/vitest-peer-version-mismatch-error.js";
|
|
21
21
|
import { CURRENT_PLUGIN_VERSION } from "./version.js";
|
|
22
|
-
import { execSync } from "node:child_process";
|
|
23
22
|
import { mkdtempSync, rmSync } from "node:fs";
|
|
24
23
|
import { tmpdir } from "node:os";
|
|
25
24
|
import { join } from "node:path";
|
|
26
25
|
import { CliLog } from "@effected/cli";
|
|
26
|
+
import { RunOnce } from "@effected/commands";
|
|
27
|
+
import { nodeRunOnceHost } from "@effected/commands/node-sync";
|
|
27
28
|
import { Audience, EnvOverride } from "@effected/env";
|
|
28
|
-
import { EnvironmentDetector, EnvironmentDetectorLive, ExecutorResolver, ExecutorResolverLive, LoggerLive, resolveLogLevel } from "@vitest-agent/engine";
|
|
29
|
-
import { AgentConsoleMode, CiConsoleMode, CoverageLevel, HumanConsoleMode, SRC_DIR, TEST_DIR,
|
|
30
|
-
import { Effect, Layer, Option } from "effect";
|
|
29
|
+
import { EnvironmentDetector, EnvironmentDetectorLive, ExecutorResolver, ExecutorResolverLive, LoggerLive, formatFatalError, resolveLogLevel } from "@vitest-agent/engine";
|
|
30
|
+
import { AgentConsoleMode, CiConsoleMode, CoverageLevel, HumanConsoleMode, SRC_DIR, TEST_DIR, isTestFileName } from "@vitest-agent/sdk";
|
|
31
|
+
import { Effect, Layer, Option, Result } from "effect";
|
|
31
32
|
|
|
32
33
|
// src/plugin.ts
|
|
33
34
|
/**
|
|
@@ -439,38 +440,14 @@ function makeDiscoverBuilder(options) {
|
|
|
439
440
|
});
|
|
440
441
|
}
|
|
441
442
|
_AgentPlugin.discover = discover;
|
|
442
|
-
/**
|
|
443
|
-
* Parses a `VITEST_AGENT_RUNSCRIPT_*` override env var, falling back to
|
|
444
|
-
* `fallback` for anything that is not a whole positive integer at or above
|
|
445
|
-
* `minimum`. Test-support: lets the concurrency e2e suite use short timeouts
|
|
446
|
-
* instead of the production-sized defaults — but a typo there (`"200ms"`,
|
|
447
|
-
* `"-1"`, `"0"`) must degrade to the default rather than to an
|
|
448
|
-
* instantly-stale lock or a busy-spinning waiter.
|
|
449
|
-
*/
|
|
450
|
-
function readRunScriptLockEnvOverride(name, fallback, minimum = 1) {
|
|
451
|
-
return parseLockTimingOverride(process.env[name], fallback, minimum);
|
|
452
|
-
}
|
|
453
443
|
function runScript(command) {
|
|
454
|
-
const
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
});
|
|
462
|
-
if (lock.recentlyBuilt) return;
|
|
463
|
-
try {
|
|
464
|
-
execSync(command, { stdio: "pipe" });
|
|
465
|
-
markRunScriptDone(lock);
|
|
466
|
-
} catch (error) {
|
|
467
|
-
const execError = error;
|
|
468
|
-
if (execError.stderr?.length) process.stderr.write(execError.stderr);
|
|
469
|
-
if (execError.stdout?.length) process.stdout.write(execError.stdout);
|
|
470
|
-
throw error;
|
|
471
|
-
} finally {
|
|
472
|
-
releaseRunScriptLock(lock);
|
|
473
|
-
}
|
|
444
|
+
const run = typeof command === "string" ? shellCommand(command, process.platform, process.env) : { argv: command };
|
|
445
|
+
const outcome = RunOnce.commandSync(runScriptOptions(command, process.cwd(), process.env), nodeRunOnceHost, run);
|
|
446
|
+
if (Result.isSuccess(outcome)) return;
|
|
447
|
+
const failure = outcome.failure;
|
|
448
|
+
if (failure.stderr !== void 0 && failure.stderr.length > 0) process.stderr.write(failure.stderr);
|
|
449
|
+
if (failure.stdout !== void 0 && failure.stdout.length > 0) process.stdout.write(failure.stdout);
|
|
450
|
+
throw failure;
|
|
474
451
|
}
|
|
475
452
|
_AgentPlugin.runScript = runScript;
|
|
476
453
|
})(AgentPlugin || (AgentPlugin = {}));
|