test-fns 1.15.2 → 1.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/domain.operations/genTempDir/genEphemeralTempDir.js +2 -2
- package/dist/domain.operations/genTempDir/genEphemeralTempDir.js.map +1 -1
- package/dist/infra/isomorph.fs/cloneFixture.js +2 -4
- package/dist/infra/isomorph.fs/cloneFixture.js.map +1 -1
- package/dist/infra/isomorph.fs/createSymlinks.js +1 -3
- package/dist/infra/isomorph.fs/createSymlinks.js.map +1 -1
- package/dist/infra/isomorph.fs/findsertFile.d.ts +10 -0
- package/dist/infra/isomorph.fs/findsertFile.js +59 -0
- package/dist/infra/isomorph.fs/findsertFile.js.map +1 -0
- package/dist/infra/isomorph.fs/findsertSymlink.d.ts +10 -0
- package/dist/infra/isomorph.fs/findsertSymlink.js +83 -0
- package/dist/infra/isomorph.fs/findsertSymlink.js.map +1 -0
- package/dist/infra/isomorph.fs/genIsolatedTempInfra.js +19 -66
- package/dist/infra/isomorph.fs/genIsolatedTempInfra.js.map +1 -1
- package/dist/infra/isomorph.fs/initGitRepo.js +3 -3
- package/dist/infra/isomorph.fs/initGitRepo.js.map +1 -1
- package/package.json +3 -3
|
@@ -55,13 +55,13 @@ const genEphemeralTempDir = (input) => {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
// clone fixture if requested
|
|
58
|
-
if (input
|
|
58
|
+
if (input.clone) {
|
|
59
59
|
// resolve clone path relative to cwd
|
|
60
60
|
const clonePath = path.resolve(process.cwd(), input.clone);
|
|
61
61
|
(0, cloneFixture_1.cloneFixture)({ from: clonePath, to: tempDir });
|
|
62
62
|
}
|
|
63
63
|
// create symlinks if requested (after clone, so symlinks can augment cloned content)
|
|
64
|
-
if (input
|
|
64
|
+
if (input.symlink && input.symlink.length > 0) {
|
|
65
65
|
(0, createSymlinks_1.createSymlinks)({
|
|
66
66
|
symlinks: input.symlink,
|
|
67
67
|
tempDir,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genEphemeralTempDir.js","sourceRoot":"","sources":["../../../src/domain.operations/genTempDir/genEphemeralTempDir.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,gDAAkC;AAClC,uEAAoE;AACpE,+EAA4E;AAC5E,2EAAwE;AACxE,qEAAkE;AAClE,iEAA+E;AAC/E,6DAA0D;AAE1D;;;;;GAKG;AACI,MAAM,mBAAmB,GAAG,CAAC,KAOnC,EAAU,EAAE;IACX,gCAAgC;IAChC,MAAM,OAAO,GAAG,IAAA,uCAAkB,EAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAEzD,6CAA6C;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACjE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,sBAAsB;IACtB,MAAM,UAAU,GAAG,IAAA,2CAAoB,EAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEnD,mCAAmC;IACnC,IAAI,UAAU,EAAE,CAAC;QACf,IAAA,yBAAW,EAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAE9B,6CAA6C;QAC7C,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAA,mCAAgB,EAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,IAAI,KAAK,
|
|
1
|
+
{"version":3,"file":"genEphemeralTempDir.js","sourceRoot":"","sources":["../../../src/domain.operations/genTempDir/genEphemeralTempDir.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,gDAAkC;AAClC,uEAAoE;AACpE,+EAA4E;AAC5E,2EAAwE;AACxE,qEAAkE;AAClE,iEAA+E;AAC/E,6DAA0D;AAE1D;;;;;GAKG;AACI,MAAM,mBAAmB,GAAG,CAAC,KAOnC,EAAU,EAAE;IACX,gCAAgC;IAChC,MAAM,OAAO,GAAG,IAAA,uCAAkB,EAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAEzD,6CAA6C;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACjE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,sBAAsB;IACtB,MAAM,UAAU,GAAG,IAAA,2CAAoB,EAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEnD,mCAAmC;IACnC,IAAI,UAAU,EAAE,CAAC;QACf,IAAA,yBAAW,EAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAE9B,6CAA6C;QAC7C,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAA,mCAAgB,EAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,qCAAqC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3D,IAAA,2BAAY,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,qFAAqF;IACrF,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,IAAA,+BAAc,EAAC;YACb,QAAQ,EAAE,KAAK,CAAC,OAAO;YACvB,OAAO;YACP,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC;IACL,CAAC;IAED,yFAAyF;IACzF,MAAM,UAAU,GAAG,CAAC,CAAC,CACnB,KAAK,CAAC,KAAK;QACX,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAC5C,CAAC;IACF,IAAI,UAAU,IAAI,UAAU,CAAC,OAAO,CAAC,OAAO,IAAI,UAAU,EAAE,CAAC;QAC3D,IAAA,mCAAgB,EAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAtDW,QAAA,mBAAmB,uBAsD9B"}
|
|
@@ -38,10 +38,8 @@ const cloneFixture = (input) => {
|
|
|
38
38
|
to: input.to,
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
fs.mkdirSync(input.to, { recursive: true });
|
|
44
|
-
}
|
|
41
|
+
// ensure destination exists
|
|
42
|
+
fs.mkdirSync(input.to, { recursive: true });
|
|
45
43
|
// copy recursively with symlinks preserved
|
|
46
44
|
fs.cpSync(input.from, input.to, {
|
|
47
45
|
recursive: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloneFixture.js","sourceRoot":"","sources":["../../../src/infra/isomorph.fs/cloneFixture.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAiD;AAEjD,4CAA8B;AAE9B;;;GAGG;AACI,MAAM,YAAY,GAAG,CAAC,KAAmC,EAAQ,EAAE;IACxE,yBAAyB;IACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,gCAAe,CAAC,2BAA2B,KAAK,CAAC,IAAI,EAAE,EAAE;YACjE,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,EAAE,EAAE,KAAK,CAAC,EAAE;SACb,CAAC,CAAC;IACL,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"cloneFixture.js","sourceRoot":"","sources":["../../../src/infra/isomorph.fs/cloneFixture.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAiD;AAEjD,4CAA8B;AAE9B;;;GAGG;AACI,MAAM,YAAY,GAAG,CAAC,KAAmC,EAAQ,EAAE;IACxE,yBAAyB;IACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,gCAAe,CAAC,2BAA2B,KAAK,CAAC,IAAI,EAAE,EAAE;YACjE,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,EAAE,EAAE,KAAK,CAAC,EAAE;SACb,CAAC,CAAC;IACL,CAAC;IAED,4BAA4B;IAC5B,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5C,2CAA2C;IAC3C,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;QAC9B,SAAS,EAAE,IAAI;QACf,gBAAgB,EAAE,IAAI;KACvB,CAAC,CAAC;AACL,CAAC,CAAC;AAjBW,QAAA,YAAY,gBAiBvB"}
|
|
@@ -65,9 +65,7 @@ const createSymlinks = (input) => {
|
|
|
65
65
|
const targetPath = path.join(input.gitRoot, symlink.to);
|
|
66
66
|
// ensure parent directories exist
|
|
67
67
|
const parentDir = path.dirname(symlinkPath);
|
|
68
|
-
|
|
69
|
-
fs.mkdirSync(parentDir, { recursive: true });
|
|
70
|
-
}
|
|
68
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
71
69
|
// create symlink
|
|
72
70
|
fs.symlinkSync(targetPath, symlinkPath);
|
|
73
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSymlinks.js","sourceRoot":"","sources":["../../../src/infra/isomorph.fs/createSymlinks.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAiD;AAEjD,4CAA8B;AAC9B,gDAAkC;AAElC;;;;;;GAMG;AACI,MAAM,cAAc,GAAG,CAAC,KAI9B,EAAQ,EAAE;IACT,yEAAyE;IACzE,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,gCAAe,CAAC,6BAA6B,UAAU,EAAE,EAAE;gBACnE,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,UAAU;aACX,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACzD,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,gCAAe,CACvB,6CAA6C,OAAO,CAAC,EAAE,EAAE,EACzD;gBACE,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,WAAW;aACZ,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QAExD,kCAAkC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC5C,
|
|
1
|
+
{"version":3,"file":"createSymlinks.js","sourceRoot":"","sources":["../../../src/infra/isomorph.fs/createSymlinks.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAiD;AAEjD,4CAA8B;AAC9B,gDAAkC;AAElC;;;;;;GAMG;AACI,MAAM,cAAc,GAAG,CAAC,KAI9B,EAAQ,EAAE;IACT,yEAAyE;IACzE,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,gCAAe,CAAC,6BAA6B,UAAU,EAAE,EAAE;gBACnE,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,UAAU;aACX,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACzD,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,gCAAe,CACvB,6CAA6C,OAAO,CAAC,EAAE,EAAE,EACzD;gBACE,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,WAAW;aACZ,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QAExD,kCAAkC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC5C,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7C,iBAAiB;QACjB,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC,CAAC;AA9CW,QAAA,cAAc,kBA8CzB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .what = writes a file if absent, verifies content if exists
|
|
3
|
+
* .why = idempotent file creation safe for parallel workers
|
|
4
|
+
*
|
|
5
|
+
* @throws UnexpectedCodePathError if file exists with different content
|
|
6
|
+
*/
|
|
7
|
+
export declare const findsertFile: (input: {
|
|
8
|
+
path: string;
|
|
9
|
+
content: string;
|
|
10
|
+
}) => void;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.findsertFile = void 0;
|
|
27
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
28
|
+
const fs = __importStar(require("node:fs"));
|
|
29
|
+
/**
|
|
30
|
+
* .what = writes a file if absent, verifies content if exists
|
|
31
|
+
* .why = idempotent file creation safe for parallel workers
|
|
32
|
+
*
|
|
33
|
+
* @throws UnexpectedCodePathError if file exists with different content
|
|
34
|
+
*/
|
|
35
|
+
const findsertFile = (input) => {
|
|
36
|
+
try {
|
|
37
|
+
fs.writeFileSync(input.path, input.content, { flag: 'wx' });
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
// check for EEXIST via code or message
|
|
41
|
+
const code = error.code;
|
|
42
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
43
|
+
const isEexist = code === 'EEXIST' || message.includes('EEXIST');
|
|
44
|
+
if (!isEexist)
|
|
45
|
+
throw error;
|
|
46
|
+
// file exists — verify content matches
|
|
47
|
+
const contentFound = fs.readFileSync(input.path, 'utf-8');
|
|
48
|
+
if (contentFound === input.content) {
|
|
49
|
+
return; // correct content — idempotent success
|
|
50
|
+
}
|
|
51
|
+
throw new helpful_errors_1.UnexpectedCodePathError('file exists with unexpected content', {
|
|
52
|
+
path: input.path,
|
|
53
|
+
contentExpected: input.content,
|
|
54
|
+
contentFound,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
exports.findsertFile = findsertFile;
|
|
59
|
+
//# sourceMappingURL=findsertFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findsertFile.js","sourceRoot":"","sources":["../../../src/infra/isomorph.fs/findsertFile.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAyD;AAEzD,4CAA8B;AAE9B;;;;;GAKG;AACI,MAAM,YAAY,GAAG,CAAC,KAG5B,EAAQ,EAAE;IACT,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,uCAAuC;QACvC,MAAM,IAAI,GAAI,KAA2B,CAAC,IAAI,CAAC;QAC/C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACjE,IAAI,CAAC,QAAQ;YAAE,MAAM,KAAK,CAAC;QAE3B,uCAAuC;QACvC,MAAM,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1D,IAAI,YAAY,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,OAAO,CAAC,uCAAuC;QACjD,CAAC;QAED,MAAM,IAAI,wCAAuB,CAAC,qCAAqC,EAAE;YACvE,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,eAAe,EAAE,KAAK,CAAC,OAAO;YAC9B,YAAY;SACb,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;AAzBW,QAAA,YAAY,gBAyBvB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .what = creates a symlink if absent, no-op if correct symlink exists
|
|
3
|
+
* .why = idempotent symlink creation safe for parallel workers
|
|
4
|
+
*
|
|
5
|
+
* @throws UnexpectedCodePathError if path exists but is not the expected symlink
|
|
6
|
+
*/
|
|
7
|
+
export declare const findsertSymlink: (input: {
|
|
8
|
+
target: string;
|
|
9
|
+
path: string;
|
|
10
|
+
}) => void;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.findsertSymlink = void 0;
|
|
27
|
+
const helpful_errors_1 = require("helpful-errors");
|
|
28
|
+
const fs = __importStar(require("node:fs"));
|
|
29
|
+
/**
|
|
30
|
+
* .what = creates a symlink if absent, no-op if correct symlink exists
|
|
31
|
+
* .why = idempotent symlink creation safe for parallel workers
|
|
32
|
+
*
|
|
33
|
+
* @throws UnexpectedCodePathError if path exists but is not the expected symlink
|
|
34
|
+
*/
|
|
35
|
+
const findsertSymlink = (input) => {
|
|
36
|
+
// check if correct symlink already exists
|
|
37
|
+
const stat = (() => {
|
|
38
|
+
try {
|
|
39
|
+
return fs.lstatSync(input.path);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
})();
|
|
45
|
+
if (stat?.isSymbolicLink()) {
|
|
46
|
+
const currentTarget = fs.readlinkSync(input.path);
|
|
47
|
+
if (currentTarget === input.target) {
|
|
48
|
+
return; // correct symlink exists
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// remove stale symlink, directory, or file
|
|
52
|
+
if (stat) {
|
|
53
|
+
fs.rmSync(input.path, { recursive: true, force: true });
|
|
54
|
+
}
|
|
55
|
+
// create symlink
|
|
56
|
+
try {
|
|
57
|
+
fs.symlinkSync(input.target, input.path);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
// handle race: another worker created symlink between our check and create
|
|
61
|
+
if (!(error instanceof Error))
|
|
62
|
+
throw error;
|
|
63
|
+
const isEexist = error.code === 'EEXIST' ||
|
|
64
|
+
error.message.includes('EEXIST');
|
|
65
|
+
if (!isEexist)
|
|
66
|
+
throw error;
|
|
67
|
+
// another worker created symlink — verify it's correct
|
|
68
|
+
const raceStat = fs.lstatSync(input.path);
|
|
69
|
+
if (raceStat.isSymbolicLink()) {
|
|
70
|
+
const currentTarget = fs.readlinkSync(input.path);
|
|
71
|
+
if (currentTarget === input.target) {
|
|
72
|
+
return; // correct symlink created by another worker
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
throw new helpful_errors_1.UnexpectedCodePathError('symlink exists but points to unexpected target', {
|
|
76
|
+
target: input.target,
|
|
77
|
+
path: input.path,
|
|
78
|
+
isSymlink: raceStat.isSymbolicLink(),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
exports.findsertSymlink = findsertSymlink;
|
|
83
|
+
//# sourceMappingURL=findsertSymlink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findsertSymlink.js","sourceRoot":"","sources":["../../../src/infra/isomorph.fs/findsertSymlink.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAyD;AAEzD,4CAA8B;AAE9B;;;;;GAKG;AACI,MAAM,eAAe,GAAG,CAAC,KAG/B,EAAQ,EAAE;IACT,0CAA0C;IAC1C,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE;QACjB,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAEL,IAAI,IAAI,EAAE,cAAc,EAAE,EAAE,CAAC;QAC3B,MAAM,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,aAAa,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;YACnC,OAAO,CAAC,yBAAyB;QACnC,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,IAAI,IAAI,EAAE,CAAC;QACT,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,iBAAiB;IACjB,IAAI,CAAC;QACH,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,2EAA2E;QAC3E,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;YAAE,MAAM,KAAK,CAAC;QAC3C,MAAM,QAAQ,GACX,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAClD,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ;YAAE,MAAM,KAAK,CAAC;QAE3B,uDAAuD;QACvD,MAAM,QAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC;YAC9B,MAAM,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClD,IAAI,aAAa,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;gBACnC,OAAO,CAAC,4CAA4C;YACtD,CAAC;QACH,CAAC;QAED,MAAM,IAAI,wCAAuB,CAC/B,gDAAgD,EAChD;YACE,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,SAAS,EAAE,QAAQ,CAAC,cAAc,EAAE;SACrC,CACF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAtDW,QAAA,eAAe,mBAsD1B"}
|
|
@@ -28,6 +28,8 @@ const helpful_errors_1 = require("helpful-errors");
|
|
|
28
28
|
const fs = __importStar(require("node:fs"));
|
|
29
29
|
const path = __importStar(require("node:path"));
|
|
30
30
|
const computeIsolatedTempBasePath_1 = require("./computeIsolatedTempBasePath");
|
|
31
|
+
const findsertFile_1 = require("./findsertFile");
|
|
32
|
+
const findsertSymlink_1 = require("./findsertSymlink");
|
|
31
33
|
const TEMP_README_CONTENT = `# genTempDir.symlink
|
|
32
34
|
|
|
33
35
|
this directory is a symlink to the physical temp directory at \`/tmp/test-fns/{repo}/.temp/\`.
|
|
@@ -66,73 +68,24 @@ const genIsolatedTempInfra = (input) => {
|
|
|
66
68
|
const pathGitRootTemp = path.join(input.gitRoot, '.temp');
|
|
67
69
|
const pathSymlink = path.join(pathGitRootTemp, 'genTempDir.symlink');
|
|
68
70
|
// ensure @gitroot/.temp/ dir exists
|
|
69
|
-
|
|
70
|
-
fs.mkdirSync(pathGitRootTemp, { recursive: true });
|
|
71
|
-
}
|
|
71
|
+
fs.mkdirSync(pathGitRootTemp, { recursive: true });
|
|
72
72
|
// ensure physical dir exists: /tmp/test-fns/{repo-dirname}/.temp/
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
: null;
|
|
90
|
-
if (symlinkStat) {
|
|
91
|
-
// check if it's a symlink
|
|
92
|
-
if (symlinkStat.isSymbolicLink()) {
|
|
93
|
-
// verify target matches, update if stale
|
|
94
|
-
const currentTarget = fs.readlinkSync(pathSymlink);
|
|
95
|
-
if (currentTarget !== pathPhysical) {
|
|
96
|
-
fs.unlinkSync(pathSymlink);
|
|
97
|
-
fs.symlinkSync(pathPhysical, pathSymlink);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
else if (symlinkStat.isDirectory()) {
|
|
101
|
-
// if directory found, remove it (contents ephemeral) and create symlink
|
|
102
|
-
fs.rmSync(pathSymlink, { recursive: true, force: true });
|
|
103
|
-
fs.symlinkSync(pathPhysical, pathSymlink);
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
// if file found, remove it and create symlink
|
|
107
|
-
fs.unlinkSync(pathSymlink);
|
|
108
|
-
fs.symlinkSync(pathPhysical, pathSymlink);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
// symlink absent, create it idempotently (race-safe for parallel workers)
|
|
113
|
-
try {
|
|
114
|
-
fs.symlinkSync(pathPhysical, pathSymlink);
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
// handle race: another worker created symlink between check and create
|
|
118
|
-
if (!(error instanceof Error))
|
|
119
|
-
throw error;
|
|
120
|
-
if (!error.message.includes('EEXIST'))
|
|
121
|
-
throw error;
|
|
122
|
-
// another worker created the symlink — verify it points to correct target
|
|
123
|
-
const stat = fs.lstatSync(pathSymlink);
|
|
124
|
-
if (stat.isSymbolicLink()) {
|
|
125
|
-
const currentTarget = fs.readlinkSync(pathSymlink);
|
|
126
|
-
if (currentTarget === pathPhysical) {
|
|
127
|
-
// correct symlink created by another worker — idempotent success
|
|
128
|
-
return { pathPhysical, pathSymlink };
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
// edge case: another worker created wrong symlink/file/dir
|
|
132
|
-
// this should be rare — throw to surface the issue rather than silently fix
|
|
133
|
-
throw new helpful_errors_1.UnexpectedCodePathError('symlink exists but points to unexpected target', { pathPhysical, pathSymlink, stat: stat.isSymbolicLink() });
|
|
134
|
-
}
|
|
135
|
-
}
|
|
73
|
+
fs.mkdirSync(pathPhysical, { recursive: true });
|
|
74
|
+
// findsert readme.md to physical dir
|
|
75
|
+
(0, findsertFile_1.findsertFile)({
|
|
76
|
+
path: path.join(pathPhysical, 'readme.md'),
|
|
77
|
+
content: TEMP_README_CONTENT,
|
|
78
|
+
});
|
|
79
|
+
// findsert .gitignore to physical dir
|
|
80
|
+
(0, findsertFile_1.findsertFile)({
|
|
81
|
+
path: path.join(pathPhysical, '.gitignore'),
|
|
82
|
+
content: '*\n',
|
|
83
|
+
});
|
|
84
|
+
// findsert symlink at @gitroot/.temp/genTempDir.symlink
|
|
85
|
+
(0, findsertSymlink_1.findsertSymlink)({
|
|
86
|
+
target: pathPhysical,
|
|
87
|
+
path: pathSymlink,
|
|
88
|
+
});
|
|
136
89
|
return { pathPhysical, pathSymlink };
|
|
137
90
|
};
|
|
138
91
|
exports.genIsolatedTempInfra = genIsolatedTempInfra;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genIsolatedTempInfra.js","sourceRoot":"","sources":["../../../src/infra/isomorph.fs/genIsolatedTempInfra.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAyD;AAEzD,4CAA8B;AAC9B,gDAAkC;AAClC,+EAA4E;
|
|
1
|
+
{"version":3,"file":"genIsolatedTempInfra.js","sourceRoot":"","sources":["../../../src/infra/isomorph.fs/genIsolatedTempInfra.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAyD;AAEzD,4CAA8B;AAC9B,gDAAkC;AAClC,+EAA4E;AAC5E,iDAA8C;AAC9C,uDAAoD;AAEpD,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;CAmB3B,CAAC;AAEF;;;;;;;GAOG;AACI,MAAM,oBAAoB,GAAG,CAAC,KAEpC,EAAiD,EAAE;IAClD,yDAAyD;IACzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,wCAAuB,CAC/B,yDAAyD,EACzD,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAC3B,CAAC;IACJ,CAAC;IAED,gBAAgB;IAChB,MAAM,YAAY,GAAG,IAAA,yDAA2B,EAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,oBAAoB,CAAC,CAAC;IAErE,oCAAoC;IACpC,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEnD,kEAAkE;IAClE,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhD,qCAAqC;IACrC,IAAA,2BAAY,EAAC;QACX,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC;QAC1C,OAAO,EAAE,mBAAmB;KAC7B,CAAC,CAAC;IAEH,sCAAsC;IACtC,IAAA,2BAAY,EAAC;QACX,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC;QAC3C,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;IAEH,wDAAwD;IACxD,IAAA,iCAAe,EAAC;QACd,MAAM,EAAE,YAAY;QACpB,IAAI,EAAE,WAAW;KAClB,CAAC,CAAC;IAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;AACvC,CAAC,CAAC;AAzCW,QAAA,oBAAoB,wBAyC/B"}
|
|
@@ -14,13 +14,13 @@ const initGitRepo = (input) => {
|
|
|
14
14
|
const userName = input.user?.name ?? 'test-fns';
|
|
15
15
|
const userEmail = input.user?.email ?? 'test-fns@test.local';
|
|
16
16
|
// initialize git repo
|
|
17
|
-
(0, node_child_process_1.
|
|
17
|
+
(0, node_child_process_1.spawnSync)('git', ['init'], { cwd: input.dir, stdio: 'pipe' });
|
|
18
18
|
// configure repo-local user identity (ci-safe)
|
|
19
|
-
(0, node_child_process_1.
|
|
19
|
+
(0, node_child_process_1.spawnSync)('git', ['config', 'user.name', userName], {
|
|
20
20
|
cwd: input.dir,
|
|
21
21
|
stdio: 'pipe',
|
|
22
22
|
});
|
|
23
|
-
(0, node_child_process_1.
|
|
23
|
+
(0, node_child_process_1.spawnSync)('git', ['config', 'user.email', userEmail], {
|
|
24
24
|
cwd: input.dir,
|
|
25
25
|
stdio: 'pipe',
|
|
26
26
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initGitRepo.js","sourceRoot":"","sources":["../../../src/infra/isomorph.fs/initGitRepo.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"initGitRepo.js","sourceRoot":"","sources":["../../../src/infra/isomorph.fs/initGitRepo.ts"],"names":[],"mappings":";;;AAAA,2DAA+C;AAE/C;;;;;;;GAOG;AACI,MAAM,WAAW,GAAG,CAAC,KAM3B,EAAQ,EAAE;IACT,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,IAAI,UAAU,CAAC;IAChD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,qBAAqB,CAAC;IAE7D,sBAAsB;IACtB,IAAA,8BAAS,EAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAE9D,+CAA+C;IAC/C,IAAA,8BAAS,EAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE;QAClD,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,KAAK,EAAE,MAAM;KACd,CAAC,CAAC;IACH,IAAA,8BAAS,EAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE;QACpD,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,KAAK,EAAE,MAAM;KACd,CAAC,CAAC;AACL,CAAC,CAAC;AAtBW,QAAA,WAAW,eAsBtB"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "test-fns",
|
|
3
3
|
"author": "ehmpathy",
|
|
4
4
|
"description": "write usecase driven tests systematically for simpler, safer, and more readable code",
|
|
5
|
-
"version": "1.15.
|
|
5
|
+
"version": "1.15.3",
|
|
6
6
|
"repository": "ehmpathy/test-fns",
|
|
7
7
|
"homepage": "https://github.com/ehmpathy/test-fns",
|
|
8
8
|
"keywords": [
|
|
@@ -96,9 +96,9 @@
|
|
|
96
96
|
"jest": "30.2.0",
|
|
97
97
|
"rhachet": "1.35.3",
|
|
98
98
|
"rhachet-brains-anthropic": "0.3.3",
|
|
99
|
-
"rhachet-roles-bhrain": "0.12.
|
|
99
|
+
"rhachet-roles-bhrain": "0.12.4",
|
|
100
100
|
"rhachet-roles-bhuild": "0.10.0",
|
|
101
|
-
"rhachet-roles-ehmpathy": "1.26.
|
|
101
|
+
"rhachet-roles-ehmpathy": "1.26.3",
|
|
102
102
|
"tsc-alias": "1.8.10",
|
|
103
103
|
"tsx": "4.21.0",
|
|
104
104
|
"typescript": "5.4.5",
|