@mcptoolshop/venvkit 0.2.5 → 1.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/README.es.md +143 -132
- package/README.fr.md +143 -132
- package/README.hi.md +143 -136
- package/README.it.md +143 -132
- package/README.ja.md +143 -132
- package/README.md +15 -4
- package/README.pt-BR.md +143 -132
- package/README.zh.md +143 -132
- package/dist/doctorLite.d.ts +75 -0
- package/dist/doctorLite.d.ts.map +1 -0
- package/dist/doctorLite.js +705 -0
- package/dist/doctorLite.js.map +1 -0
- package/dist/doctorLite.test.d.ts +2 -0
- package/dist/doctorLite.test.d.ts.map +1 -0
- package/dist/doctorLite.test.js +268 -0
- package/dist/doctorLite.test.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/integration.test.d.ts +2 -0
- package/dist/integration.test.d.ts.map +1 -0
- package/dist/integration.test.js +245 -0
- package/dist/integration.test.js.map +1 -0
- package/dist/mapRender.d.ts +105 -0
- package/dist/mapRender.d.ts.map +1 -0
- package/dist/mapRender.js +718 -0
- package/dist/mapRender.js.map +1 -0
- package/dist/mapRender.test.d.ts +2 -0
- package/dist/mapRender.test.d.ts.map +1 -0
- package/dist/mapRender.test.js +571 -0
- package/dist/mapRender.test.js.map +1 -0
- package/dist/map_cli.d.ts +3 -0
- package/dist/map_cli.d.ts.map +1 -0
- package/dist/map_cli.js +278 -0
- package/dist/map_cli.js.map +1 -0
- package/dist/map_cli.test.d.ts +2 -0
- package/dist/map_cli.test.d.ts.map +1 -0
- package/dist/map_cli.test.js +320 -0
- package/dist/map_cli.test.js.map +1 -0
- package/dist/runLog.d.ts +71 -0
- package/dist/runLog.d.ts.map +1 -0
- package/dist/runLog.js +98 -0
- package/dist/runLog.js.map +1 -0
- package/dist/runLog.test.d.ts +2 -0
- package/dist/runLog.test.d.ts.map +1 -0
- package/dist/runLog.test.js +327 -0
- package/dist/runLog.test.js.map +1 -0
- package/dist/scanEnvPaths.d.ts +18 -0
- package/dist/scanEnvPaths.d.ts.map +1 -0
- package/dist/scanEnvPaths.js +177 -0
- package/dist/scanEnvPaths.js.map +1 -0
- package/dist/scanEnvPaths.test.d.ts +2 -0
- package/dist/scanEnvPaths.test.d.ts.map +1 -0
- package/dist/scanEnvPaths.test.js +250 -0
- package/dist/scanEnvPaths.test.js.map +1 -0
- package/dist/taskCluster.d.ts +62 -0
- package/dist/taskCluster.d.ts.map +1 -0
- package/dist/taskCluster.js +180 -0
- package/dist/taskCluster.js.map +1 -0
- package/dist/taskCluster.test.d.ts +2 -0
- package/dist/taskCluster.test.d.ts.map +1 -0
- package/dist/taskCluster.test.js +375 -0
- package/dist/taskCluster.test.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +26 -0
- package/dist/vitest.config.js.map +1 -0
- package/dist/windows.test.d.ts +6 -0
- package/dist/windows.test.d.ts.map +1 -0
- package/dist/windows.test.js +121 -0
- package/dist/windows.test.js.map +1 -0
- package/package.json +6 -2
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
// scanEnvPaths.test.ts
|
|
2
|
+
// Unit tests for environment path discovery
|
|
3
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
4
|
+
import * as fs from "node:fs/promises";
|
|
5
|
+
import * as path from "node:path";
|
|
6
|
+
import * as os from "node:os";
|
|
7
|
+
import { scanEnvPaths } from "./scanEnvPaths.js";
|
|
8
|
+
describe("scanEnvPaths", () => {
|
|
9
|
+
let tempDir;
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "venvkit-scan-test-"));
|
|
12
|
+
});
|
|
13
|
+
afterEach(async () => {
|
|
14
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
15
|
+
});
|
|
16
|
+
// Helper to create a mock venv structure
|
|
17
|
+
async function createMockVenv(venvPath) {
|
|
18
|
+
await fs.mkdir(venvPath, { recursive: true });
|
|
19
|
+
await fs.writeFile(path.join(venvPath, "pyvenv.cfg"), "home = C:\\Python311\nversion = 3.11.5\n");
|
|
20
|
+
const binDir = os.platform() === "win32" ? "Scripts" : "bin";
|
|
21
|
+
const pyExe = os.platform() === "win32" ? "python.exe" : "python";
|
|
22
|
+
await fs.mkdir(path.join(venvPath, binDir), { recursive: true });
|
|
23
|
+
await fs.writeFile(path.join(venvPath, binDir, pyExe), "fake python");
|
|
24
|
+
return path.join(venvPath, binDir, pyExe);
|
|
25
|
+
}
|
|
26
|
+
describe("finding Python venvs", () => {
|
|
27
|
+
it("finds venv with pyvenv.cfg", async () => {
|
|
28
|
+
const venvPath = path.join(tempDir, "project", ".venv");
|
|
29
|
+
await createMockVenv(venvPath);
|
|
30
|
+
const result = await scanEnvPaths({
|
|
31
|
+
roots: [path.join(tempDir, "project")],
|
|
32
|
+
maxDepth: 3,
|
|
33
|
+
includeUserHomeCache: false,
|
|
34
|
+
});
|
|
35
|
+
expect(result.pythonPaths.length).toBeGreaterThanOrEqual(1);
|
|
36
|
+
expect(result.meta.foundVenvs).toBeGreaterThanOrEqual(1);
|
|
37
|
+
});
|
|
38
|
+
it("finds multiple venvs in project tree", async () => {
|
|
39
|
+
await createMockVenv(path.join(tempDir, "project1", ".venv"));
|
|
40
|
+
await createMockVenv(path.join(tempDir, "project2", "venv"));
|
|
41
|
+
await createMockVenv(path.join(tempDir, "project3", "env"));
|
|
42
|
+
const result = await scanEnvPaths({
|
|
43
|
+
roots: [tempDir],
|
|
44
|
+
maxDepth: 3,
|
|
45
|
+
includeUserHomeCache: false,
|
|
46
|
+
});
|
|
47
|
+
expect(result.meta.foundVenvs).toBeGreaterThanOrEqual(3);
|
|
48
|
+
});
|
|
49
|
+
it("finds venv in standard project locations", async () => {
|
|
50
|
+
// Test standard venv folder names: .venv, venv, env
|
|
51
|
+
const projectRoot = path.join(tempDir, "myproject");
|
|
52
|
+
await fs.mkdir(projectRoot, { recursive: true });
|
|
53
|
+
const venvPath = path.join(projectRoot, ".venv");
|
|
54
|
+
await createMockVenv(venvPath);
|
|
55
|
+
const result = await scanEnvPaths({
|
|
56
|
+
roots: [projectRoot],
|
|
57
|
+
maxDepth: 3,
|
|
58
|
+
includeUserHomeCache: false,
|
|
59
|
+
});
|
|
60
|
+
expect(result.pythonPaths.some(p => p.includes(".venv"))).toBe(true);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe("scan options", () => {
|
|
64
|
+
it("respects maxDepth limit", async () => {
|
|
65
|
+
// Create venv at depth 2
|
|
66
|
+
await createMockVenv(path.join(tempDir, "level1", ".venv"));
|
|
67
|
+
// Create venv at depth 4 (should not be found with maxDepth=2)
|
|
68
|
+
await createMockVenv(path.join(tempDir, "level1", "level2", "level3", ".venv"));
|
|
69
|
+
const result = await scanEnvPaths({
|
|
70
|
+
roots: [tempDir],
|
|
71
|
+
maxDepth: 2,
|
|
72
|
+
includeUserHomeCache: false,
|
|
73
|
+
});
|
|
74
|
+
// Should find shallow venv but not deeply nested one
|
|
75
|
+
const foundPaths = result.pythonPaths.filter(p => p.includes(tempDir));
|
|
76
|
+
expect(foundPaths.length).toBe(1);
|
|
77
|
+
});
|
|
78
|
+
it("ignores hidden directories by default", async () => {
|
|
79
|
+
await createMockVenv(path.join(tempDir, ".hidden", "venv"));
|
|
80
|
+
await createMockVenv(path.join(tempDir, "visible", "venv"));
|
|
81
|
+
const result = await scanEnvPaths({
|
|
82
|
+
roots: [tempDir],
|
|
83
|
+
maxDepth: 3,
|
|
84
|
+
includeHidden: false,
|
|
85
|
+
includeUserHomeCache: false,
|
|
86
|
+
});
|
|
87
|
+
const foundPaths = result.pythonPaths.filter(p => p.includes(tempDir));
|
|
88
|
+
expect(foundPaths.some(p => p.includes(".hidden"))).toBe(false);
|
|
89
|
+
expect(foundPaths.some(p => p.includes("visible"))).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
it("includes hidden directories when flag is set", async () => {
|
|
92
|
+
await createMockVenv(path.join(tempDir, ".hidden", "venv"));
|
|
93
|
+
const result = await scanEnvPaths({
|
|
94
|
+
roots: [tempDir],
|
|
95
|
+
maxDepth: 3,
|
|
96
|
+
includeHidden: true,
|
|
97
|
+
includeUserHomeCache: false,
|
|
98
|
+
});
|
|
99
|
+
const foundPaths = result.pythonPaths.filter(p => p.includes(tempDir));
|
|
100
|
+
expect(foundPaths.some(p => p.includes(".hidden"))).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
it("deduplicates paths by default", async () => {
|
|
103
|
+
const venvPath = path.join(tempDir, "project", ".venv");
|
|
104
|
+
await createMockVenv(venvPath);
|
|
105
|
+
// Scan same root twice
|
|
106
|
+
const result = await scanEnvPaths({
|
|
107
|
+
roots: [path.join(tempDir, "project"), path.join(tempDir, "project")],
|
|
108
|
+
maxDepth: 3,
|
|
109
|
+
dedupe: true,
|
|
110
|
+
includeUserHomeCache: false,
|
|
111
|
+
});
|
|
112
|
+
const foundPaths = result.pythonPaths.filter(p => p.includes(tempDir));
|
|
113
|
+
// Should only have one entry despite scanning same location twice
|
|
114
|
+
expect(new Set(foundPaths).size).toBe(foundPaths.length);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
describe("handling edge cases", () => {
|
|
118
|
+
it("handles empty directory", async () => {
|
|
119
|
+
const emptyDir = path.join(tempDir, "empty");
|
|
120
|
+
await fs.mkdir(emptyDir, { recursive: true });
|
|
121
|
+
const result = await scanEnvPaths({
|
|
122
|
+
roots: [emptyDir],
|
|
123
|
+
maxDepth: 3,
|
|
124
|
+
includeUserHomeCache: false,
|
|
125
|
+
});
|
|
126
|
+
const foundInTemp = result.pythonPaths.filter(p => p.includes(tempDir));
|
|
127
|
+
expect(foundInTemp.length).toBe(0);
|
|
128
|
+
});
|
|
129
|
+
it("handles permission errors gracefully", async () => {
|
|
130
|
+
// This test might behave differently on Windows vs POSIX
|
|
131
|
+
// The key is that it doesn't throw
|
|
132
|
+
const result = await scanEnvPaths({
|
|
133
|
+
roots: ["/nonexistent/path/that/should/not/exist"],
|
|
134
|
+
maxDepth: 3,
|
|
135
|
+
includeUserHomeCache: false,
|
|
136
|
+
});
|
|
137
|
+
expect(result).toBeDefined();
|
|
138
|
+
expect(result.pythonPaths).toBeDefined();
|
|
139
|
+
});
|
|
140
|
+
it("skips node_modules directory", async () => {
|
|
141
|
+
// Create a venv inside node_modules (should be skipped)
|
|
142
|
+
await createMockVenv(path.join(tempDir, "node_modules", "some-pkg", ".venv"));
|
|
143
|
+
await createMockVenv(path.join(tempDir, "src", ".venv"));
|
|
144
|
+
const result = await scanEnvPaths({
|
|
145
|
+
roots: [tempDir],
|
|
146
|
+
maxDepth: 5,
|
|
147
|
+
includeUserHomeCache: false,
|
|
148
|
+
});
|
|
149
|
+
const foundPaths = result.pythonPaths.filter(p => p.includes(tempDir));
|
|
150
|
+
expect(foundPaths.some(p => p.includes("node_modules"))).toBe(false);
|
|
151
|
+
expect(foundPaths.some(p => p.includes("src"))).toBe(true);
|
|
152
|
+
});
|
|
153
|
+
it("skips .git directory", async () => {
|
|
154
|
+
await createMockVenv(path.join(tempDir, ".git", "hooks", ".venv"));
|
|
155
|
+
await createMockVenv(path.join(tempDir, "app", ".venv"));
|
|
156
|
+
const result = await scanEnvPaths({
|
|
157
|
+
roots: [tempDir],
|
|
158
|
+
maxDepth: 5,
|
|
159
|
+
includeHidden: true, // Even with hidden enabled, .git should be skipped
|
|
160
|
+
includeUserHomeCache: false,
|
|
161
|
+
});
|
|
162
|
+
const foundPaths = result.pythonPaths.filter(p => p.includes(tempDir));
|
|
163
|
+
expect(foundPaths.some(p => p.includes(".git"))).toBe(false);
|
|
164
|
+
});
|
|
165
|
+
it("handles venv without python executable", async () => {
|
|
166
|
+
// Create pyvenv.cfg but no python executable
|
|
167
|
+
const venvPath = path.join(tempDir, "broken-venv");
|
|
168
|
+
await fs.mkdir(venvPath, { recursive: true });
|
|
169
|
+
await fs.writeFile(path.join(venvPath, "pyvenv.cfg"), "home = C:\\Python311\n");
|
|
170
|
+
// Deliberately don't create Scripts/python.exe
|
|
171
|
+
const result = await scanEnvPaths({
|
|
172
|
+
roots: [tempDir],
|
|
173
|
+
maxDepth: 3,
|
|
174
|
+
includeUserHomeCache: false,
|
|
175
|
+
});
|
|
176
|
+
// Should not crash, and should not find the broken venv
|
|
177
|
+
const foundBroken = result.pythonPaths.filter(p => p.includes("broken-venv"));
|
|
178
|
+
expect(foundBroken.length).toBe(0);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
describe("meta information", () => {
|
|
182
|
+
it("reports scanned roots in meta", async () => {
|
|
183
|
+
const root1 = path.join(tempDir, "root1");
|
|
184
|
+
const root2 = path.join(tempDir, "root2");
|
|
185
|
+
await fs.mkdir(root1, { recursive: true });
|
|
186
|
+
await fs.mkdir(root2, { recursive: true });
|
|
187
|
+
const result = await scanEnvPaths({
|
|
188
|
+
roots: [root1, root2],
|
|
189
|
+
maxDepth: 3,
|
|
190
|
+
includeUserHomeCache: false,
|
|
191
|
+
});
|
|
192
|
+
expect(result.meta.scannedRoots).toContain(root1);
|
|
193
|
+
expect(result.meta.scannedRoots).toContain(root2);
|
|
194
|
+
expect(result.meta.maxDepth).toBe(3);
|
|
195
|
+
});
|
|
196
|
+
it("counts venvs and bases separately", async () => {
|
|
197
|
+
await createMockVenv(path.join(tempDir, "venv1"));
|
|
198
|
+
await createMockVenv(path.join(tempDir, "venv2"));
|
|
199
|
+
const result = await scanEnvPaths({
|
|
200
|
+
roots: [tempDir],
|
|
201
|
+
maxDepth: 3,
|
|
202
|
+
includeUserHomeCache: false,
|
|
203
|
+
});
|
|
204
|
+
expect(result.meta.foundVenvs).toBeGreaterThanOrEqual(2);
|
|
205
|
+
expect(typeof result.meta.foundBases).toBe("number");
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
describe("nested environment handling", () => {
|
|
209
|
+
it("detects venv and does not descend further", async () => {
|
|
210
|
+
// Create a venv with a nested venv inside (unusual but possible)
|
|
211
|
+
const outerVenv = path.join(tempDir, "outer-venv");
|
|
212
|
+
await createMockVenv(outerVenv);
|
|
213
|
+
// Create another venv inside (should not be found because we stop at outer venv)
|
|
214
|
+
const innerVenv = path.join(outerVenv, "nested", "inner-venv");
|
|
215
|
+
await createMockVenv(innerVenv);
|
|
216
|
+
const result = await scanEnvPaths({
|
|
217
|
+
roots: [tempDir],
|
|
218
|
+
maxDepth: 10,
|
|
219
|
+
includeUserHomeCache: false,
|
|
220
|
+
});
|
|
221
|
+
const foundPaths = result.pythonPaths.filter(p => p.includes(tempDir));
|
|
222
|
+
const foundOuter = foundPaths.filter(p => p.includes("outer-venv") && !p.includes("inner-venv"));
|
|
223
|
+
const foundInner = foundPaths.filter(p => p.includes("inner-venv"));
|
|
224
|
+
// Should find outer venv
|
|
225
|
+
expect(foundOuter.length).toBe(1);
|
|
226
|
+
// Should NOT find inner venv (scan stops at venv boundary)
|
|
227
|
+
expect(foundInner.length).toBe(0);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
describe("large directory trees", () => {
|
|
231
|
+
it("handles directory with many subdirectories", async () => {
|
|
232
|
+
// Create many directories to test performance doesn't degrade badly
|
|
233
|
+
for (let i = 0; i < 20; i++) {
|
|
234
|
+
await fs.mkdir(path.join(tempDir, `dir${i}`), { recursive: true });
|
|
235
|
+
}
|
|
236
|
+
await createMockVenv(path.join(tempDir, "dir10", ".venv"));
|
|
237
|
+
const start = Date.now();
|
|
238
|
+
const result = await scanEnvPaths({
|
|
239
|
+
roots: [tempDir],
|
|
240
|
+
maxDepth: 3,
|
|
241
|
+
includeUserHomeCache: false,
|
|
242
|
+
});
|
|
243
|
+
const elapsed = Date.now() - start;
|
|
244
|
+
expect(result.meta.foundVenvs).toBeGreaterThanOrEqual(1);
|
|
245
|
+
// Should complete in reasonable time (less than 5 seconds)
|
|
246
|
+
expect(elapsed).toBeLessThan(5000);
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
//# sourceMappingURL=scanEnvPaths.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanEnvPaths.test.js","sourceRoot":"","sources":["../scanEnvPaths.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { RunLogEventV1 } from "./runLog.js";
|
|
2
|
+
export type TaskSignature = {
|
|
3
|
+
sigId: string;
|
|
4
|
+
name: string;
|
|
5
|
+
command: string;
|
|
6
|
+
requirementsKey: string;
|
|
7
|
+
};
|
|
8
|
+
export type TaskCluster = {
|
|
9
|
+
sig: TaskSignature;
|
|
10
|
+
runs: number;
|
|
11
|
+
ok: number;
|
|
12
|
+
fail: number;
|
|
13
|
+
successRate: number;
|
|
14
|
+
lastAt: string;
|
|
15
|
+
dominantFailure?: string;
|
|
16
|
+
failureCounts: Record<string, number>;
|
|
17
|
+
envCounts: Record<string, number>;
|
|
18
|
+
envFailCounts: Record<string, number>;
|
|
19
|
+
envOkCounts: Record<string, number>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Extract a stable signature from a run event.
|
|
23
|
+
* Runs with the same signature are clustered together.
|
|
24
|
+
*/
|
|
25
|
+
export declare function signatureForRun(run: RunLogEventV1): TaskSignature;
|
|
26
|
+
/**
|
|
27
|
+
* Cluster runs by task signature.
|
|
28
|
+
* Returns clusters sorted by run count (descending).
|
|
29
|
+
*/
|
|
30
|
+
export declare function clusterRuns(runs: RunLogEventV1[]): TaskCluster[];
|
|
31
|
+
/**
|
|
32
|
+
* Determine if a task cluster is flaky.
|
|
33
|
+
* Flaky = both succeeds and fails, with success rate not extreme.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isFlaky(cluster: TaskCluster): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Determine if a task cluster is env-dependent flaky.
|
|
38
|
+
* This means it succeeds on some envs and fails on others.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isEnvDependentFlaky(cluster: TaskCluster): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Get the envs where this task fails most.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getFailingEnvs(cluster: TaskCluster, limit?: number): Array<{
|
|
45
|
+
pythonPath: string;
|
|
46
|
+
failCount: number;
|
|
47
|
+
totalCount: number;
|
|
48
|
+
failRate: number;
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Get summary statistics for a set of clusters.
|
|
52
|
+
*/
|
|
53
|
+
export declare function summarizeClusters(clusters: TaskCluster[]): {
|
|
54
|
+
totalTasks: number;
|
|
55
|
+
totalRuns: number;
|
|
56
|
+
totalOk: number;
|
|
57
|
+
totalFail: number;
|
|
58
|
+
overallSuccessRate: number;
|
|
59
|
+
flakyCount: number;
|
|
60
|
+
envDependentFlakyCount: number;
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=taskCluster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskCluster.d.ts","sourceRoot":"","sources":["../taskCluster.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,aAAa,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IAEf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEtC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC,CAAC;AA6BF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,aAAa,CAMjE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,WAAW,EAAE,CAuDhE;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAKrD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAejE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,WAAW,EACpB,KAAK,SAAI,GACR,KAAK,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAUxF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB,EAAE,MAAM,CAAC;CAChC,CAwBA"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// taskCluster.ts
|
|
2
|
+
//
|
|
3
|
+
// Cluster task runs by signature for aggregated visualization.
|
|
4
|
+
// Instead of 500 task nodes, you get one node per task signature, with:
|
|
5
|
+
// - run count
|
|
6
|
+
// - success rate
|
|
7
|
+
// - last run timestamp
|
|
8
|
+
// - dominant failure code
|
|
9
|
+
// - top envs it routes to
|
|
10
|
+
//
|
|
11
|
+
// Also provides flake detection: a task is flaky if it fails on some envs
|
|
12
|
+
// but succeeds on others (or alternates over time).
|
|
13
|
+
import { createHash } from "node:crypto";
|
|
14
|
+
function sha16(s) {
|
|
15
|
+
return createHash("sha256").update(s).digest("hex").slice(0, 16);
|
|
16
|
+
}
|
|
17
|
+
function normCmd(cmd) {
|
|
18
|
+
return cmd.trim().replace(/\s+/g, " ").toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
function normReq(req) {
|
|
21
|
+
if (!req)
|
|
22
|
+
return "";
|
|
23
|
+
const pkgs = (req.packages ?? [])
|
|
24
|
+
.map((p) => p.toLowerCase())
|
|
25
|
+
.sort()
|
|
26
|
+
.join(",");
|
|
27
|
+
const feats = (req.features ?? [])
|
|
28
|
+
.map((f) => f.toLowerCase())
|
|
29
|
+
.sort()
|
|
30
|
+
.join(",");
|
|
31
|
+
const tags = (req.tags ?? [])
|
|
32
|
+
.map((t) => t.toLowerCase())
|
|
33
|
+
.sort()
|
|
34
|
+
.join(",");
|
|
35
|
+
const py = (req.python ?? "").toLowerCase();
|
|
36
|
+
const x64 = req.requireX64 ? "x64" : "";
|
|
37
|
+
return `py=${py}|pkgs=${pkgs}|feat=${feats}|tags=${tags}|${x64}`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Extract a stable signature from a run event.
|
|
41
|
+
* Runs with the same signature are clustered together.
|
|
42
|
+
*/
|
|
43
|
+
export function signatureForRun(run) {
|
|
44
|
+
const command = normCmd(run.task.command);
|
|
45
|
+
const requirementsKey = normReq(run.task.requirements);
|
|
46
|
+
const base = `${run.task.name}|${command}|${requirementsKey}`;
|
|
47
|
+
const sigId = `task_${sha16(base)}`;
|
|
48
|
+
return { sigId, name: run.task.name, command, requirementsKey };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Cluster runs by task signature.
|
|
52
|
+
* Returns clusters sorted by run count (descending).
|
|
53
|
+
*/
|
|
54
|
+
export function clusterRuns(runs) {
|
|
55
|
+
const map = new Map();
|
|
56
|
+
for (const r of runs) {
|
|
57
|
+
const sig = signatureForRun(r);
|
|
58
|
+
const key = sig.sigId;
|
|
59
|
+
let c = map.get(key);
|
|
60
|
+
if (!c) {
|
|
61
|
+
c = {
|
|
62
|
+
sig,
|
|
63
|
+
runs: 0,
|
|
64
|
+
ok: 0,
|
|
65
|
+
fail: 0,
|
|
66
|
+
successRate: 0,
|
|
67
|
+
lastAt: r.at,
|
|
68
|
+
failureCounts: {},
|
|
69
|
+
envCounts: {},
|
|
70
|
+
envFailCounts: {},
|
|
71
|
+
envOkCounts: {},
|
|
72
|
+
};
|
|
73
|
+
map.set(key, c);
|
|
74
|
+
}
|
|
75
|
+
c.runs += 1;
|
|
76
|
+
if (r.outcome.ok)
|
|
77
|
+
c.ok += 1;
|
|
78
|
+
else
|
|
79
|
+
c.fail += 1;
|
|
80
|
+
if (r.at > c.lastAt)
|
|
81
|
+
c.lastAt = r.at;
|
|
82
|
+
const py = r.selected.pythonPath;
|
|
83
|
+
c.envCounts[py] = (c.envCounts[py] ?? 0) + 1;
|
|
84
|
+
if (r.outcome.ok) {
|
|
85
|
+
c.envOkCounts[py] = (c.envOkCounts[py] ?? 0) + 1;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const code = r.doctor?.dominantIssue ?? r.outcome.errorClass ?? "RUN_FAILED";
|
|
89
|
+
c.failureCounts[code] = (c.failureCounts[code] ?? 0) + 1;
|
|
90
|
+
c.envFailCounts[py] = (c.envFailCounts[py] ?? 0) + 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Compute derived fields
|
|
94
|
+
for (const c of map.values()) {
|
|
95
|
+
c.successRate = c.runs ? c.ok / c.runs : 0;
|
|
96
|
+
// Find dominant failure code
|
|
97
|
+
let best = null;
|
|
98
|
+
for (const [code, count] of Object.entries(c.failureCounts)) {
|
|
99
|
+
if (!best || count > best.count)
|
|
100
|
+
best = { code, count };
|
|
101
|
+
}
|
|
102
|
+
if (best)
|
|
103
|
+
c.dominantFailure = best.code;
|
|
104
|
+
}
|
|
105
|
+
return [...map.values()].sort((a, b) => b.runs - a.runs);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Determine if a task cluster is flaky.
|
|
109
|
+
* Flaky = both succeeds and fails, with success rate not extreme.
|
|
110
|
+
*/
|
|
111
|
+
export function isFlaky(cluster) {
|
|
112
|
+
// Needs both successes and failures
|
|
113
|
+
if (cluster.ok === 0 || cluster.fail === 0)
|
|
114
|
+
return false;
|
|
115
|
+
// Success rate between 20% and 95% indicates inconsistent behavior
|
|
116
|
+
return cluster.successRate > 0.2 && cluster.successRate < 0.95;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Determine if a task cluster is env-dependent flaky.
|
|
120
|
+
* This means it succeeds on some envs and fails on others.
|
|
121
|
+
*/
|
|
122
|
+
export function isEnvDependentFlaky(cluster) {
|
|
123
|
+
const envs = Object.keys(cluster.envCounts);
|
|
124
|
+
if (envs.length < 2)
|
|
125
|
+
return false;
|
|
126
|
+
let hasSuccessEnv = false;
|
|
127
|
+
let hasFailEnv = false;
|
|
128
|
+
for (const py of envs) {
|
|
129
|
+
const ok = cluster.envOkCounts[py] ?? 0;
|
|
130
|
+
const fail = cluster.envFailCounts[py] ?? 0;
|
|
131
|
+
if (ok > 0 && fail === 0)
|
|
132
|
+
hasSuccessEnv = true;
|
|
133
|
+
if (fail > 0 && ok === 0)
|
|
134
|
+
hasFailEnv = true;
|
|
135
|
+
}
|
|
136
|
+
return hasSuccessEnv && hasFailEnv;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get the envs where this task fails most.
|
|
140
|
+
*/
|
|
141
|
+
export function getFailingEnvs(cluster, limit = 3) {
|
|
142
|
+
return Object.entries(cluster.envFailCounts)
|
|
143
|
+
.map(([py, failCount]) => ({
|
|
144
|
+
pythonPath: py,
|
|
145
|
+
failCount,
|
|
146
|
+
totalCount: cluster.envCounts[py] ?? failCount,
|
|
147
|
+
failRate: failCount / (cluster.envCounts[py] ?? failCount),
|
|
148
|
+
}))
|
|
149
|
+
.sort((a, b) => b.failCount - a.failCount)
|
|
150
|
+
.slice(0, limit);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get summary statistics for a set of clusters.
|
|
154
|
+
*/
|
|
155
|
+
export function summarizeClusters(clusters) {
|
|
156
|
+
let totalRuns = 0;
|
|
157
|
+
let totalOk = 0;
|
|
158
|
+
let totalFail = 0;
|
|
159
|
+
let flakyCount = 0;
|
|
160
|
+
let envDependentFlakyCount = 0;
|
|
161
|
+
for (const c of clusters) {
|
|
162
|
+
totalRuns += c.runs;
|
|
163
|
+
totalOk += c.ok;
|
|
164
|
+
totalFail += c.fail;
|
|
165
|
+
if (isFlaky(c))
|
|
166
|
+
flakyCount++;
|
|
167
|
+
if (isEnvDependentFlaky(c))
|
|
168
|
+
envDependentFlakyCount++;
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
totalTasks: clusters.length,
|
|
172
|
+
totalRuns,
|
|
173
|
+
totalOk,
|
|
174
|
+
totalFail,
|
|
175
|
+
overallSuccessRate: totalRuns ? totalOk / totalRuns : 0,
|
|
176
|
+
flakyCount,
|
|
177
|
+
envDependentFlakyCount,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=taskCluster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskCluster.js","sourceRoot":"","sources":["../taskCluster.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskCluster.test.d.ts","sourceRoot":"","sources":["../taskCluster.test.ts"],"names":[],"mappings":""}
|