@testspectra/cli 1.0.22 → 1.0.23
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/dist/commands/init.js +57 -3
- package/package.json +1 -1
package/dist/commands/init.js
CHANGED
|
@@ -28,6 +28,54 @@ function parsePnpmWorkspaceGlobs(content) {
|
|
|
28
28
|
}
|
|
29
29
|
return globs;
|
|
30
30
|
}
|
|
31
|
+
function ensurePnpmWorkspaceIncludes(pnpmWorkspacePath, targetPath) {
|
|
32
|
+
const normalizedTarget = targetPath.replace(/\\/g, "/");
|
|
33
|
+
if (!fs.existsSync(pnpmWorkspacePath)) {
|
|
34
|
+
const newContent = `packages:\n - '${normalizedTarget}'\n`;
|
|
35
|
+
fs.writeFileSync(pnpmWorkspacePath, newContent, "utf-8");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const content = fs.readFileSync(pnpmWorkspacePath, "utf-8");
|
|
39
|
+
const currentGlobs = parsePnpmWorkspaceGlobs(content);
|
|
40
|
+
// Check if target is already covered by an existing glob or exact path
|
|
41
|
+
const isAlreadyCovered = currentGlobs.some((glob) => {
|
|
42
|
+
const normGlob = glob.replace(/\\/g, "/");
|
|
43
|
+
if (normGlob === normalizedTarget)
|
|
44
|
+
return true;
|
|
45
|
+
if (normGlob === `${normalizedTarget}/*` || normGlob === `${normalizedTarget}/**`)
|
|
46
|
+
return true;
|
|
47
|
+
if (normGlob.endsWith("/*")) {
|
|
48
|
+
const parent = normGlob.slice(0, -2);
|
|
49
|
+
if (normalizedTarget.startsWith(`${parent}/`) && normalizedTarget.split("/").length === parent.split("/").length + 1)
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if (normGlob.endsWith("/**")) {
|
|
53
|
+
const parent = normGlob.slice(0, -3);
|
|
54
|
+
if (normalizedTarget.startsWith(`${parent}/`))
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
});
|
|
59
|
+
if (!isAlreadyCovered) {
|
|
60
|
+
// Insert new package pattern right under packages:
|
|
61
|
+
const lines = content.split("\n");
|
|
62
|
+
let insertIndex = -1;
|
|
63
|
+
for (let i = 0; i < lines.length; i++) {
|
|
64
|
+
if (lines[i].trim().startsWith("packages:")) {
|
|
65
|
+
insertIndex = i + 1;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (insertIndex !== -1) {
|
|
70
|
+
lines.splice(insertIndex, 0, ` - '${normalizedTarget}'`);
|
|
71
|
+
fs.writeFileSync(pnpmWorkspacePath, lines.join("\n"), "utf-8");
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
const newContent = `packages:\n - '${normalizedTarget}'\n` + content;
|
|
75
|
+
fs.writeFileSync(pnpmWorkspacePath, newContent, "utf-8");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
31
79
|
function scanDirectoriesForProjects(cwd, patterns) {
|
|
32
80
|
const foundProjects = [];
|
|
33
81
|
const visited = new Set();
|
|
@@ -334,7 +382,13 @@ export async function initCommand(options = {}) {
|
|
|
334
382
|
fs.unlinkSync(localConfig);
|
|
335
383
|
featureE2eDirs.push(targetE2eDir);
|
|
336
384
|
}
|
|
337
|
-
// 5.
|
|
385
|
+
// 5. Ensure pnpm-workspace.yaml includes shared library and all feature E2E directories
|
|
386
|
+
const pnpmWorkspaceFilePath = path.join(cwd, "pnpm-workspace.yaml");
|
|
387
|
+
ensurePnpmWorkspaceIncludes(pnpmWorkspaceFilePath, sharedTestingRelPath);
|
|
388
|
+
for (const e2eDir of featureE2eDirs) {
|
|
389
|
+
ensurePnpmWorkspaceIncludes(pnpmWorkspaceFilePath, path.relative(cwd, e2eDir));
|
|
390
|
+
}
|
|
391
|
+
// 6. Update Root Solution tsconfig.json references
|
|
338
392
|
const rootTsConfigPath = path.join(cwd, "tsconfig.json");
|
|
339
393
|
const references = [];
|
|
340
394
|
for (const e2eDir of featureE2eDirs) {
|
|
@@ -359,12 +413,12 @@ export async function initCommand(options = {}) {
|
|
|
359
413
|
rootTsConfig = { files: [], references };
|
|
360
414
|
}
|
|
361
415
|
fs.writeFileSync(rootTsConfigPath, JSON.stringify(rootTsConfig, null, 2), "utf-8");
|
|
362
|
-
//
|
|
416
|
+
// 7. Generate Ambient Types for Shared + All E2E Feature Directories
|
|
363
417
|
TypeGenerator.writeDeclarationFiles(cwd);
|
|
364
418
|
for (const e2eDir of featureE2eDirs) {
|
|
365
419
|
TypeGenerator.writeDeclarationFiles(e2eDir);
|
|
366
420
|
}
|
|
367
|
-
//
|
|
421
|
+
// 8. Generate ARCHITECTURE.md in root documenting the exact generated layout
|
|
368
422
|
const archDocContent = `# TestSpectra Enterprise Monorepo Architecture
|
|
369
423
|
|
|
370
424
|
This workspace uses TestSpectra's **"Centralized Configuration, Distributed Implementation"** model for automated cross-platform testing.
|