@systemfsoftware/stryker-js-cli 4.0.1 → 4.0.3
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/CHANGELOG.md +16 -0
- package/dist/main.mjs +56 -58
- package/package.json +17 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @systemfsoftware/stryker-js-cli
|
|
2
2
|
|
|
3
|
+
## 4.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Refreshed builds on the platform-services dependency graph; the packages no longer reach for host builtins directly. No CLI flags or option names change.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies:
|
|
10
|
+
- @systemfsoftware/stryker-js@0.2.0
|
|
11
|
+
- @systemfsoftware/stryker-js-platform-node@0.2.0
|
|
12
|
+
|
|
13
|
+
## 4.0.2
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Re-published against the oxc-based instrumenter: workspace dependency ranges move to the new instrumenter major; no package's own behavior changes in this release.
|
|
18
|
+
|
|
3
19
|
## 4.0.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/main.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import * as
|
|
4
|
-
import * as NodePath from "@effect/platform-node-shared/NodePath";
|
|
2
|
+
import * as NodeFileSystem$1 from "@effect/platform-node-shared/NodeFileSystem";
|
|
3
|
+
import * as NodePath$1 from "@effect/platform-node-shared/NodePath";
|
|
5
4
|
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
|
|
6
5
|
import * as NodeStdio from "@effect/platform-node/NodeStdio";
|
|
7
|
-
import { ConfigFileUnreadableError, buildVerdictEnvelope, defaultOptions, generateRunId, makeRunLayer, readConfig, runMutationTest, strykerEngines, strykerVersion, toRelativeNormalizedFileName } from "@systemfsoftware/stryker-js-platform-node";
|
|
6
|
+
import { ConfigFileUnreadableError, buildVerdictEnvelope, defaultOptions, generateRunId, makeRunLayer, nodeModuleLayer, readConfig, runMutationTest, strykerEngines, strykerVersion, toRelativeNormalizedFileName } from "@systemfsoftware/stryker-js-platform-node";
|
|
8
7
|
import * as Effect from "effect/Effect";
|
|
9
8
|
import * as Exit from "effect/Exit";
|
|
10
9
|
import * as Layer from "effect/Layer";
|
|
@@ -30,8 +29,6 @@ import * as CliError from "effect/unstable/cli/CliError";
|
|
|
30
29
|
import * as Command from "effect/unstable/cli/Command";
|
|
31
30
|
import * as Flag from "effect/unstable/cli/Flag";
|
|
32
31
|
import * as GlobalFlag from "effect/unstable/cli/GlobalFlag";
|
|
33
|
-
import { readFileSync } from "node:fs";
|
|
34
|
-
import { resolve } from "node:path";
|
|
35
32
|
import { ExitClass, highestExitClass } from "@systemfsoftware/stryker-js/ExitClass";
|
|
36
33
|
import { Mutant, causeText } from "@systemfsoftware/stryker-js/Mutant";
|
|
37
34
|
import * as Clock from "effect/Clock";
|
|
@@ -42,8 +39,10 @@ import * as Context from "effect/Context";
|
|
|
42
39
|
import { pipe } from "effect/Function";
|
|
43
40
|
import * as Stdio from "effect/Stdio";
|
|
44
41
|
import * as Stream from "effect/Stream";
|
|
42
|
+
import { NodeFileSystem, NodePath } from "@effect/platform-node";
|
|
45
43
|
import { sha256 } from "@noble/hashes/sha256";
|
|
46
44
|
import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils";
|
|
45
|
+
import "@systemfsoftware/stryker-js/Module";
|
|
47
46
|
//#region src/RunOutcome.workflow.ts
|
|
48
47
|
var RunOutcomeCommand = class extends S.TaggedClass()("RunOutcomeCommand", {
|
|
49
48
|
succeeded: S.Boolean,
|
|
@@ -1184,7 +1183,6 @@ function survivorMutateSpans(survivors, basePath) {
|
|
|
1184
1183
|
return spans;
|
|
1185
1184
|
}
|
|
1186
1185
|
const hashContent = (content) => bytesToHex(sha256(utf8ToBytes(content)));
|
|
1187
|
-
const resolveAbsolutePath = (file) => resolve(file);
|
|
1188
1186
|
/**
|
|
1189
1187
|
* The survivors admission, as a description whose phases chain by type and
|
|
1190
1188
|
* read in the order they run. The read gathers the admission's whole input
|
|
@@ -1196,8 +1194,9 @@ const resolveAbsolutePath = (file) => resolve(file);
|
|
|
1196
1194
|
* stashed context back and dispatches the decision to the verdict/run,
|
|
1197
1195
|
* failing the run with a rejection.
|
|
1198
1196
|
*/
|
|
1199
|
-
const survivorsAdmissionDescription = (runMutationTest, stream, mode, runContext, basePath
|
|
1197
|
+
const survivorsAdmissionDescription = (runMutationTest, stream, mode, runContext, basePath) => pipe(Cell.read((cliOptions) => Effect.flatMap(Path.Path, (pathService) => resolveSurvivorsRunOptions(cliOptions, basePath).pipe(Effect.flatMap((resolvedOptions) => {
|
|
1200
1198
|
const priorReportPath = priorReportPathOf(resolvedOptions);
|
|
1199
|
+
const resolveAbsolutePath = (file) => pathService.resolve(file);
|
|
1201
1200
|
return Effect.flatMap(readPriorReport(priorReportPath), (read) => Effect.flatMap(currentSourceHashesFor(priorReportFileKeys(read.raw)), (sourceContentHashes) => Ref.set(runContext, {
|
|
1202
1201
|
resolvedOptions,
|
|
1203
1202
|
priorReportPath,
|
|
@@ -1207,9 +1206,10 @@ const survivorsAdmissionDescription = (runMutationTest, stream, mode, runContext
|
|
|
1207
1206
|
priorReportRaw: read.raw,
|
|
1208
1207
|
priorReportFound: read.found,
|
|
1209
1208
|
priorReportPath,
|
|
1210
|
-
sourceContentHashes
|
|
1209
|
+
sourceContentHashes,
|
|
1210
|
+
resolveAbsolutePath
|
|
1211
1211
|
}))));
|
|
1212
|
-
}))),
|
|
1212
|
+
}))).pipe(Effect.provide(Layer.mergeAll(NodeFileSystem.layer, NodePath.layer, nodeModuleLayer)))), Cell.decode(({ resolvedOptions, priorReportRaw, priorReportFound, sourceContentHashes, resolveAbsolutePath }) => {
|
|
1213
1213
|
if (!priorReportFound) return Result.succeed(AdmitSurvivorsRunCommand.make({
|
|
1214
1214
|
priorReport: void 0,
|
|
1215
1215
|
currentConfig: resolvedOptions,
|
|
@@ -1261,9 +1261,8 @@ const survivorsAdmissionDescription = (runMutationTest, stream, mode, runContext
|
|
|
1261
1261
|
*/
|
|
1262
1262
|
function runSurvivorsAdmission(runMutationTest, stream, mode, cliOptions, basePath) {
|
|
1263
1263
|
return Effect.gen(function* () {
|
|
1264
|
-
const services = yield* Effect.context();
|
|
1265
1264
|
const admissionContext = yield* Ref.make(void 0);
|
|
1266
|
-
return yield* Cell.apply(survivorsAdmissionDescription(runMutationTest, stream, mode, admissionContext, basePath
|
|
1265
|
+
return yield* Cell.apply(survivorsAdmissionDescription(runMutationTest, stream, mode, admissionContext, basePath), cliOptions);
|
|
1267
1266
|
});
|
|
1268
1267
|
}
|
|
1269
1268
|
function resolveSurvivorsRunOptions(cliOptions, basePath) {
|
|
@@ -1513,37 +1512,49 @@ function describeCommandNode(node) {
|
|
|
1513
1512
|
};
|
|
1514
1513
|
}
|
|
1515
1514
|
function readCoreEntries() {
|
|
1516
|
-
|
|
1517
|
-
const
|
|
1518
|
-
const
|
|
1519
|
-
const
|
|
1515
|
+
return Effect.gen(function* () {
|
|
1516
|
+
const path = yield* Path.Path;
|
|
1517
|
+
const fs = yield* FileSystem.FileSystem;
|
|
1518
|
+
const resolved = import.meta.resolve("@systemfsoftware/stryker-js-platform-node/package.json");
|
|
1519
|
+
const manifestPath = yield* path.fromFileUrl(new URL(resolved));
|
|
1520
|
+
const raw = yield* fs.readFileString(manifestPath);
|
|
1521
|
+
let parsed;
|
|
1522
|
+
try {
|
|
1523
|
+
parsed = JSON.parse(raw);
|
|
1524
|
+
} catch {
|
|
1525
|
+
return [];
|
|
1526
|
+
}
|
|
1520
1527
|
const ExportsSchema = S.Struct({ exports: S.Record(S.String, S.Unknown) });
|
|
1521
1528
|
const decoded = S.decodeUnknownResult(ExportsSchema)(parsed);
|
|
1522
1529
|
if (Result.isSuccess(decoded)) return Object.keys(decoded.success.exports).filter((key) => key !== "./package.json");
|
|
1523
1530
|
return [];
|
|
1524
|
-
}
|
|
1525
|
-
return [];
|
|
1526
|
-
}
|
|
1531
|
+
}).pipe(Effect.catchCause(() => {
|
|
1532
|
+
return Effect.succeed([]);
|
|
1533
|
+
}), Effect.catchDefect(() => {
|
|
1534
|
+
return Effect.succeed([]);
|
|
1535
|
+
}));
|
|
1527
1536
|
}
|
|
1528
1537
|
function buildLLMSManifest(command, version) {
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1538
|
+
return Effect.gen(function* () {
|
|
1539
|
+
const root = describeCommandNode(command) ?? {
|
|
1540
|
+
name: "",
|
|
1541
|
+
description: "",
|
|
1542
|
+
options: [],
|
|
1543
|
+
args: [],
|
|
1544
|
+
subcommands: []
|
|
1545
|
+
};
|
|
1546
|
+
const entries = yield* readCoreEntries();
|
|
1547
|
+
return {
|
|
1548
|
+
schemaVersion: "1.0",
|
|
1549
|
+
tool: root.name,
|
|
1550
|
+
version,
|
|
1551
|
+
commands: [root],
|
|
1552
|
+
entries
|
|
1553
|
+
};
|
|
1554
|
+
});
|
|
1543
1555
|
}
|
|
1544
|
-
/** The manifest as one JSON document, ready for stdout — the U4 convention. */
|
|
1545
1556
|
function emitLLMSManifest(command, version) {
|
|
1546
|
-
return
|
|
1557
|
+
return Effect.map(buildLLMSManifest(command, version), (manifest) => JSON.stringify(manifest));
|
|
1547
1558
|
}
|
|
1548
1559
|
function createSplitter(separator) {
|
|
1549
1560
|
return (value) => value.split(separator).filter(Boolean);
|
|
@@ -1716,39 +1727,26 @@ function makeStrykerCommand(requestRef) {
|
|
|
1716
1727
|
if (Option.isSome(config["configFile"])) options["configFile"] = config["configFile"].value;
|
|
1717
1728
|
return options;
|
|
1718
1729
|
}
|
|
1719
|
-
const strykerCommand = Command.make("stryker", rootConfig, (config) => {
|
|
1730
|
+
const strykerCommand = Command.make("stryker", rootConfig, (config) => Effect.gen(function* () {
|
|
1720
1731
|
if (config.llms === true) {
|
|
1721
1732
|
const document = {
|
|
1722
1733
|
_tag: "manifest",
|
|
1723
1734
|
schemaVersion: "1.0",
|
|
1724
1735
|
code: 0,
|
|
1725
|
-
manifest: emitLLMSManifest(strykerCommand, strykerVersion)
|
|
1736
|
+
manifest: yield* emitLLMSManifest(strykerCommand, strykerVersion)
|
|
1726
1737
|
};
|
|
1727
|
-
return Ref.set(requestRef, Option.some({
|
|
1738
|
+
return yield* Ref.set(requestRef, Option.some({
|
|
1728
1739
|
_tag: "llms",
|
|
1729
1740
|
document
|
|
1730
1741
|
}));
|
|
1731
1742
|
}
|
|
1732
|
-
return Effect.failSync(() => CliError.ShowHelp.make({
|
|
1743
|
+
return yield* Effect.failSync(() => CliError.ShowHelp.make({
|
|
1733
1744
|
commandPath: ["stryker"],
|
|
1734
1745
|
errors: []
|
|
1735
1746
|
}));
|
|
1736
|
-
}).pipe(Command.withSubcommands([runCommand]));
|
|
1747
|
+
})).pipe(Command.withSubcommands([runCommand]));
|
|
1737
1748
|
return strykerCommand;
|
|
1738
1749
|
}
|
|
1739
|
-
/**
|
|
1740
|
-
* The CLI parses only text/number/choice options, so the framework's platform
|
|
1741
|
-
* services are never read at runtime; the v4 runner still demands them in its
|
|
1742
|
-
* environment. The bootstrap provides `Path.layer` (the universal
|
|
1743
|
-
* implementation in `effect/Path`), an *empty* file system (`layerNoop`:
|
|
1744
|
-
* every operation reports not-found), and a process-stdio `Terminal` whose
|
|
1745
|
-
* interactive input primitives fail loudly — the run-only surface (R14) has
|
|
1746
|
-
* no prompts. `@effect/platform-node` is a declared dependency of this
|
|
1747
|
-
* package (it provides the `NodeRuntime` the bin runs through), but no
|
|
1748
|
-
* platform-node service is wired into the command environment: the parser
|
|
1749
|
-
* never reads a real file system at run time, so the noop layers are
|
|
1750
|
-
* sufficient.
|
|
1751
|
-
*/
|
|
1752
1750
|
const terminalLayer = Layer.succeed(Terminal.Terminal, Terminal.make({
|
|
1753
1751
|
columns: Effect.sync(() => process.stdout.columns),
|
|
1754
1752
|
rows: Effect.sync(() => process.stdout.rows),
|
|
@@ -1767,7 +1765,7 @@ const cliLayer = Layer.mergeAll(CliConfig.layer({ builtIns: [
|
|
|
1767
1765
|
GlobalFlag.Wizard,
|
|
1768
1766
|
GlobalFlag.Completions,
|
|
1769
1767
|
GlobalFlag.LogLevel
|
|
1770
|
-
] }), Path.layer,
|
|
1768
|
+
] }), Path.layer, NodeFileSystem$1.layer, terminalLayer, NodeStdio.layer, NodeChildProcessSpawner.layer.pipe(Layer.provideMerge(Layer.mergeAll(NodeFileSystem$1.layer, NodePath$1.layer))));
|
|
1771
1769
|
function strykerCliEffect(argv, runMutationTest, detectMode, createRunEventStream, lastSignal) {
|
|
1772
1770
|
return Effect.gen(function* () {
|
|
1773
1771
|
const mode = yield* detectMode;
|
|
@@ -1790,13 +1788,13 @@ function strykerCliEffect(argv, runMutationTest, detectMode, createRunEventStrea
|
|
|
1790
1788
|
return result.success;
|
|
1791
1789
|
}).pipe(Effect.orElseSucceed(() => 2));
|
|
1792
1790
|
}
|
|
1793
|
-
const defaultRunMutationTest = (hostOptions, queue) => (options) => Effect.scoped(runMutationTest(options)).pipe(Effect.provideService(RunEvents, queue)
|
|
1791
|
+
const defaultRunMutationTest = (hostOptions, queue) => (options) => Effect.scoped(runMutationTest(options, makeRunLayer(hostOptions, queue))).pipe(Effect.provideService(RunEvents, queue));
|
|
1794
1792
|
function hostOptionsOf(mode, stream) {
|
|
1795
1793
|
return {
|
|
1796
1794
|
runId: stream.runId,
|
|
1797
1795
|
resolvedMode: mode,
|
|
1798
1796
|
runStartedAt: stream.startedAt,
|
|
1799
|
-
basePath:
|
|
1797
|
+
basePath: process.cwd(),
|
|
1800
1798
|
reporterPluginModules: [import.meta.resolve("@systemfsoftware/stryker-js-html-reporter"), import.meta.resolve("@systemfsoftware/stryker-js-platform-node/builtin-reporters")],
|
|
1801
1799
|
allowConsoleColors: isColorEnabled(mode, process.env["NO_COLOR"])
|
|
1802
1800
|
};
|
|
@@ -1806,7 +1804,7 @@ const runStrykerCli = (input, createRunEventStream) => Effect.gen(function* () {
|
|
|
1806
1804
|
const hostOptions = hostOptionsOf(input.mode, stream);
|
|
1807
1805
|
const runMutationTestImpl = input.runMutationTest ?? defaultRunMutationTest(hostOptions, stream.queue);
|
|
1808
1806
|
const basePath = hostOptions.basePath;
|
|
1809
|
-
const pathService = yield* Path.Path.pipe(Effect.provide(NodePath.layer));
|
|
1807
|
+
const pathService = yield* Path.Path.pipe(Effect.provide(NodePath$1.layer));
|
|
1810
1808
|
let currentFiber = null;
|
|
1811
1809
|
const onSignal = () => {
|
|
1812
1810
|
process.removeListener("SIGINT", onSignal);
|
|
@@ -1890,7 +1888,7 @@ const program = Effect.gen(function* () {
|
|
|
1890
1888
|
const outputMode = yield* OutputModeProbe;
|
|
1891
1889
|
const runEvents = yield* RunEventStreamPort;
|
|
1892
1890
|
return yield* strykerCliEffect(process.argv.slice(2), void 0, outputMode.detectMode, runEvents.createRunEventStream, lastSignal);
|
|
1893
|
-
}).pipe(Effect.provideService(Logger.LogToStderr, true), Effect.provide(Layer.merge(OutputModeProbeLive, RunEventStreamFileLive).pipe(Layer.provide(Layer.mergeAll(NodeStdio.layer, NodeFileSystem.layer, NodePath.layer)))));
|
|
1891
|
+
}).pipe(Effect.provideService(Logger.LogToStderr, true), Effect.provide(Layer.merge(OutputModeProbeLive, RunEventStreamFileLive).pipe(Layer.provide(Layer.mergeAll(NodeStdio.layer, NodeFileSystem$1.layer, NodePath$1.layer)))));
|
|
1894
1892
|
NodeRuntime.runMain(program, {
|
|
1895
1893
|
disableErrorReporting: true,
|
|
1896
1894
|
teardown: (exit, onExit) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@systemfsoftware/stryker-js-cli",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.3",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/systemfsoftware/systemfsoftware.git",
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
"@effect/platform-node-shared": "^4.0.0-rc.112",
|
|
19
19
|
"@noble/hashes": "1.8.0",
|
|
20
20
|
"effect": "^4.0.0-rc.112",
|
|
21
|
-
"@systemfsoftware/effect-cell-types": "^5.0.
|
|
22
|
-
"@systemfsoftware/stryker-js": "^0.1.
|
|
23
|
-
"@systemfsoftware/stryker-js-
|
|
24
|
-
"@systemfsoftware/stryker-js
|
|
21
|
+
"@systemfsoftware/effect-cell-types": "^5.0.2",
|
|
22
|
+
"@systemfsoftware/stryker-js-html-reporter": "^0.1.2",
|
|
23
|
+
"@systemfsoftware/stryker-js-platform-node": "^0.2.0",
|
|
24
|
+
"@systemfsoftware/stryker-js": "^0.2.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@systemfsoftware/arethetypeswrong-cli": "^1.1.1",
|
|
@@ -32,17 +32,18 @@
|
|
|
32
32
|
"testcontainers": "^12.1.0",
|
|
33
33
|
"tsdown": "^0.22.14",
|
|
34
34
|
"vite-tsconfig-paths": "^6.1.1",
|
|
35
|
-
"vitest": "^4
|
|
36
|
-
"@systemfsoftware/effect-gherkin-spec": "^
|
|
37
|
-
"@systemfsoftware/effect-schema-law": "^2.0.
|
|
38
|
-
"@systemfsoftware/
|
|
35
|
+
"vitest": "^4",
|
|
36
|
+
"@systemfsoftware/effect-gherkin-spec": "^4.0.0",
|
|
37
|
+
"@systemfsoftware/effect-schema-law": "^2.0.1",
|
|
38
|
+
"@systemfsoftware/effect-schema-vite": "^2.0.2",
|
|
39
|
+
"@systemfsoftware/all": "^1.1.0",
|
|
39
40
|
"@systemfsoftware/oxlint-config": "^0.1.0",
|
|
40
|
-
"@systemfsoftware/
|
|
41
|
-
"@systemfsoftware/
|
|
42
|
-
"@systemfsoftware/
|
|
41
|
+
"@systemfsoftware/stryker-js-typescript-checker": "^3.0.3",
|
|
42
|
+
"@systemfsoftware/stryker-js-vitest-runner": "^2.1.0",
|
|
43
|
+
"@systemfsoftware/stryker-plugins": "^2.0.1",
|
|
43
44
|
"@systemfsoftware/tsconfig": "^1.3.3",
|
|
44
|
-
"@systemfsoftware/
|
|
45
|
-
"@systemfsoftware/
|
|
45
|
+
"@systemfsoftware/vitest-config": "^0.1.0",
|
|
46
|
+
"@systemfsoftware/stryker-test-contribution": "^1.1.2"
|
|
46
47
|
},
|
|
47
48
|
"engines": {
|
|
48
49
|
"node": ">=20.0.0"
|
|
@@ -65,8 +66,8 @@
|
|
|
65
66
|
"test": "vitest run",
|
|
66
67
|
"test:contract": "vitest run --config vitest.contract.config.ts",
|
|
67
68
|
"lint": "f=${OXLINT_FORMAT:-${AGENT:+agent}}; oxlint . --format=${f:-default}",
|
|
68
|
-
"mutation": "
|
|
69
|
-
"mutation:full": "
|
|
69
|
+
"mutation": "node ./dist/main.mjs run",
|
|
70
|
+
"mutation:full": "node ./dist/main.mjs run --force",
|
|
70
71
|
"api:check": "echo 'no API report for CLI (dts: false)' && exit 0",
|
|
71
72
|
"api:update": "echo 'no API report for CLI (dts: false)' && exit 0"
|
|
72
73
|
}
|