@hawkeyexl/manni 4.9.0 → 4.11.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/README.md +1 -1
- package/dist/{batch-W5GXL2P4.js → batch-UAULUMGH.js} +18 -14
- package/dist/{build-Q56FEXR6.js → build-QSPNK5AL.js} +14 -11
- package/dist/calibrate-KXN4URPM.js +40 -0
- package/dist/{capture-GMYH4ATL.js → capture-JHTSUPUC.js} +16 -13
- package/dist/{check-OAJWC3WD.js → check-MDGXEUWL.js} +5 -5
- package/dist/{check-KUBELO5G.js → check-VELUQAUW.js} +17 -14
- package/dist/{check-KUBELO5G.js.map → check-VELUQAUW.js.map} +1 -1
- package/dist/check-WOQRKNZK.js +29 -0
- package/dist/{check-ZE5HIDOW.js → check-YEOYBFST.js} +14 -11
- package/dist/{chunk-FGUXMZXO.js → chunk-2DRHT73U.js} +7 -7
- package/dist/{chunk-XHFHXOQQ.js → chunk-2IAZEB45.js} +8 -8
- package/dist/{chunk-35WTFPQS.js → chunk-2IR4T5PO.js} +2 -2
- package/dist/{chunk-KX5IYIOO.js → chunk-2MJ62AYQ.js} +2 -2
- package/dist/chunk-2MJ62AYQ.js.map +1 -0
- package/dist/{chunk-OWSNXPPX.js → chunk-4CK6ZSOK.js} +6 -6
- package/dist/{chunk-YUZ2ECZY.js → chunk-4D5IZSXM.js} +3 -3
- package/dist/{chunk-RFSGKF4O.js → chunk-4VBSTXN6.js} +4 -4
- package/dist/{chunk-3XMG4CZY.js → chunk-54F74XR3.js} +15 -13
- package/dist/{chunk-3XMG4CZY.js.map → chunk-54F74XR3.js.map} +1 -1
- package/dist/{chunk-IN6DWNVE.js → chunk-6HWBRZIN.js} +47 -191
- package/dist/chunk-6HWBRZIN.js.map +1 -0
- package/dist/{chunk-GEMXGXPR.js → chunk-ADMEPUBT.js} +3 -3
- package/dist/{chunk-23UAGEKP.js → chunk-B7XYNRJQ.js} +2 -2
- package/dist/{chunk-QKE3XS2L.js → chunk-BBT6AVUG.js} +2 -2
- package/dist/{chunk-VKWZCEWB.js → chunk-BKVHX6FU.js} +4 -4
- package/dist/{chunk-X6WLCNKC.js → chunk-D4N2V43Z.js} +4 -4
- package/dist/{chunk-XXDXIIQ4.js → chunk-EFW7CAG4.js} +2 -2
- package/dist/{chunk-UDUHRXJ4.js → chunk-EIFCP6CZ.js} +2 -2
- package/dist/{chunk-KPXOJMQ6.js → chunk-FBMZJEB3.js} +2 -2
- package/dist/{chunk-HRXDM6H6.js → chunk-FQXWVS6J.js} +8 -8
- package/dist/{chunk-76I6I5N2.js → chunk-FUCPZVRY.js} +2 -2
- package/dist/{chunk-DTGIUMZV.js → chunk-GDVZ5VII.js} +4 -4
- package/dist/{chunk-QCCAHV6A.js → chunk-GV56WGL2.js} +321 -3308
- package/dist/chunk-GV56WGL2.js.map +1 -0
- package/dist/{chunk-TKTRIZT4.js → chunk-HA6MQMOY.js} +6 -6
- package/dist/{chunk-ECVQNGTH.js → chunk-HQR2ZBHW.js} +3 -3
- package/dist/{chunk-MHAYLDBK.js → chunk-IGSHYP74.js} +4 -4
- package/dist/{chunk-YEUQ7OKT.js → chunk-J6IDQGJL.js} +4 -4
- package/dist/{chunk-5LBEQ4ZU.js → chunk-JPQDNYXH.js} +2 -2
- package/dist/{chunk-6KKZXB2O.js → chunk-JROBZ7JA.js} +2 -2
- package/dist/{chunk-TMI2YF6D.js → chunk-KGEQJ5CC.js} +15 -26
- package/dist/{chunk-TMI2YF6D.js.map → chunk-KGEQJ5CC.js.map} +1 -1
- package/dist/{chunk-2EHDJ47Y.js → chunk-LBSCW232.js} +4 -4
- package/dist/{chunk-M6GH3FGJ.js → chunk-LKP7QDFN.js} +4 -4
- package/dist/{chunk-5EB6RIXJ.js → chunk-LPIF5LIE.js} +2 -2
- package/dist/chunk-M42DZCOU.js +164 -0
- package/dist/chunk-M42DZCOU.js.map +1 -0
- package/dist/{chunk-ND2S5BXB.js → chunk-MSRU4D4P.js} +2 -2
- package/dist/{chunk-BSTXARMY.js → chunk-NSBXVPZL.js} +11 -11
- package/dist/{chunk-Q45PZX2D.js → chunk-ODRPL3WB.js} +2 -2
- package/dist/{chunk-FSBIPCWE.js → chunk-OPXWPJDA.js} +10 -10
- package/dist/chunk-PCQ7ELJH.js +3081 -0
- package/dist/chunk-PCQ7ELJH.js.map +1 -0
- package/dist/{chunk-QAKJNPY3.js → chunk-PCS4VJBV.js} +6 -6
- package/dist/{chunk-GRILZZGS.js → chunk-PWBH7DCQ.js} +3 -3
- package/dist/{chunk-XKBEHKWO.js → chunk-QLWC7MKD.js} +34 -32
- package/dist/chunk-QLWC7MKD.js.map +1 -0
- package/dist/{chunk-XTAHZTES.js → chunk-R4WXQIOZ.js} +6 -6
- package/dist/{chunk-3CDZWY6M.js → chunk-RLT5SEML.js} +5 -5
- package/dist/{chunk-XG6PVB5S.js → chunk-SSQZB5SQ.js} +1 -11
- package/dist/chunk-SSQZB5SQ.js.map +1 -0
- package/dist/chunk-T7JAOYE5.js +393 -0
- package/dist/chunk-T7JAOYE5.js.map +1 -0
- package/dist/chunk-TU2WUBVZ.js +2 -0
- package/dist/{chunk-Q2H7J3FF.js → chunk-U7CTFN2J.js} +12 -10
- package/dist/{chunk-Q2H7J3FF.js.map → chunk-U7CTFN2J.js.map} +1 -1
- package/dist/{chunk-3XGGF5JW.js → chunk-VSEBFHAY.js} +10 -7
- package/dist/{chunk-3XGGF5JW.js.map → chunk-VSEBFHAY.js.map} +1 -1
- package/dist/{chunk-OVOYKWCM.js → chunk-WDWXAYVH.js} +4 -4
- package/dist/{chunk-5WME4CB6.js → chunk-Y6DOMTQD.js} +10 -8
- package/dist/{chunk-5WME4CB6.js.map → chunk-Y6DOMTQD.js.map} +1 -1
- package/dist/chunk-ZMECS2IJ.js +27 -0
- package/dist/chunk-ZMECS2IJ.js.map +1 -0
- package/dist/chunk-ZPLVANY2.js +15 -0
- package/dist/chunk-ZPLVANY2.js.map +1 -0
- package/dist/{cli-MEPJTS2V.js → cli-3BTCK4AB.js} +18 -15
- package/dist/{cli-MEPJTS2V.js.map → cli-3BTCK4AB.js.map} +1 -1
- package/dist/{cli-EMQXRN6E.js → cli-4MF37HAQ.js} +16 -12
- package/dist/{cli-EMQXRN6E.js.map → cli-4MF37HAQ.js.map} +1 -1
- package/dist/{cli-YDMMIL2U.js → cli-6KZTHWGP.js} +17 -14
- package/dist/{cli-YDMMIL2U.js.map → cli-6KZTHWGP.js.map} +1 -1
- package/dist/{cli-ZJRHU7MO.js → cli-DRMZBZLB.js} +39 -34
- package/dist/cli-DRMZBZLB.js.map +1 -0
- package/dist/{cli-J35OPSTP.js → cli-I62SRH3R.js} +10 -8
- package/dist/cli-JJMOVIKS.js +83 -0
- package/dist/cli-JJMOVIKS.js.map +1 -0
- package/dist/{cli-TPONWND4.js → cli-O4ABTN4Z.js} +25 -21
- package/dist/{cli-TPONWND4.js.map → cli-O4ABTN4Z.js.map} +1 -1
- package/dist/{cli-URNPOMOH.js → cli-ONTC5PKT.js} +3 -3
- package/dist/{cli-BJ7JXJ2U.js → cli-RORDPAPE.js} +17 -14
- package/dist/{cli-BJ7JXJ2U.js.map → cli-RORDPAPE.js.map} +1 -1
- package/dist/{cli-B7SFJDZA.js → cli-VID7PJS3.js} +17 -13
- package/dist/{cli-B7SFJDZA.js.map → cli-VID7PJS3.js.map} +1 -1
- package/dist/cli-VUKMWSSF.js +839 -0
- package/dist/cli-VUKMWSSF.js.map +1 -0
- package/dist/cli.js +24 -11
- package/dist/cli.js.map +1 -1
- package/dist/{config-YWSNBFEE.js → config-XDA42RJL.js} +3 -3
- package/dist/docmeta.js +9 -7
- package/dist/docmeta.js.map +1 -1
- package/dist/github-RY3FRA6P.js +29 -0
- package/dist/github-YKQSH7FS.js +34 -0
- package/dist/index.d.ts +1023 -915
- package/dist/index.js +107 -81
- package/dist/index.js.map +1 -1
- package/dist/{json-JIUPGOUQ.js → json-BXY44ED7.js} +13 -10
- package/dist/lint-YJ2L22BW.js +33 -0
- package/dist/list-NSG24VVX.js +31 -0
- package/dist/list-V6EGCSHX.js +34 -0
- package/dist/{page-WQ3GQF76.js → page-EV7OUBAU.js} +12 -9
- package/dist/{prepare-ZUTYXTUZ.js → prepare-JHJDJB6I.js} +17 -14
- package/dist/{prepare-ZUTYXTUZ.js.map → prepare-JHJDJB6I.js.map} +1 -1
- package/dist/{pretty-Q3C433DW.js → pretty-Q5Y2PA64.js} +14 -11
- package/dist/{pretty-CBV5XSMZ.js → pretty-SCRK66M5.js} +13 -10
- package/dist/{reporters-DH5HPFXJ.js → reporters-A5ADKDYR.js} +12 -9
- package/dist/{reporters-TTYGOUAF.js → reporters-RBYTASMI.js} +5 -5
- package/dist/run-BUE2DDXN.js +36 -0
- package/dist/{term-DL3YFL43.js → term-CQAGNG3Q.js} +17 -14
- package/dist/{term-DL3YFL43.js.map → term-CQAGNG3Q.js.map} +1 -1
- package/dist/{validate-UVDMC5LT.js → validate-ZBW44RHT.js} +6 -5
- package/dist/validate-ZBW44RHT.js.map +1 -0
- package/package.json +1 -1
- package/plugin/manni/.claude-plugin/plugin.json +1 -1
- package/dist/calibrate-XFE56P4M.js +0 -36
- package/dist/check-HBRX4FOR.js +0 -26
- package/dist/chunk-IN6DWNVE.js.map +0 -1
- package/dist/chunk-KX5IYIOO.js.map +0 -1
- package/dist/chunk-QCCAHV6A.js.map +0 -1
- package/dist/chunk-XG6PVB5S.js.map +0 -1
- package/dist/chunk-XKBEHKWO.js.map +0 -1
- package/dist/cli-ZJRHU7MO.js.map +0 -1
- package/dist/github-63CZJGZS.js +0 -31
- package/dist/github-IYOVHWHG.js +0 -26
- package/dist/lint-TBE35CCW.js +0 -29
- package/dist/list-IZ4RIM72.js +0 -30
- package/dist/list-TNEJ3J77.js +0 -28
- package/dist/run-LZXKVTM7.js +0 -32
- /package/dist/{batch-W5GXL2P4.js.map → batch-UAULUMGH.js.map} +0 -0
- /package/dist/{build-Q56FEXR6.js.map → build-QSPNK5AL.js.map} +0 -0
- /package/dist/{calibrate-XFE56P4M.js.map → calibrate-KXN4URPM.js.map} +0 -0
- /package/dist/{capture-GMYH4ATL.js.map → capture-JHTSUPUC.js.map} +0 -0
- /package/dist/{check-HBRX4FOR.js.map → check-MDGXEUWL.js.map} +0 -0
- /package/dist/{check-OAJWC3WD.js.map → check-WOQRKNZK.js.map} +0 -0
- /package/dist/{check-ZE5HIDOW.js.map → check-YEOYBFST.js.map} +0 -0
- /package/dist/{chunk-FGUXMZXO.js.map → chunk-2DRHT73U.js.map} +0 -0
- /package/dist/{chunk-XHFHXOQQ.js.map → chunk-2IAZEB45.js.map} +0 -0
- /package/dist/{chunk-35WTFPQS.js.map → chunk-2IR4T5PO.js.map} +0 -0
- /package/dist/{chunk-OWSNXPPX.js.map → chunk-4CK6ZSOK.js.map} +0 -0
- /package/dist/{chunk-YUZ2ECZY.js.map → chunk-4D5IZSXM.js.map} +0 -0
- /package/dist/{chunk-RFSGKF4O.js.map → chunk-4VBSTXN6.js.map} +0 -0
- /package/dist/{chunk-GEMXGXPR.js.map → chunk-ADMEPUBT.js.map} +0 -0
- /package/dist/{chunk-23UAGEKP.js.map → chunk-B7XYNRJQ.js.map} +0 -0
- /package/dist/{chunk-QKE3XS2L.js.map → chunk-BBT6AVUG.js.map} +0 -0
- /package/dist/{chunk-VKWZCEWB.js.map → chunk-BKVHX6FU.js.map} +0 -0
- /package/dist/{chunk-X6WLCNKC.js.map → chunk-D4N2V43Z.js.map} +0 -0
- /package/dist/{chunk-XXDXIIQ4.js.map → chunk-EFW7CAG4.js.map} +0 -0
- /package/dist/{chunk-UDUHRXJ4.js.map → chunk-EIFCP6CZ.js.map} +0 -0
- /package/dist/{chunk-KPXOJMQ6.js.map → chunk-FBMZJEB3.js.map} +0 -0
- /package/dist/{chunk-HRXDM6H6.js.map → chunk-FQXWVS6J.js.map} +0 -0
- /package/dist/{chunk-76I6I5N2.js.map → chunk-FUCPZVRY.js.map} +0 -0
- /package/dist/{chunk-DTGIUMZV.js.map → chunk-GDVZ5VII.js.map} +0 -0
- /package/dist/{chunk-TKTRIZT4.js.map → chunk-HA6MQMOY.js.map} +0 -0
- /package/dist/{chunk-ECVQNGTH.js.map → chunk-HQR2ZBHW.js.map} +0 -0
- /package/dist/{chunk-MHAYLDBK.js.map → chunk-IGSHYP74.js.map} +0 -0
- /package/dist/{chunk-YEUQ7OKT.js.map → chunk-J6IDQGJL.js.map} +0 -0
- /package/dist/{chunk-5LBEQ4ZU.js.map → chunk-JPQDNYXH.js.map} +0 -0
- /package/dist/{chunk-6KKZXB2O.js.map → chunk-JROBZ7JA.js.map} +0 -0
- /package/dist/{chunk-2EHDJ47Y.js.map → chunk-LBSCW232.js.map} +0 -0
- /package/dist/{chunk-M6GH3FGJ.js.map → chunk-LKP7QDFN.js.map} +0 -0
- /package/dist/{chunk-5EB6RIXJ.js.map → chunk-LPIF5LIE.js.map} +0 -0
- /package/dist/{chunk-ND2S5BXB.js.map → chunk-MSRU4D4P.js.map} +0 -0
- /package/dist/{chunk-BSTXARMY.js.map → chunk-NSBXVPZL.js.map} +0 -0
- /package/dist/{chunk-Q45PZX2D.js.map → chunk-ODRPL3WB.js.map} +0 -0
- /package/dist/{chunk-FSBIPCWE.js.map → chunk-OPXWPJDA.js.map} +0 -0
- /package/dist/{chunk-QAKJNPY3.js.map → chunk-PCS4VJBV.js.map} +0 -0
- /package/dist/{chunk-GRILZZGS.js.map → chunk-PWBH7DCQ.js.map} +0 -0
- /package/dist/{chunk-XTAHZTES.js.map → chunk-R4WXQIOZ.js.map} +0 -0
- /package/dist/{chunk-3CDZWY6M.js.map → chunk-RLT5SEML.js.map} +0 -0
- /package/dist/{cli-J35OPSTP.js.map → chunk-TU2WUBVZ.js.map} +0 -0
- /package/dist/{chunk-OVOYKWCM.js.map → chunk-WDWXAYVH.js.map} +0 -0
- /package/dist/{config-YWSNBFEE.js.map → cli-I62SRH3R.js.map} +0 -0
- /package/dist/{cli-URNPOMOH.js.map → cli-ONTC5PKT.js.map} +0 -0
- /package/dist/{github-63CZJGZS.js.map → config-XDA42RJL.js.map} +0 -0
- /package/dist/{github-IYOVHWHG.js.map → github-RY3FRA6P.js.map} +0 -0
- /package/dist/{json-JIUPGOUQ.js.map → github-YKQSH7FS.js.map} +0 -0
- /package/dist/{lint-TBE35CCW.js.map → json-BXY44ED7.js.map} +0 -0
- /package/dist/{list-IZ4RIM72.js.map → lint-YJ2L22BW.js.map} +0 -0
- /package/dist/{list-TNEJ3J77.js.map → list-NSG24VVX.js.map} +0 -0
- /package/dist/{page-WQ3GQF76.js.map → list-V6EGCSHX.js.map} +0 -0
- /package/dist/{pretty-CBV5XSMZ.js.map → page-EV7OUBAU.js.map} +0 -0
- /package/dist/{pretty-Q3C433DW.js.map → pretty-Q5Y2PA64.js.map} +0 -0
- /package/dist/{reporters-DH5HPFXJ.js.map → pretty-SCRK66M5.js.map} +0 -0
- /package/dist/{reporters-TTYGOUAF.js.map → reporters-A5ADKDYR.js.map} +0 -0
- /package/dist/{run-LZXKVTM7.js.map → reporters-RBYTASMI.js.map} +0 -0
- /package/dist/{validate-UVDMC5LT.js.map → run-BUE2DDXN.js.map} +0 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
outputTail,
|
|
4
|
+
realExec
|
|
5
|
+
} from "./chunk-ZPLVANY2.js";
|
|
6
|
+
import {
|
|
7
|
+
DEFAULT_IGNORE,
|
|
8
|
+
STDIN_TOKEN,
|
|
9
|
+
notFoundMessage,
|
|
10
|
+
resolveTargetSet
|
|
11
|
+
} from "./chunk-VSEBFHAY.js";
|
|
12
|
+
import {
|
|
13
|
+
palette
|
|
14
|
+
} from "./chunk-RNVYGWIC.js";
|
|
15
|
+
import {
|
|
16
|
+
escapeWorkflowCommandMessage,
|
|
17
|
+
escapeWorkflowCommandProperty
|
|
18
|
+
} from "./chunk-MNH7QO4Z.js";
|
|
19
|
+
import {
|
|
20
|
+
docDetectiveConfigPath,
|
|
21
|
+
findConfigFile,
|
|
22
|
+
readConfigFile,
|
|
23
|
+
selectCollections
|
|
24
|
+
} from "./chunk-QLWC7MKD.js";
|
|
25
|
+
import {
|
|
26
|
+
ToolError
|
|
27
|
+
} from "./chunk-G3T47CFV.js";
|
|
28
|
+
|
|
29
|
+
// src/test/errors.ts
|
|
30
|
+
var TestError = class extends ToolError {
|
|
31
|
+
constructor(message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "TestError";
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// src/test/commands/run.ts
|
|
38
|
+
import { existsSync } from "node:fs";
|
|
39
|
+
import { mkdtemp, readdir, readFile, rm } from "node:fs/promises";
|
|
40
|
+
import { tmpdir } from "node:os";
|
|
41
|
+
import { join as join2, relative as relative2, resolve } from "node:path";
|
|
42
|
+
import fg from "fast-glob";
|
|
43
|
+
import picomatch from "picomatch";
|
|
44
|
+
|
|
45
|
+
// src/test/core/doc-detective.ts
|
|
46
|
+
import { spawn } from "node:child_process";
|
|
47
|
+
import { statSync } from "node:fs";
|
|
48
|
+
import { join } from "node:path";
|
|
49
|
+
var NOT_ON_PATH = "doc-detective is not on PATH. Install Doc Detective (npm install -g doc-detective) to run doc tests.";
|
|
50
|
+
var COMMAND_LINE_LIMIT = "the selected inputs exceed the command-line limit. Narrow the collection, or set input in the Doc Detective config.";
|
|
51
|
+
var NO_TIMEOUT = 2 ** 31 - 1;
|
|
52
|
+
function launchFor(args, host) {
|
|
53
|
+
if (host.platform !== "win32") return { command: "doc-detective", args, viaShim: false };
|
|
54
|
+
for (const entry of host.path.split(";")) {
|
|
55
|
+
const dir = entry.replace(/^"(.*)"$/, "$1");
|
|
56
|
+
if (dir === "" || !host.isFile(join(dir, "doc-detective.cmd"))) continue;
|
|
57
|
+
const script = join(dir, "node_modules", "doc-detective", "bin", "doc-detective.js");
|
|
58
|
+
if (host.isFile(script)) {
|
|
59
|
+
return { command: process.execPath, args: [script, ...args], viaShim: false };
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
return { command: "doc-detective", args, viaShim: true };
|
|
64
|
+
}
|
|
65
|
+
function assertFitsCommandLine(launch, platform) {
|
|
66
|
+
if (platform !== "win32") return;
|
|
67
|
+
const length = [launch.command, ...launch.args].reduce((n, arg) => n + arg.length + 3, 0);
|
|
68
|
+
if (length > (launch.viaShim ? 8191 : 32767)) throw new TestError(COMMAND_LINE_LIMIT);
|
|
69
|
+
}
|
|
70
|
+
function isFile(path) {
|
|
71
|
+
try {
|
|
72
|
+
return statSync(path).isFile();
|
|
73
|
+
} catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function streamed(launch, opts) {
|
|
78
|
+
return new Promise((settle) => {
|
|
79
|
+
let stdout = "";
|
|
80
|
+
let stderr = "";
|
|
81
|
+
const child = spawn(launch.command, launch.args, {
|
|
82
|
+
cwd: opts.cwd,
|
|
83
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
84
|
+
windowsHide: true
|
|
85
|
+
});
|
|
86
|
+
child.stdout.setEncoding("utf8");
|
|
87
|
+
child.stderr.setEncoding("utf8");
|
|
88
|
+
child.stdout.on("data", (chunk) => {
|
|
89
|
+
stdout += chunk;
|
|
90
|
+
if (opts.progress) process.stderr.write(chunk);
|
|
91
|
+
});
|
|
92
|
+
child.stderr.on("data", (chunk) => {
|
|
93
|
+
stderr += chunk;
|
|
94
|
+
if (opts.progress) process.stderr.write(chunk);
|
|
95
|
+
});
|
|
96
|
+
child.on("error", (err) => {
|
|
97
|
+
settle({ code: null, stdout, stderr, timedOut: false, spawnError: err.message });
|
|
98
|
+
});
|
|
99
|
+
child.on("close", (code) => {
|
|
100
|
+
settle({ code, stdout, stderr, timedOut: false });
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
var realSpawn = async (args, opts) => {
|
|
105
|
+
const launch = launchFor(args, {
|
|
106
|
+
platform: process.platform,
|
|
107
|
+
path: process.env["PATH"] ?? "",
|
|
108
|
+
isFile
|
|
109
|
+
});
|
|
110
|
+
assertFitsCommandLine(launch, process.platform);
|
|
111
|
+
if (!launch.viaShim) return streamed(launch, opts);
|
|
112
|
+
const result = await realExec([launch.command, ...launch.args], {
|
|
113
|
+
cwd: opts.cwd,
|
|
114
|
+
timeoutMs: NO_TIMEOUT
|
|
115
|
+
});
|
|
116
|
+
if (opts.progress) process.stderr.write(result.stdout + result.stderr);
|
|
117
|
+
return result;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// src/test/core/results.ts
|
|
121
|
+
import { relative } from "node:path";
|
|
122
|
+
var ZERO_COUNTS = { pass: 0, fail: 0, warning: 0, skipped: 0 };
|
|
123
|
+
function isRecord(value) {
|
|
124
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
125
|
+
}
|
|
126
|
+
function records(value) {
|
|
127
|
+
return Array.isArray(value) ? value.filter(isRecord) : [];
|
|
128
|
+
}
|
|
129
|
+
function counts(value) {
|
|
130
|
+
if (!isRecord(value)) return void 0;
|
|
131
|
+
const out = { ...ZERO_COUNTS };
|
|
132
|
+
for (const key of Object.keys(out)) {
|
|
133
|
+
const n = value[key];
|
|
134
|
+
if (typeof n !== "number") return void 0;
|
|
135
|
+
out[key] = n;
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
function parseResults(text) {
|
|
140
|
+
let parsed;
|
|
141
|
+
try {
|
|
142
|
+
parsed = JSON.parse(text);
|
|
143
|
+
} catch {
|
|
144
|
+
return void 0;
|
|
145
|
+
}
|
|
146
|
+
if (parsed === null) return null;
|
|
147
|
+
if (!isRecord(parsed) || !isRecord(parsed["summary"])) return void 0;
|
|
148
|
+
if (counts(parsed["summary"]["tests"]) === void 0) return void 0;
|
|
149
|
+
if (!Array.isArray(parsed["specs"])) return void 0;
|
|
150
|
+
return parsed;
|
|
151
|
+
}
|
|
152
|
+
function testCounts(results) {
|
|
153
|
+
if (results === null || !isRecord(results["summary"])) return { ...ZERO_COUNTS };
|
|
154
|
+
return counts(results["summary"]["tests"]) ?? { ...ZERO_COUNTS };
|
|
155
|
+
}
|
|
156
|
+
function anyFailed(results) {
|
|
157
|
+
if (results === null) return false;
|
|
158
|
+
const summary = results["summary"];
|
|
159
|
+
if (!isRecord(summary)) return false;
|
|
160
|
+
return Object.values(summary).some((level) => (counts(level)?.fail ?? 0) > 0);
|
|
161
|
+
}
|
|
162
|
+
function collectFindings(results, cwd) {
|
|
163
|
+
if (results === null) return [];
|
|
164
|
+
const out = [];
|
|
165
|
+
for (const spec of records(results["specs"])) {
|
|
166
|
+
for (const test of records(spec["tests"])) {
|
|
167
|
+
const contentPath = test["contentPath"] ?? spec["contentPath"];
|
|
168
|
+
const file = typeof contentPath !== "string" ? "" : /^[a-z][a-z0-9+.-]*:\/\//i.test(contentPath) ? contentPath : relative(cwd, contentPath).replace(/\\/g, "/");
|
|
169
|
+
for (const context of records(test["contexts"])) {
|
|
170
|
+
for (const step of records(context["steps"])) {
|
|
171
|
+
const result = step["result"];
|
|
172
|
+
if (result !== "FAIL" && result !== "WARNING") continue;
|
|
173
|
+
const location = step["location"];
|
|
174
|
+
const line = isRecord(location) ? location["line"] : void 0;
|
|
175
|
+
const description = step["resultDescription"];
|
|
176
|
+
out.push({
|
|
177
|
+
file,
|
|
178
|
+
...typeof line === "number" ? { line } : {},
|
|
179
|
+
result,
|
|
180
|
+
description: typeof description === "string" ? description : ""
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// src/test/commands/run.ts
|
|
190
|
+
var DOC_DETECTIVE_CONFIG_NAMES = [".doc-detective.json", ".doc-detective.yaml", ".doc-detective.yml"];
|
|
191
|
+
var NO_RESULTS = "Doc Detective wrote no results to read. Run doc-detective directly to see why.";
|
|
192
|
+
function empty(results = null) {
|
|
193
|
+
return { results, findings: [], tests: { pass: 0, fail: 0, warning: 0, skipped: 0 }, exitCode: 0 };
|
|
194
|
+
}
|
|
195
|
+
var toError = (message) => new TestError(message);
|
|
196
|
+
async function asTestError(work) {
|
|
197
|
+
try {
|
|
198
|
+
return await work();
|
|
199
|
+
} catch (err) {
|
|
200
|
+
if (err instanceof ToolError && !(err instanceof TestError)) throw new TestError(err.message);
|
|
201
|
+
throw err;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async function loadConfig(cwd, configPath) {
|
|
205
|
+
const opts = { section: "test", legacyNames: [], toError };
|
|
206
|
+
const file = configPath === void 0 ? await findConfigFile(cwd, opts) : await readConfigFile(configPath, cwd, opts);
|
|
207
|
+
if (file !== null && file.wrapped && file.value !== null) {
|
|
208
|
+
throw new TestError(
|
|
209
|
+
`${file.source}: test has no keys. Doc Detective's settings live under tools.doc-detective.`
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
return file;
|
|
213
|
+
}
|
|
214
|
+
async function positionalInputs(paths, cwd, allowEmpty) {
|
|
215
|
+
const inputs = [];
|
|
216
|
+
const missing = [];
|
|
217
|
+
for (const path of paths) {
|
|
218
|
+
const posix = path.replace(/\\/g, "/");
|
|
219
|
+
if (existsSync(resolve(cwd, posix))) {
|
|
220
|
+
inputs.push(path);
|
|
221
|
+
} else if (picomatch.scan(posix).isGlob) {
|
|
222
|
+
const found = await fg(posix, { cwd, ignore: DEFAULT_IGNORE, onlyFiles: true, dot: false });
|
|
223
|
+
inputs.push(...found.sort());
|
|
224
|
+
} else {
|
|
225
|
+
missing.push(posix);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (missing.length > 0 && !allowEmpty) throw new TestError(notFoundMessage(missing));
|
|
229
|
+
return inputs;
|
|
230
|
+
}
|
|
231
|
+
async function collectionInputs(file, names, cwd, allowEmpty) {
|
|
232
|
+
const collections = selectCollections(file.collections, names, file.source, toError);
|
|
233
|
+
const { files } = await asTestError(
|
|
234
|
+
() => resolveTargetSet({
|
|
235
|
+
inputs: collections.flatMap((c) => c.paths),
|
|
236
|
+
exclude: collections.flatMap((c) => c.exclude),
|
|
237
|
+
cwd: file.dir,
|
|
238
|
+
allowEmpty
|
|
239
|
+
})
|
|
240
|
+
);
|
|
241
|
+
return files.map((f) => relative2(cwd, resolve(file.dir, f)).replace(/\\/g, "/"));
|
|
242
|
+
}
|
|
243
|
+
async function readResults(outDir) {
|
|
244
|
+
const names = (await readdir(outDir)).filter((n) => /^testResults-.*\.json$/.test(n)).sort();
|
|
245
|
+
const last = names.at(-1);
|
|
246
|
+
if (last === void 0) throw new TestError(NO_RESULTS);
|
|
247
|
+
const results = parseResults(await readFile(join2(outDir, last), "utf8"));
|
|
248
|
+
if (results === void 0) throw new TestError(NO_RESULTS);
|
|
249
|
+
return results;
|
|
250
|
+
}
|
|
251
|
+
async function runTest(opts = {}) {
|
|
252
|
+
const cwd = resolve(opts.cwd ?? process.cwd());
|
|
253
|
+
const paths = opts.paths ?? [];
|
|
254
|
+
const wanted = opts.collection ?? [];
|
|
255
|
+
const allowEmpty = opts.allowEmpty ?? false;
|
|
256
|
+
if (paths.includes(STDIN_TOKEN)) {
|
|
257
|
+
throw new TestError("test run reads files; Doc Detective has no stdin. Pass a path.");
|
|
258
|
+
}
|
|
259
|
+
if (wanted.length > 0 && paths.length > 0) {
|
|
260
|
+
throw new TestError(
|
|
261
|
+
"--collection selects a configured collection; it cannot be combined with paths."
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
const file = await loadConfig(cwd, opts.configPath);
|
|
265
|
+
if (wanted.length > 0 && file === null) {
|
|
266
|
+
throw new TestError("--collection needs a config file to select from.");
|
|
267
|
+
}
|
|
268
|
+
const written = file?.tools["doc-detective"]?.config;
|
|
269
|
+
let ddConfig;
|
|
270
|
+
if (file !== null && written !== void 0) {
|
|
271
|
+
ddConfig = docDetectiveConfigPath(file.tools, file.dir);
|
|
272
|
+
if (ddConfig !== void 0 && !existsSync(ddConfig)) {
|
|
273
|
+
throw new TestError(`${file.source}: tools.doc-detective.config "${written}" does not exist.`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
let inputs;
|
|
277
|
+
if (paths.length > 0) {
|
|
278
|
+
inputs = await positionalInputs(paths, cwd, allowEmpty);
|
|
279
|
+
if (inputs.length === 0) {
|
|
280
|
+
if (allowEmpty) return empty();
|
|
281
|
+
const tried = paths.map((p) => `"${p}"`).join(", ");
|
|
282
|
+
throw new TestError(
|
|
283
|
+
`No files matched. Patterns tried: ${tried}. Pass --allow-empty if that is expected.`
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
} else if (file !== null && wanted.length > 0) {
|
|
287
|
+
inputs = await collectionInputs(file, wanted, cwd, allowEmpty);
|
|
288
|
+
if (inputs.length === 0) {
|
|
289
|
+
if (allowEmpty) return empty();
|
|
290
|
+
throw new TestError("--collection matched no files. Pass --allow-empty if that is expected.");
|
|
291
|
+
}
|
|
292
|
+
} else if (ddConfig === void 0 && !DOC_DETECTIVE_CONFIG_NAMES.some((name) => existsSync(join2(cwd, name)))) {
|
|
293
|
+
throw new TestError(
|
|
294
|
+
"test run needs paths or a Doc Detective config. Pass paths, or add .doc-detective.json."
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
const outDir = await mkdtemp(join2(tmpdir(), "manni-test-"));
|
|
298
|
+
try {
|
|
299
|
+
const args = [
|
|
300
|
+
// ponytail: Doc Detective splits -i on commas, so a path holding a comma
|
|
301
|
+
// is two inputs. Upgrade path: a generated config whose input is a list.
|
|
302
|
+
...inputs === void 0 ? [] : ["-i", inputs.join(",")],
|
|
303
|
+
...ddConfig === void 0 ? [] : ["-c", ddConfig],
|
|
304
|
+
"-r",
|
|
305
|
+
"json",
|
|
306
|
+
"-o",
|
|
307
|
+
outDir
|
|
308
|
+
];
|
|
309
|
+
const run = await (opts.spawn ?? realSpawn)(args, { cwd, progress: opts.progress ?? false });
|
|
310
|
+
if (run.spawnError !== void 0) throw new TestError(NOT_ON_PATH);
|
|
311
|
+
if (run.code !== 0) {
|
|
312
|
+
const how = run.code === null ? "killed before exiting" : `exit ${String(run.code)}`;
|
|
313
|
+
throw new TestError(`Doc Detective failed (${how}):
|
|
314
|
+
${outputTail(run)}`);
|
|
315
|
+
}
|
|
316
|
+
const results = await readResults(outDir);
|
|
317
|
+
const tests = testCounts(results);
|
|
318
|
+
const total = tests.pass + tests.fail + tests.warning + tests.skipped;
|
|
319
|
+
if (total === 0) {
|
|
320
|
+
if (allowEmpty) return empty(results);
|
|
321
|
+
throw new TestError(
|
|
322
|
+
"Doc Detective found no tests in the inputs. Pass --allow-empty if that is expected."
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
results,
|
|
327
|
+
findings: collectFindings(results, cwd),
|
|
328
|
+
tests,
|
|
329
|
+
exitCode: anyFailed(results) ? 1 : 0
|
|
330
|
+
};
|
|
331
|
+
} finally {
|
|
332
|
+
await rm(outDir, { recursive: true, force: true });
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/test/reporters/summary.ts
|
|
337
|
+
function summaryLine(tests) {
|
|
338
|
+
const total = tests.pass + tests.fail + tests.warning + tests.skipped;
|
|
339
|
+
const plural = (n, word) => `${String(n)} ${word}${n === 1 ? "" : "s"}`;
|
|
340
|
+
return `${plural(total, "test")}: ${String(tests.pass)} passed, ${String(tests.fail)} failed, ${plural(tests.warning, "warning")}, ${String(tests.skipped)} skipped`;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// src/test/reporters/github.ts
|
|
344
|
+
function renderGithub(result) {
|
|
345
|
+
const commands = result.findings.map((f) => {
|
|
346
|
+
const level = f.result === "FAIL" ? "error" : "warning";
|
|
347
|
+
const props = [
|
|
348
|
+
...f.file === "" ? [] : [`file=${escapeWorkflowCommandProperty(f.file)}`],
|
|
349
|
+
...f.line === void 0 ? [] : [`line=${String(f.line)}`],
|
|
350
|
+
"title=Doc Detective"
|
|
351
|
+
].join(",");
|
|
352
|
+
return `::${level} ${props}::${escapeWorkflowCommandMessage(f.description)}`;
|
|
353
|
+
});
|
|
354
|
+
return [...commands, summaryLine(result.tests)].join("\n");
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/test/reporters/json.ts
|
|
358
|
+
function renderJson(result) {
|
|
359
|
+
return JSON.stringify(result.results, null, 2);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// src/test/reporters/pretty.ts
|
|
363
|
+
function renderPretty(result, opts) {
|
|
364
|
+
const c = palette(opts.color);
|
|
365
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
366
|
+
for (const finding of result.findings) {
|
|
367
|
+
const list = byFile.get(finding.file);
|
|
368
|
+
if (list === void 0) byFile.set(finding.file, [finding]);
|
|
369
|
+
else list.push(finding);
|
|
370
|
+
}
|
|
371
|
+
const width = Math.max(0, ...result.findings.map((f) => String(f.line ?? "").length));
|
|
372
|
+
const blocks = [...byFile].map(
|
|
373
|
+
([file, findings]) => [
|
|
374
|
+
c.bold(file),
|
|
375
|
+
...findings.map((f) => {
|
|
376
|
+
const label = f.result.padEnd(7);
|
|
377
|
+
const tag = f.result === "FAIL" ? c.red(label) : c.yellow(label);
|
|
378
|
+
return ` ${String(f.line ?? "").padStart(width)} ${tag} ${f.description}`;
|
|
379
|
+
})
|
|
380
|
+
].join("\n")
|
|
381
|
+
);
|
|
382
|
+
return [...blocks, summaryLine(result.tests)].join("\n\n");
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export {
|
|
386
|
+
TestError,
|
|
387
|
+
realSpawn,
|
|
388
|
+
runTest,
|
|
389
|
+
renderGithub,
|
|
390
|
+
renderJson,
|
|
391
|
+
renderPretty
|
|
392
|
+
};
|
|
393
|
+
//# sourceMappingURL=chunk-T7JAOYE5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/test/errors.ts","../src/test/commands/run.ts","../src/test/core/doc-detective.ts","../src/test/core/results.ts","../src/test/reporters/summary.ts","../src/test/reporters/github.ts","../src/test/reporters/json.ts","../src/test/reporters/pretty.ts"],"sourcesContent":["import { ToolError } from \"../shared/errors.js\";\n\n/** An operational or usage error in the test domain: exit 2. */\nexport class TestError extends ToolError {\n constructor(message: string) {\n super(message);\n this.name = \"TestError\";\n }\n}\n","/**\n * `manni test run`: run Doc Detective and read its verdict from its results.\n *\n * Input precedence is positional paths, then `--collection`, then Doc\n * Detective's own config `input`. Without `--collection`, manni's collections\n * are not read: Doc Detective's config is this tool's default input.\n *\n * Doc Detective exits 0 when tests fail, so the exit code only says whether it\n * ran. The verdict is the results file it writes under `-o`, which is a temp\n * directory removed afterwards.\n */\nimport { existsSync } from \"node:fs\";\nimport { mkdtemp, readdir, readFile, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join, relative, resolve } from \"node:path\";\nimport fg from \"fast-glob\";\nimport picomatch from \"picomatch\";\nimport { selectCollections } from \"../../shared/collections.js\";\nimport { findConfigFile, readConfigFile, type ConfigFile } from \"../../shared/config-file.js\";\nimport { ToolError } from \"../../shared/errors.js\";\nimport { outputTail } from \"../../shared/exec.js\";\nimport { docDetectiveConfigPath } from \"../../shared/tools.js\";\nimport { DEFAULT_IGNORE, notFoundMessage, resolveTargetSet, STDIN_TOKEN } from \"../../meta/internal.js\";\nimport { NOT_ON_PATH, realSpawn, type DocDetectiveSpawn } from \"../core/doc-detective.js\";\nimport {\n anyFailed,\n collectFindings,\n parseResults,\n testCounts,\n type DocDetectiveResults,\n type ResultCounts,\n type TestFinding,\n} from \"../core/results.js\";\nimport { TestError } from \"../errors.js\";\n\nexport interface RunTestOptions {\n /** Positional files, directories and globs. */\n paths?: string[];\n /** `--collection <name>`, repeatable. */\n collection?: string[];\n /** `-c, --config`: a manni config file. */\n configPath?: string;\n cwd?: string;\n /** Finding no tests, or no inputs, is a pass. */\n allowEmpty?: boolean;\n /** Stream Doc Detective's output to stderr as it runs. */\n progress?: boolean;\n /** Test seam: how Doc Detective is started. */\n spawn?: DocDetectiveSpawn;\n}\n\nexport interface TestRunResult {\n /** Doc Detective's results object as it wrote it; `null` when it found no tests. */\n results: DocDetectiveResults | null;\n /** Every FAIL and WARNING step. */\n findings: TestFinding[];\n /** The test-level counts. */\n tests: ResultCounts;\n /** 1 when anything failed. */\n exitCode: 0 | 1;\n}\n\n/** What Doc Detective finds on its own in the working directory. */\nconst DOC_DETECTIVE_CONFIG_NAMES = [\".doc-detective.json\", \".doc-detective.yaml\", \".doc-detective.yml\"];\n\nconst NO_RESULTS = \"Doc Detective wrote no results to read. Run doc-detective directly to see why.\";\n\n/** A run with nothing to report; a fresh object each time, so no caller shares one. */\nfunction empty(results: DocDetectiveResults | null = null): TestRunResult {\n return { results, findings: [], tests: { pass: 0, fail: 0, warning: 0, skipped: 0 }, exitCode: 0 };\n}\n\nconst toError = (message: string): Error => new TestError(message);\n\n/** A sibling's `ToolError` (meta's walk, say) reported as this domain's. */\nasync function asTestError<T>(work: () => Promise<T>): Promise<T> {\n try {\n return await work();\n } catch (err) {\n if (err instanceof ToolError && !(err instanceof TestError)) throw new TestError(err.message);\n throw err;\n }\n}\n\nasync function loadConfig(cwd: string, configPath: string | undefined): Promise<ConfigFile | null> {\n const opts = { section: \"test\", legacyNames: [], toError };\n const file =\n configPath === undefined ? await findConfigFile(cwd, opts) : await readConfigFile(configPath, cwd, opts);\n // The domain has no keys of its own, so a `test:` section is a setting that\n // would otherwise read as configured and do nothing.\n if (file !== null && file.wrapped && file.value !== null) {\n throw new TestError(\n `${file.source}: test has no keys. Doc Detective's settings live under tools.doc-detective.`,\n );\n }\n return file;\n}\n\n/**\n * Positional inputs as Doc Detective takes them. Files and directories go as\n * typed, and Doc Detective walks a directory itself. A glob is expanded here.\n * A name that does not exist is refused, because Doc Detective skips one in\n * silence.\n */\nasync function positionalInputs(paths: string[], cwd: string, allowEmpty: boolean): Promise<string[]> {\n const inputs: string[] = [];\n const missing: string[] = [];\n for (const path of paths) {\n const posix = path.replace(/\\\\/g, \"/\");\n if (existsSync(resolve(cwd, posix))) {\n inputs.push(path);\n } else if (picomatch.scan(posix).isGlob) {\n const found = await fg(posix, { cwd, ignore: DEFAULT_IGNORE, onlyFiles: true, dot: false });\n inputs.push(...found.sort());\n } else {\n missing.push(posix);\n }\n }\n if (missing.length > 0 && !allowEmpty) throw new TestError(notFoundMessage(missing));\n return inputs;\n}\n\n/** The selected collections' files, minus their excludes, relative to `cwd`. */\nasync function collectionInputs(\n file: ConfigFile,\n names: string[],\n cwd: string,\n allowEmpty: boolean,\n): Promise<string[]> {\n const collections = selectCollections(file.collections, names, file.source, toError);\n const { files } = await asTestError(() =>\n resolveTargetSet({\n inputs: collections.flatMap((c) => c.paths),\n exclude: collections.flatMap((c) => c.exclude),\n cwd: file.dir,\n allowEmpty,\n }),\n );\n return files.map((f) => relative(cwd, resolve(file.dir, f)).replace(/\\\\/g, \"/\"));\n}\n\nasync function readResults(outDir: string): Promise<DocDetectiveResults | null> {\n const names = (await readdir(outDir)).filter((n) => /^testResults-.*\\.json$/.test(n)).sort();\n const last = names.at(-1);\n if (last === undefined) throw new TestError(NO_RESULTS);\n const results = parseResults(await readFile(join(outDir, last), \"utf8\"));\n if (results === undefined) throw new TestError(NO_RESULTS);\n return results;\n}\n\nexport async function runTest(opts: RunTestOptions = {}): Promise<TestRunResult> {\n const cwd = resolve(opts.cwd ?? process.cwd());\n const paths = opts.paths ?? [];\n const wanted = opts.collection ?? [];\n const allowEmpty = opts.allowEmpty ?? false;\n\n if (paths.includes(STDIN_TOKEN)) {\n throw new TestError(\"test run reads files; Doc Detective has no stdin. Pass a path.\");\n }\n // lint's two sentences: a collection is a set the operator did not type, so\n // it composes with no typed path, and only a config can define one.\n if (wanted.length > 0 && paths.length > 0) {\n throw new TestError(\n \"--collection selects a configured collection; it cannot be combined with paths.\",\n );\n }\n const file = await loadConfig(cwd, opts.configPath);\n if (wanted.length > 0 && file === null) {\n throw new TestError(\"--collection needs a config file to select from.\");\n }\n\n // The path as written names the file in the refusal; the resolved one is\n // what Doc Detective is given.\n const written = file?.tools[\"doc-detective\"]?.config;\n let ddConfig: string | undefined;\n if (file !== null && written !== undefined) {\n ddConfig = docDetectiveConfigPath(file.tools, file.dir);\n if (ddConfig !== undefined && !existsSync(ddConfig)) {\n throw new TestError(`${file.source}: tools.doc-detective.config \"${written}\" does not exist.`);\n }\n }\n\n let inputs: string[] | undefined;\n if (paths.length > 0) {\n inputs = await positionalInputs(paths, cwd, allowEmpty);\n if (inputs.length === 0) {\n if (allowEmpty) return empty();\n const tried = paths.map((p) => `\"${p}\"`).join(\", \");\n throw new TestError(\n `No files matched. Patterns tried: ${tried}. Pass --allow-empty if that is expected.`,\n );\n }\n } else if (file !== null && wanted.length > 0) {\n inputs = await collectionInputs(file, wanted, cwd, allowEmpty);\n if (inputs.length === 0) {\n if (allowEmpty) return empty();\n throw new TestError(\"--collection matched no files. Pass --allow-empty if that is expected.\");\n }\n } else if (\n ddConfig === undefined &&\n !DOC_DETECTIVE_CONFIG_NAMES.some((name) => existsSync(join(cwd, name)))\n ) {\n throw new TestError(\n \"test run needs paths or a Doc Detective config. Pass paths, or add .doc-detective.json.\",\n );\n }\n\n const outDir = await mkdtemp(join(tmpdir(), \"manni-test-\"));\n try {\n const args = [\n // ponytail: Doc Detective splits -i on commas, so a path holding a comma\n // is two inputs. Upgrade path: a generated config whose input is a list.\n ...(inputs === undefined ? [] : [\"-i\", inputs.join(\",\")]),\n ...(ddConfig === undefined ? [] : [\"-c\", ddConfig]),\n \"-r\",\n \"json\",\n \"-o\",\n outDir,\n ];\n const run = await (opts.spawn ?? realSpawn)(args, { cwd, progress: opts.progress ?? false });\n if (run.spawnError !== undefined) throw new TestError(NOT_ON_PATH);\n if (run.code !== 0) {\n const how = run.code === null ? \"killed before exiting\" : `exit ${String(run.code)}`;\n throw new TestError(`Doc Detective failed (${how}):\\n${outputTail(run)}`);\n }\n\n const results = await readResults(outDir);\n const tests = testCounts(results);\n const total = tests.pass + tests.fail + tests.warning + tests.skipped;\n // A `null` results file counts as zero tests, so `total` covers it.\n if (total === 0) {\n if (allowEmpty) return empty(results);\n throw new TestError(\n \"Doc Detective found no tests in the inputs. Pass --allow-empty if that is expected.\",\n );\n }\n return {\n results,\n findings: collectFindings(results, cwd),\n tests,\n exitCode: anyFailed(results) ? 1 : 0,\n };\n } finally {\n await rm(outDir, { recursive: true, force: true });\n }\n}\n","/**\n * The Doc Detective process seam: the only module that starts `doc-detective`.\n * Unit tests inject a `DocDetectiveSpawn`; the real one is `realSpawn`.\n *\n * On Windows an npm global install puts a `.cmd` shim on PATH, and `cmd.exe`\n * caps the command line it runs at 8191 characters, which a collection of a\n * few hundred pages passes. So the bin script the shim points at is run with\n * node directly. Only when no script sits beside the shim does the shim run,\n * through `realExec`, which knows how to start one without a shell.\n */\nimport { spawn } from \"node:child_process\";\nimport { statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ExecResult } from \"@hawkeyexl/inference\";\nimport { realExec } from \"../../shared/exec.js\";\nimport { TestError } from \"../errors.js\";\n\n/**\n * Start Doc Detective with `args` (its own flags, no program name) and wait\n * for it. `progress` streams its output to stderr as it runs; the output is\n * captured either way.\n */\nexport type DocDetectiveSpawn = (\n args: string[],\n opts: { cwd: string; progress: boolean },\n) => Promise<ExecResult>;\n\n/** How Doc Detective is started on this host. */\nexport interface Launch {\n command: string;\n args: string[];\n /** Started through a Windows `.cmd` shim, so `cmd.exe`'s cap applies. */\n viaShim: boolean;\n}\n\nexport const NOT_ON_PATH =\n \"doc-detective is not on PATH. Install Doc Detective (npm install -g doc-detective) to run doc tests.\";\n\nconst COMMAND_LINE_LIMIT =\n \"the selected inputs exceed the command-line limit. Narrow the collection, or set input in the Doc Detective config.\";\n\n/** No timeout: a docs suite runs as long as its tests do. */\nconst NO_TIMEOUT = 2 ** 31 - 1;\n\nexport function launchFor(\n args: string[],\n host: { platform: NodeJS.Platform; path: string; isFile: (path: string) => boolean },\n): Launch {\n if (host.platform !== \"win32\") return { command: \"doc-detective\", args, viaShim: false };\n // Windows lets a PATH entry be quoted, as in \"C:\\Program Files\\nodejs\".\n for (const entry of host.path.split(\";\")) {\n const dir = entry.replace(/^\"(.*)\"$/, \"$1\");\n if (dir === \"\" || !host.isFile(join(dir, \"doc-detective.cmd\"))) continue;\n const script = join(dir, \"node_modules\", \"doc-detective\", \"bin\", \"doc-detective.js\");\n if (host.isFile(script)) {\n return { command: process.execPath, args: [script, ...args], viaShim: false };\n }\n break;\n }\n return { command: \"doc-detective\", args, viaShim: true };\n}\n\n/**\n * Refuse a command line Windows would truncate or reject.\n *\n * ponytail: Windows caps a command line at 32,767 characters, and at 8,191\n * through a `.cmd` shim. Past the cap the run is refused. The upgrade path is\n * running the inputs in batches and merging the results files.\n */\nexport function assertFitsCommandLine(launch: Launch, platform: NodeJS.Platform): void {\n if (platform !== \"win32\") return;\n // Each argument costs its quotes and the space before it.\n const length = [launch.command, ...launch.args].reduce((n, arg) => n + arg.length + 3, 0);\n if (length > (launch.viaShim ? 8_191 : 32_767)) throw new TestError(COMMAND_LINE_LIMIT);\n}\n\nfunction isFile(path: string): boolean {\n try {\n return statSync(path).isFile();\n } catch {\n return false;\n }\n}\n\nfunction streamed(launch: Launch, opts: { cwd: string; progress: boolean }): Promise<ExecResult> {\n return new Promise((settle) => {\n let stdout = \"\";\n let stderr = \"\";\n const child = spawn(launch.command, launch.args, {\n cwd: opts.cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n windowsHide: true,\n });\n child.stdout.setEncoding(\"utf8\");\n child.stderr.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n stdout += chunk;\n if (opts.progress) process.stderr.write(chunk);\n });\n child.stderr.on(\"data\", (chunk: string) => {\n stderr += chunk;\n if (opts.progress) process.stderr.write(chunk);\n });\n child.on(\"error\", (err) => {\n settle({ code: null, stdout, stderr, timedOut: false, spawnError: err.message });\n });\n child.on(\"close\", (code) => {\n settle({ code, stdout, stderr, timedOut: false });\n });\n });\n}\n\nexport const realSpawn: DocDetectiveSpawn = async (args, opts) => {\n const launch = launchFor(args, {\n platform: process.platform,\n path: process.env[\"PATH\"] ?? \"\",\n isFile,\n });\n assertFitsCommandLine(launch, process.platform);\n if (!launch.viaShim) return streamed(launch, opts);\n // ponytail: the shim path captures and replays rather than streaming live.\n // It runs only when a shim has no bin script beside it.\n const result = await realExec([launch.command, ...launch.args], {\n cwd: opts.cwd,\n timeoutMs: NO_TIMEOUT,\n });\n if (opts.progress) process.stderr.write(result.stdout + result.stderr);\n return result;\n};\n","/**\n * Doc Detective's results file, read across a process boundary.\n *\n * The object is kept as Doc Detective wrote it, because `-f json` prints it\n * verbatim. Only the parts the verdict and the reports need are checked: the\n * test-level counts, and each step's result, description and line.\n */\nimport { relative } from \"node:path\";\n\n/** One level's counts in Doc Detective's `summary`. */\nexport interface ResultCounts {\n pass: number;\n fail: number;\n warning: number;\n skipped: number;\n}\n\n/** Doc Detective's results object, as it wrote it. */\nexport type DocDetectiveResults = Record<string, unknown>;\n\n/** A step that FAILed or WARNed, named by the page it came from. */\nexport interface TestFinding {\n /** The page, posix and relative to the run's working directory. */\n file: string;\n /** The step's line in the page, when Doc Detective located it. */\n line?: number;\n result: \"FAIL\" | \"WARNING\";\n description: string;\n}\n\nexport const ZERO_COUNTS: ResultCounts = { pass: 0, fail: 0, warning: 0, skipped: 0 };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction records(value: unknown): Record<string, unknown>[] {\n return Array.isArray(value) ? value.filter(isRecord) : [];\n}\n\nfunction counts(value: unknown): ResultCounts | undefined {\n if (!isRecord(value)) return undefined;\n const out = { ...ZERO_COUNTS };\n for (const key of Object.keys(out) as (keyof ResultCounts)[]) {\n const n = value[key];\n if (typeof n !== \"number\") return undefined;\n out[key] = n;\n }\n return out;\n}\n\n/**\n * Parse a results file. `null` is what Doc Detective writes when it found no\n * tests. `undefined` is a file that is not a results object at all.\n */\nexport function parseResults(text: string): DocDetectiveResults | null | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return undefined;\n }\n if (parsed === null) return null;\n if (!isRecord(parsed) || !isRecord(parsed[\"summary\"])) return undefined;\n if (counts(parsed[\"summary\"][\"tests\"]) === undefined) return undefined;\n if (!Array.isArray(parsed[\"specs\"])) return undefined;\n return parsed;\n}\n\n/** The test-level counts, which the summary line reports. */\nexport function testCounts(results: DocDetectiveResults | null): ResultCounts {\n if (results === null || !isRecord(results[\"summary\"])) return { ...ZERO_COUNTS };\n return counts(results[\"summary\"][\"tests\"]) ?? { ...ZERO_COUNTS };\n}\n\n/** Whether anything failed, at any level Doc Detective counts. */\nexport function anyFailed(results: DocDetectiveResults | null): boolean {\n if (results === null) return false;\n const summary = results[\"summary\"];\n if (!isRecord(summary)) return false;\n return Object.values(summary).some((level) => (counts(level)?.fail ?? 0) > 0);\n}\n\n/** Every FAIL and WARNING step, in the order Doc Detective ran them. */\nexport function collectFindings(results: DocDetectiveResults | null, cwd: string): TestFinding[] {\n if (results === null) return [];\n const out: TestFinding[] = [];\n for (const spec of records(results[\"specs\"])) {\n for (const test of records(spec[\"tests\"])) {\n const contentPath = test[\"contentPath\"] ?? spec[\"contentPath\"];\n // Without a contentPath the file is unknown, and `\"\"` says so: the\n // github reporter then leaves `file=` off the annotation. A URL input\n // is reported as Doc Detective names it; only a file path is relative.\n const file =\n typeof contentPath !== \"string\"\n ? \"\"\n : /^[a-z][a-z0-9+.-]*:\\/\\//i.test(contentPath)\n ? contentPath\n : relative(cwd, contentPath).replace(/\\\\/g, \"/\");\n for (const context of records(test[\"contexts\"])) {\n for (const step of records(context[\"steps\"])) {\n const result = step[\"result\"];\n if (result !== \"FAIL\" && result !== \"WARNING\") continue;\n const location = step[\"location\"];\n const line = isRecord(location) ? location[\"line\"] : undefined;\n const description = step[\"resultDescription\"];\n out.push({\n file,\n ...(typeof line === \"number\" ? { line } : {}),\n result,\n description: typeof description === \"string\" ? description : \"\",\n });\n }\n }\n }\n }\n return out;\n}\n","import type { ResultCounts } from \"../core/results.js\";\n\n/** `2 tests: 1 passed, 1 failed, 0 warnings, 0 skipped`, test-level counts. */\nexport function summaryLine(tests: ResultCounts): string {\n const total = tests.pass + tests.fail + tests.warning + tests.skipped;\n const plural = (n: number, word: string): string => `${String(n)} ${word}${n === 1 ? \"\" : \"s\"}`;\n return `${plural(total, \"test\")}: ${String(tests.pass)} passed, ${String(tests.fail)} failed, ${plural(tests.warning, \"warning\")}, ${String(tests.skipped)} skipped`;\n}\n","import {\n escapeWorkflowCommandMessage,\n escapeWorkflowCommandProperty,\n} from \"../../shared/github.js\";\nimport type { TestRunResult } from \"../commands/run.js\";\nimport { summaryLine } from \"./summary.js\";\n\n/** One workflow command per FAIL or WARNING step, then the summary line. */\nexport function renderGithub(result: TestRunResult): string {\n const commands = result.findings.map((f) => {\n const level = f.result === \"FAIL\" ? \"error\" : \"warning\";\n const props = [\n ...(f.file === \"\" ? [] : [`file=${escapeWorkflowCommandProperty(f.file)}`]),\n ...(f.line === undefined ? [] : [`line=${String(f.line)}`]),\n \"title=Doc Detective\",\n ].join(\",\");\n return `::${level} ${props}::${escapeWorkflowCommandMessage(f.description)}`;\n });\n return [...commands, summaryLine(result.tests)].join(\"\\n\");\n}\n","import type { TestRunResult } from \"../commands/run.js\";\n\n/**\n * Doc Detective's results object, verbatim, so a script written against its\n * schema reads manni's output unchanged. `null` when it found no tests.\n */\nexport function renderJson(result: TestRunResult): string {\n return JSON.stringify(result.results, null, 2);\n}\n","import { palette } from \"../../shared/color.js\";\nimport type { TestRunResult } from \"../commands/run.js\";\nimport type { TestFinding } from \"../core/results.js\";\nimport { summaryLine } from \"./summary.js\";\n\n/**\n * Each FAIL and WARNING step under its page, with its line, then the\n * test-level summary. A run with neither prints the summary alone.\n */\nexport function renderPretty(result: TestRunResult, opts: { color: boolean }): string {\n const c = palette(opts.color);\n const byFile = new Map<string, TestFinding[]>();\n for (const finding of result.findings) {\n const list = byFile.get(finding.file);\n if (list === undefined) byFile.set(finding.file, [finding]);\n else list.push(finding);\n }\n const width = Math.max(0, ...result.findings.map((f) => String(f.line ?? \"\").length));\n const blocks = [...byFile].map(([file, findings]) =>\n [\n c.bold(file),\n ...findings.map((f) => {\n const label = f.result.padEnd(7);\n const tag = f.result === \"FAIL\" ? c.red(label) : c.yellow(label);\n return ` ${String(f.line ?? \"\").padStart(width)} ${tag} ${f.description}`;\n }),\n ].join(\"\\n\"),\n );\n return [...blocks, summaryLine(result.tests)].join(\"\\n\\n\");\n}\n"],"mappings":"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","names":["join","relative","relative","join"]}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
isTurnBudgetSkip
|
|
4
|
-
|
|
5
|
-
realExec
|
|
6
|
-
} from "./chunk-XG6PVB5S.js";
|
|
3
|
+
isTurnBudgetSkip
|
|
4
|
+
} from "./chunk-SSQZB5SQ.js";
|
|
7
5
|
import {
|
|
8
6
|
EXECUTION_GRANTS,
|
|
9
7
|
NOT_GRANTED_REASON,
|
|
@@ -12,34 +10,38 @@ import {
|
|
|
12
10
|
isExecutionGrant,
|
|
13
11
|
unknownGrantsMessage
|
|
14
12
|
} from "./chunk-YNHZHSSM.js";
|
|
13
|
+
import {
|
|
14
|
+
outputTail,
|
|
15
|
+
realExec
|
|
16
|
+
} from "./chunk-ZPLVANY2.js";
|
|
15
17
|
import {
|
|
16
18
|
DocevalsError
|
|
17
19
|
} from "./chunk-SE4JN5XN.js";
|
|
18
20
|
import {
|
|
19
21
|
declaredAt
|
|
20
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-LKP7QDFN.js";
|
|
21
23
|
import {
|
|
22
24
|
metaProvenanceEntries
|
|
23
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-M42DZCOU.js";
|
|
24
26
|
import {
|
|
25
27
|
familyMarks,
|
|
26
28
|
loadExternalMetadata,
|
|
27
29
|
memberOf,
|
|
28
30
|
mergeWithMarks,
|
|
29
31
|
provenanceEntries
|
|
30
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-GV56WGL2.js";
|
|
31
33
|
import {
|
|
32
34
|
__default,
|
|
33
35
|
classifyRef,
|
|
34
36
|
extractFrontmatter
|
|
35
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-VSEBFHAY.js";
|
|
36
38
|
import {
|
|
37
39
|
findConfigFileSync,
|
|
38
40
|
ownsKey,
|
|
39
41
|
parseCollections,
|
|
40
42
|
readConfigFileSync,
|
|
41
43
|
selectCollections
|
|
42
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-QLWC7MKD.js";
|
|
43
45
|
import {
|
|
44
46
|
warn
|
|
45
47
|
} from "./chunk-HX44GB4Z.js";
|
|
@@ -2958,4 +2960,4 @@ export {
|
|
|
2958
2960
|
applySelection,
|
|
2959
2961
|
runEvals
|
|
2960
2962
|
};
|
|
2961
|
-
//# sourceMappingURL=chunk-
|
|
2963
|
+
//# sourceMappingURL=chunk-U7CTFN2J.js.map
|