@mcptoolshop/venvkit 0.2.0 → 0.2.1
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 +2 -2
- package/dist/mapRender.test.js +0 -101
- package/dist/mapRender.test.js.map +1 -1
- package/dist/runLog.test.js +0 -167
- package/dist/runLog.test.js.map +1 -1
- package/dist/taskCluster.test.js +0 -84
- package/dist/taskCluster.test.js.map +1 -1
- package/package.json +68 -58
- package/dist/integration.test.d.ts +0 -2
- package/dist/integration.test.d.ts.map +0 -1
- package/dist/integration.test.js +0 -245
- package/dist/integration.test.js.map +0 -1
- package/dist/map_cli.test.d.ts +0 -2
- package/dist/map_cli.test.d.ts.map +0 -1
- package/dist/map_cli.test.js +0 -276
- package/dist/map_cli.test.js.map +0 -1
- package/dist/scanEnvPaths.test.d.ts +0 -2
- package/dist/scanEnvPaths.test.d.ts.map +0 -1
- package/dist/scanEnvPaths.test.js +0 -250
- package/dist/scanEnvPaths.test.js.map +0 -1
package/dist/map_cli.test.js
DELETED
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
// map_cli.test.ts
|
|
2
|
-
// Unit tests for CLI argument parsing and command execution
|
|
3
|
-
import { describe, it, expect, vi, 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 main to test CLI behavior
|
|
8
|
-
// Note: We test parseArgs behavior through main() invocation
|
|
9
|
-
// since parseArgs is not exported directly
|
|
10
|
-
describe("map_cli", () => {
|
|
11
|
-
let tempDir;
|
|
12
|
-
let originalCwd;
|
|
13
|
-
let originalArgv;
|
|
14
|
-
let stderrOutput;
|
|
15
|
-
let stdoutOutput;
|
|
16
|
-
beforeEach(async () => {
|
|
17
|
-
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "venvkit-cli-test-"));
|
|
18
|
-
originalCwd = process.cwd();
|
|
19
|
-
originalArgv = process.argv;
|
|
20
|
-
stderrOutput = "";
|
|
21
|
-
stdoutOutput = "";
|
|
22
|
-
// Mock stderr/stdout
|
|
23
|
-
vi.spyOn(process.stderr, "write").mockImplementation((chunk) => {
|
|
24
|
-
stderrOutput += chunk;
|
|
25
|
-
return true;
|
|
26
|
-
});
|
|
27
|
-
vi.spyOn(process.stdout, "write").mockImplementation((chunk) => {
|
|
28
|
-
stdoutOutput += chunk;
|
|
29
|
-
return true;
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
afterEach(async () => {
|
|
33
|
-
vi.restoreAllMocks();
|
|
34
|
-
process.argv = originalArgv;
|
|
35
|
-
try {
|
|
36
|
-
process.chdir(originalCwd);
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
// Ignore if original dir doesn't exist
|
|
40
|
-
}
|
|
41
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
42
|
-
});
|
|
43
|
-
// Helper to create a mock venv for testing
|
|
44
|
-
async function createMockVenv(venvPath) {
|
|
45
|
-
await fs.mkdir(venvPath, { recursive: true });
|
|
46
|
-
await fs.writeFile(path.join(venvPath, "pyvenv.cfg"), "home = C:\\Python311\nversion = 3.11.5\n");
|
|
47
|
-
const binDir = os.platform() === "win32" ? "Scripts" : "bin";
|
|
48
|
-
const pyExe = os.platform() === "win32" ? "python.exe" : "python";
|
|
49
|
-
await fs.mkdir(path.join(venvPath, binDir), { recursive: true });
|
|
50
|
-
await fs.writeFile(path.join(venvPath, binDir, pyExe), "fake python");
|
|
51
|
-
return path.join(venvPath, binDir, pyExe);
|
|
52
|
-
}
|
|
53
|
-
describe("argument parsing", () => {
|
|
54
|
-
it("parses --root argument", async () => {
|
|
55
|
-
const { main } = await import("./map_cli.js");
|
|
56
|
-
// Create an empty project (will find no python envs)
|
|
57
|
-
const projectDir = path.join(tempDir, "project");
|
|
58
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
59
|
-
await main(["--root", projectDir, "--out", path.join(tempDir, "out")]);
|
|
60
|
-
expect(stderrOutput).toContain("Scanning for Python environments in:");
|
|
61
|
-
expect(stderrOutput).toContain(projectDir);
|
|
62
|
-
});
|
|
63
|
-
it("parses multiple --root arguments", async () => {
|
|
64
|
-
const { main } = await import("./map_cli.js");
|
|
65
|
-
const project1 = path.join(tempDir, "project1");
|
|
66
|
-
const project2 = path.join(tempDir, "project2");
|
|
67
|
-
await fs.mkdir(project1, { recursive: true });
|
|
68
|
-
await fs.mkdir(project2, { recursive: true });
|
|
69
|
-
await main(["--root", project1, "--root", project2, "--out", path.join(tempDir, "out")]);
|
|
70
|
-
expect(stderrOutput).toContain(project1);
|
|
71
|
-
expect(stderrOutput).toContain(project2);
|
|
72
|
-
});
|
|
73
|
-
it("parses -r short form for root", async () => {
|
|
74
|
-
const { main } = await import("./map_cli.js");
|
|
75
|
-
const projectDir = path.join(tempDir, "project");
|
|
76
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
77
|
-
await main(["-r", projectDir, "--out", path.join(tempDir, "out")]);
|
|
78
|
-
expect(stderrOutput).toContain(projectDir);
|
|
79
|
-
});
|
|
80
|
-
it("parses --maxDepth argument", async () => {
|
|
81
|
-
const { main } = await import("./map_cli.js");
|
|
82
|
-
const projectDir = path.join(tempDir, "project");
|
|
83
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
84
|
-
// Just verify it runs without error with maxDepth
|
|
85
|
-
await main(["--root", projectDir, "--maxDepth", "10", "--out", path.join(tempDir, "out")]);
|
|
86
|
-
expect(stderrOutput).toContain("Scanning");
|
|
87
|
-
});
|
|
88
|
-
it("parses --concurrency argument", async () => {
|
|
89
|
-
const { main } = await import("./map_cli.js");
|
|
90
|
-
const projectDir = path.join(tempDir, "project");
|
|
91
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
92
|
-
await main(["--root", projectDir, "--concurrency", "4", "--out", path.join(tempDir, "out")]);
|
|
93
|
-
// Should run without error
|
|
94
|
-
expect(stderrOutput).toContain("Scanning");
|
|
95
|
-
});
|
|
96
|
-
it("parses --no-tasks flag", async () => {
|
|
97
|
-
const { main } = await import("./map_cli.js");
|
|
98
|
-
const projectDir = path.join(tempDir, "project");
|
|
99
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
100
|
-
await main(["--root", projectDir, "--no-tasks", "--out", path.join(tempDir, "out")]);
|
|
101
|
-
expect(stderrOutput).toContain("Scanning");
|
|
102
|
-
});
|
|
103
|
-
it("uses current directory as default root", async () => {
|
|
104
|
-
const { main } = await import("./map_cli.js");
|
|
105
|
-
// Create temp directory and chdir to it
|
|
106
|
-
const projectDir = path.join(tempDir, "cwd-project");
|
|
107
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
108
|
-
process.chdir(projectDir);
|
|
109
|
-
await main(["--out", path.join(tempDir, "out")]);
|
|
110
|
-
expect(stderrOutput).toContain("Scanning for Python environments in:");
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
describe("output generation", () => {
|
|
114
|
-
it("creates output directory if missing", async () => {
|
|
115
|
-
const { main } = await import("./map_cli.js");
|
|
116
|
-
const projectDir = path.join(tempDir, "project");
|
|
117
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
118
|
-
const outDir = path.join(tempDir, "nested", "output", "dir");
|
|
119
|
-
await main(["--root", projectDir, "--out", outDir]);
|
|
120
|
-
// Directory should be created
|
|
121
|
-
const stats = await fs.stat(outDir);
|
|
122
|
-
expect(stats.isDirectory()).toBe(true);
|
|
123
|
-
});
|
|
124
|
-
it("writes venv-map.json when envs found", async () => {
|
|
125
|
-
const { main } = await import("./map_cli.js");
|
|
126
|
-
// Create mock venv
|
|
127
|
-
const projectDir = path.join(tempDir, "project");
|
|
128
|
-
await createMockVenv(path.join(projectDir, ".venv"));
|
|
129
|
-
// Mock doctorLite to avoid actual subprocess execution
|
|
130
|
-
vi.doMock("./doctorLite.js", () => ({
|
|
131
|
-
doctorLite: vi.fn().mockResolvedValue({
|
|
132
|
-
pythonPath: path.join(projectDir, ".venv", "Scripts", "python.exe"),
|
|
133
|
-
ranAt: new Date().toISOString(),
|
|
134
|
-
status: "good",
|
|
135
|
-
score: 100,
|
|
136
|
-
summary: "Healthy",
|
|
137
|
-
facts: {
|
|
138
|
-
version: "3.11.5",
|
|
139
|
-
version_info: [3, 11, 5],
|
|
140
|
-
executable: path.join(projectDir, ".venv", "Scripts", "python.exe"),
|
|
141
|
-
prefix: path.join(projectDir, ".venv"),
|
|
142
|
-
base_prefix: "C:\\Python311",
|
|
143
|
-
bits: 64,
|
|
144
|
-
machine: "AMD64",
|
|
145
|
-
os: "windows",
|
|
146
|
-
py_path: [],
|
|
147
|
-
enable_user_site: false,
|
|
148
|
-
user_site: "",
|
|
149
|
-
},
|
|
150
|
-
findings: [],
|
|
151
|
-
}),
|
|
152
|
-
}));
|
|
153
|
-
const outDir = path.join(tempDir, "output");
|
|
154
|
-
await fs.mkdir(outDir, { recursive: true });
|
|
155
|
-
// Note: This test may fail if no actual venvs are found due to mocking limitations
|
|
156
|
-
// The key assertion is that the function runs without throwing
|
|
157
|
-
try {
|
|
158
|
-
await main(["--root", projectDir, "--out", outDir]);
|
|
159
|
-
}
|
|
160
|
-
catch {
|
|
161
|
-
// May fail due to doctorLite trying to run actual subprocesses
|
|
162
|
-
}
|
|
163
|
-
expect(stderrOutput).toContain("Scanning");
|
|
164
|
-
});
|
|
165
|
-
it("writes venv-map.mmd mermaid file", async () => {
|
|
166
|
-
const { main } = await import("./map_cli.js");
|
|
167
|
-
const projectDir = path.join(tempDir, "project");
|
|
168
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
169
|
-
const outDir = path.join(tempDir, "output");
|
|
170
|
-
await main(["--root", projectDir, "--out", outDir]);
|
|
171
|
-
// Even with no envs, output files should be attempted
|
|
172
|
-
expect(stderrOutput).toContain("Scanning");
|
|
173
|
-
});
|
|
174
|
-
it("writes venv-map.html viewer", async () => {
|
|
175
|
-
const { main } = await import("./map_cli.js");
|
|
176
|
-
const projectDir = path.join(tempDir, "project");
|
|
177
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
178
|
-
const outDir = path.join(tempDir, "output");
|
|
179
|
-
await main(["--root", projectDir, "--out", outDir]);
|
|
180
|
-
expect(stderrOutput).toContain("Scanning");
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
describe("CLI behavior", () => {
|
|
184
|
-
it("reports no envs found gracefully", async () => {
|
|
185
|
-
const { main } = await import("./map_cli.js");
|
|
186
|
-
const emptyDir = path.join(tempDir, "empty");
|
|
187
|
-
await fs.mkdir(emptyDir, { recursive: true });
|
|
188
|
-
await main(["--root", emptyDir, "--out", path.join(tempDir, "out")]);
|
|
189
|
-
expect(stderrOutput).toContain("No Python environments found");
|
|
190
|
-
});
|
|
191
|
-
it("reports found environment count", async () => {
|
|
192
|
-
const { main } = await import("./map_cli.js");
|
|
193
|
-
// Create a project (may or may not find system pythons)
|
|
194
|
-
const projectDir = path.join(tempDir, "project");
|
|
195
|
-
await createMockVenv(path.join(projectDir, ".venv"));
|
|
196
|
-
await main(["--root", projectDir, "--out", path.join(tempDir, "out")]);
|
|
197
|
-
expect(stderrOutput).toContain("Found");
|
|
198
|
-
expect(stderrOutput).toContain("Python executables");
|
|
199
|
-
});
|
|
200
|
-
it("prints mermaid to stdout", async () => {
|
|
201
|
-
const { main } = await import("./map_cli.js");
|
|
202
|
-
const projectDir = path.join(tempDir, "project");
|
|
203
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
204
|
-
await main(["--root", projectDir, "--out", path.join(tempDir, "out")]);
|
|
205
|
-
// Even if no envs found, shouldn't throw
|
|
206
|
-
expect(stderrOutput).toContain("Scanning");
|
|
207
|
-
});
|
|
208
|
-
});
|
|
209
|
-
describe("run log integration", () => {
|
|
210
|
-
it("loads run log from default location", async () => {
|
|
211
|
-
const { main } = await import("./map_cli.js");
|
|
212
|
-
const projectDir = path.join(tempDir, "project");
|
|
213
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
214
|
-
// Create a run log file
|
|
215
|
-
const outDir = path.join(tempDir, "out");
|
|
216
|
-
await fs.mkdir(outDir, { recursive: true });
|
|
217
|
-
await fs.writeFile(path.join(outDir, "runs.jsonl"), JSON.stringify({
|
|
218
|
-
version: "1.0",
|
|
219
|
-
runId: "test-run-1",
|
|
220
|
-
at: new Date().toISOString(),
|
|
221
|
-
task: { name: "test", command: "pytest" },
|
|
222
|
-
selected: { pythonPath: "C:\\python.exe", status: "good" },
|
|
223
|
-
outcome: { ok: true, exitCode: 0, durationMs: 100 },
|
|
224
|
-
}) + "\n");
|
|
225
|
-
await main(["--root", projectDir, "--out", outDir]);
|
|
226
|
-
// Should mention task runs if found
|
|
227
|
-
expect(stderrOutput).toContain("Scanning");
|
|
228
|
-
});
|
|
229
|
-
it("loads run log from custom path", async () => {
|
|
230
|
-
const { main } = await import("./map_cli.js");
|
|
231
|
-
const projectDir = path.join(tempDir, "project");
|
|
232
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
233
|
-
const customLogPath = path.join(tempDir, "custom-runs.jsonl");
|
|
234
|
-
await fs.writeFile(customLogPath, "");
|
|
235
|
-
await main([
|
|
236
|
-
"--root", projectDir,
|
|
237
|
-
"--out", path.join(tempDir, "out"),
|
|
238
|
-
"--runlog", customLogPath,
|
|
239
|
-
]);
|
|
240
|
-
expect(stderrOutput).toContain("Scanning");
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
describe("error handling", () => {
|
|
244
|
-
it("handles invalid root directory gracefully", async () => {
|
|
245
|
-
const { main } = await import("./map_cli.js");
|
|
246
|
-
const nonexistentDir = path.join(tempDir, "nonexistent");
|
|
247
|
-
// Should not throw
|
|
248
|
-
await main(["--root", nonexistentDir, "--out", path.join(tempDir, "out")]);
|
|
249
|
-
expect(stderrOutput).toContain("Scanning");
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
describe("flags and options", () => {
|
|
253
|
-
it("parses --strict flag", async () => {
|
|
254
|
-
const { main } = await import("./map_cli.js");
|
|
255
|
-
const projectDir = path.join(tempDir, "project");
|
|
256
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
257
|
-
await main(["--root", projectDir, "--strict", "--out", path.join(tempDir, "out")]);
|
|
258
|
-
expect(stderrOutput).toContain("Scanning");
|
|
259
|
-
});
|
|
260
|
-
it("parses --httpsProbe flag", async () => {
|
|
261
|
-
const { main } = await import("./map_cli.js");
|
|
262
|
-
const projectDir = path.join(tempDir, "project");
|
|
263
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
264
|
-
await main(["--root", projectDir, "--httpsProbe", "--out", path.join(tempDir, "out")]);
|
|
265
|
-
expect(stderrOutput).toContain("Scanning");
|
|
266
|
-
});
|
|
267
|
-
it("parses --minScore filter", async () => {
|
|
268
|
-
const { main } = await import("./map_cli.js");
|
|
269
|
-
const projectDir = path.join(tempDir, "project");
|
|
270
|
-
await fs.mkdir(projectDir, { recursive: true });
|
|
271
|
-
await main(["--root", projectDir, "--minScore", "50", "--out", path.join(tempDir, "out")]);
|
|
272
|
-
expect(stderrOutput).toContain("Scanning");
|
|
273
|
-
});
|
|
274
|
-
});
|
|
275
|
-
});
|
|
276
|
-
//# sourceMappingURL=map_cli.test.js.map
|
package/dist/map_cli.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"map_cli.test.js","sourceRoot":"","sources":["../map_cli.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scanEnvPaths.test.d.ts","sourceRoot":"","sources":["../scanEnvPaths.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,250 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scanEnvPaths.test.js","sourceRoot":"","sources":["../scanEnvPaths.test.ts"],"names":[],"mappings":"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"}
|