@paraharness/git 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +68 -2
- package/dist/builders/create-git-candidate-comparison-tools.d.ts +13 -0
- package/dist/builders/create-git-candidate-comparison-tools.d.ts.map +1 -0
- package/dist/builders/create-git-candidate-comparison-tools.js +41 -0
- package/dist/builders/create-git-candidate-comparison-tools.js.map +1 -0
- package/dist/builders/create-git-commit-and-push-builder.d.ts +18 -0
- package/dist/builders/create-git-commit-and-push-builder.d.ts.map +1 -0
- package/dist/builders/create-git-commit-and-push-builder.js +65 -0
- package/dist/builders/create-git-commit-and-push-builder.js.map +1 -0
- package/dist/builders/create-git-cow-worktree-builder.d.ts +15 -0
- package/dist/builders/create-git-cow-worktree-builder.d.ts.map +1 -0
- package/dist/builders/create-git-cow-worktree-builder.js +64 -0
- package/dist/builders/create-git-cow-worktree-builder.js.map +1 -0
- package/dist/builders/create-git-discard-branch-builder.d.ts +13 -0
- package/dist/builders/create-git-discard-branch-builder.d.ts.map +1 -0
- package/dist/builders/create-git-discard-branch-builder.js +22 -0
- package/dist/builders/create-git-discard-branch-builder.js.map +1 -0
- package/dist/builders/create-git-keep-worktree-builder.d.ts +13 -0
- package/dist/builders/create-git-keep-worktree-builder.d.ts.map +1 -0
- package/dist/builders/create-git-keep-worktree-builder.js +22 -0
- package/dist/builders/create-git-keep-worktree-builder.js.map +1 -0
- package/dist/builders/create-git-merge-queue-builder.d.ts +19 -0
- package/dist/builders/create-git-merge-queue-builder.d.ts.map +1 -0
- package/dist/builders/create-git-merge-queue-builder.js +59 -0
- package/dist/builders/create-git-merge-queue-builder.js.map +1 -0
- package/dist/builders/create-git-patch-equivalence-builder.d.ts +13 -0
- package/dist/builders/create-git-patch-equivalence-builder.d.ts.map +1 -0
- package/dist/builders/create-git-patch-equivalence-builder.js +32 -0
- package/dist/builders/create-git-patch-equivalence-builder.js.map +1 -0
- package/dist/builders/create-git-public-surface-cross-tester-builder.d.ts +14 -0
- package/dist/builders/create-git-public-surface-cross-tester-builder.d.ts.map +1 -0
- package/dist/builders/create-git-public-surface-cross-tester-builder.js +36 -0
- package/dist/builders/create-git-public-surface-cross-tester-builder.js.map +1 -0
- package/dist/builders/create-git-ref-reader-tools.d.ts +13 -0
- package/dist/builders/create-git-ref-reader-tools.d.ts.map +1 -0
- package/dist/builders/create-git-ref-reader-tools.js +41 -0
- package/dist/builders/create-git-ref-reader-tools.js.map +1 -0
- package/dist/builders/create-git-reset-worktree-builder.d.ts +13 -0
- package/dist/builders/create-git-reset-worktree-builder.d.ts.map +1 -0
- package/dist/builders/create-git-reset-worktree-builder.js +22 -0
- package/dist/builders/create-git-reset-worktree-builder.js.map +1 -0
- package/dist/builders/create-git-snapshot-and-reset-builder.d.ts +13 -0
- package/dist/builders/create-git-snapshot-and-reset-builder.d.ts.map +1 -0
- package/dist/builders/create-git-snapshot-and-reset-builder.js +23 -0
- package/dist/builders/create-git-snapshot-and-reset-builder.js.map +1 -0
- package/dist/builders/git-commit-and-push-builder.d.ts +44 -0
- package/dist/builders/git-commit-and-push-builder.d.ts.map +1 -0
- package/dist/builders/git-commit-and-push-builder.js +2 -0
- package/dist/builders/git-commit-and-push-builder.js.map +1 -0
- package/dist/builders/git-commit-and-push-options.d.ts +22 -0
- package/dist/builders/git-commit-and-push-options.d.ts.map +1 -0
- package/dist/builders/git-commit-and-push-options.js +2 -0
- package/dist/builders/git-commit-and-push-options.js.map +1 -0
- package/dist/builders/git-cow-worktree-builder.d.ts +64 -0
- package/dist/builders/git-cow-worktree-builder.d.ts.map +1 -0
- package/dist/builders/git-cow-worktree-builder.js +2 -0
- package/dist/builders/git-cow-worktree-builder.js.map +1 -0
- package/dist/builders/git-cow-worktree-options.d.ts +42 -0
- package/dist/builders/git-cow-worktree-options.d.ts.map +1 -0
- package/dist/builders/git-cow-worktree-options.js +2 -0
- package/dist/builders/git-cow-worktree-options.js.map +1 -0
- package/dist/builders/git-merge-queue-builder.d.ts +37 -0
- package/dist/builders/git-merge-queue-builder.d.ts.map +1 -0
- package/dist/builders/git-merge-queue-builder.js +2 -0
- package/dist/builders/git-merge-queue-builder.js.map +1 -0
- package/dist/builders/git-merge-queue-options.d.ts +23 -0
- package/dist/builders/git-merge-queue-options.d.ts.map +1 -0
- package/dist/builders/git-merge-queue-options.js +2 -0
- package/dist/builders/git-merge-queue-options.js.map +1 -0
- package/dist/builders/git-namespace-contract.d.ts +141 -0
- package/dist/builders/git-namespace-contract.d.ts.map +1 -0
- package/dist/builders/git-namespace-contract.js +2 -0
- package/dist/builders/git-namespace-contract.js.map +1 -0
- package/dist/builders/git-namespace.d.ts +6 -0
- package/dist/builders/git-namespace.d.ts.map +1 -0
- package/dist/builders/git-namespace.js +32 -0
- package/dist/builders/git-namespace.js.map +1 -0
- package/dist/builders/git-public-surface-cross-tester-options.d.ts +16 -0
- package/dist/builders/git-public-surface-cross-tester-options.d.ts.map +1 -0
- package/dist/builders/git-public-surface-cross-tester-options.js +2 -0
- package/dist/builders/git-public-surface-cross-tester-options.js.map +1 -0
- package/dist/builders/git-reconcile-strategy-options.d.ts +16 -0
- package/dist/builders/git-reconcile-strategy-options.d.ts.map +1 -0
- package/dist/builders/git-reconcile-strategy-options.js +2 -0
- package/dist/builders/git-reconcile-strategy-options.js.map +1 -0
- package/dist/builders/internal/build-git-cow-worktree-node.d.ts +35 -0
- package/dist/builders/internal/build-git-cow-worktree-node.d.ts.map +1 -0
- package/dist/builders/internal/build-git-cow-worktree-node.js +77 -0
- package/dist/builders/internal/build-git-cow-worktree-node.js.map +1 -0
- package/dist/executors/create-git-executors.d.ts +12 -0
- package/dist/executors/create-git-executors.d.ts.map +1 -0
- package/dist/executors/create-git-executors.js +43 -0
- package/dist/executors/create-git-executors.js.map +1 -0
- package/dist/executors/git-checkpoint-payload.d.ts +44 -0
- package/dist/executors/git-checkpoint-payload.d.ts.map +1 -0
- package/dist/executors/git-checkpoint-payload.js +2 -0
- package/dist/executors/git-checkpoint-payload.js.map +1 -0
- package/dist/executors/git-commit-and-merge-steps.d.ts +33 -0
- package/dist/executors/git-commit-and-merge-steps.d.ts.map +1 -0
- package/dist/executors/git-commit-and-merge-steps.js +52 -0
- package/dist/executors/git-commit-and-merge-steps.js.map +1 -0
- package/dist/executors/git-cow-worktree-scope.d.ts +201 -0
- package/dist/executors/git-cow-worktree-scope.d.ts.map +1 -0
- package/dist/executors/git-cow-worktree-scope.js +260 -0
- package/dist/executors/git-cow-worktree-scope.js.map +1 -0
- package/dist/executors/git-cross-verifiers-and-tools.d.ts +42 -0
- package/dist/executors/git-cross-verifiers-and-tools.d.ts.map +1 -0
- package/dist/executors/git-cross-verifiers-and-tools.js +112 -0
- package/dist/executors/git-cross-verifiers-and-tools.js.map +1 -0
- package/dist/executors/git-executors.constants.d.ts +4 -0
- package/dist/executors/git-executors.constants.d.ts.map +1 -0
- package/dist/executors/git-executors.constants.js +4 -0
- package/dist/executors/git-executors.constants.js.map +1 -0
- package/dist/executors/git-hooks-and-checks.d.ts +51 -0
- package/dist/executors/git-hooks-and-checks.d.ts.map +1 -0
- package/dist/executors/git-hooks-and-checks.js +139 -0
- package/dist/executors/git-hooks-and-checks.js.map +1 -0
- package/dist/executors/internal/checkpoint-restore-steps.d.ts +50 -0
- package/dist/executors/internal/checkpoint-restore-steps.d.ts.map +1 -0
- package/dist/executors/internal/checkpoint-restore-steps.js +184 -0
- package/dist/executors/internal/checkpoint-restore-steps.js.map +1 -0
- package/dist/executors/internal/checkpoint-staging-and-integrity.d.ts +51 -0
- package/dist/executors/internal/checkpoint-staging-and-integrity.d.ts.map +1 -0
- package/dist/executors/internal/checkpoint-staging-and-integrity.js +192 -0
- package/dist/executors/internal/checkpoint-staging-and-integrity.js.map +1 -0
- package/dist/executors/internal/compute-worktree-status-options.d.ts +15 -0
- package/dist/executors/internal/compute-worktree-status-options.d.ts.map +1 -0
- package/dist/executors/internal/compute-worktree-status-options.js +2 -0
- package/dist/executors/internal/compute-worktree-status-options.js.map +1 -0
- package/dist/executors/internal/cow-worktree-hydrator.d.ts +51 -0
- package/dist/executors/internal/cow-worktree-hydrator.d.ts.map +1 -0
- package/dist/executors/internal/cow-worktree-hydrator.js +174 -0
- package/dist/executors/internal/cow-worktree-hydrator.js.map +1 -0
- package/dist/executors/internal/file-digest-and-globs.d.ts +58 -0
- package/dist/executors/internal/file-digest-and-globs.d.ts.map +1 -0
- package/dist/executors/internal/file-digest-and-globs.js +188 -0
- package/dist/executors/internal/file-digest-and-globs.js.map +1 -0
- package/dist/executors/internal/git-checkpoint-diff-effects.d.ts +16 -0
- package/dist/executors/internal/git-checkpoint-diff-effects.d.ts.map +1 -0
- package/dist/executors/internal/git-checkpoint-diff-effects.js +38 -0
- package/dist/executors/internal/git-checkpoint-diff-effects.js.map +1 -0
- package/dist/executors/internal/git-checkpoint-restore.d.ts +14 -0
- package/dist/executors/internal/git-checkpoint-restore.d.ts.map +1 -0
- package/dist/executors/internal/git-checkpoint-restore.js +37 -0
- package/dist/executors/internal/git-checkpoint-restore.js.map +1 -0
- package/dist/executors/internal/git-checkpoint-serialize.d.ts +13 -0
- package/dist/executors/internal/git-checkpoint-serialize.d.ts.map +1 -0
- package/dist/executors/internal/git-checkpoint-serialize.js +48 -0
- package/dist/executors/internal/git-checkpoint-serialize.js.map +1 -0
- package/dist/executors/internal/git-checkpoint-status-map.d.ts +14 -0
- package/dist/executors/internal/git-checkpoint-status-map.d.ts.map +1 -0
- package/dist/executors/internal/git-checkpoint-status-map.js +27 -0
- package/dist/executors/internal/git-checkpoint-status-map.js.map +1 -0
- package/dist/executors/internal/git-cli-command-options.d.ts +21 -0
- package/dist/executors/internal/git-cli-command-options.d.ts.map +1 -0
- package/dist/executors/internal/git-cli-command-options.js +2 -0
- package/dist/executors/internal/git-cli-command-options.js.map +1 -0
- package/dist/executors/internal/git-cli-command-result.d.ts +16 -0
- package/dist/executors/internal/git-cli-command-result.d.ts.map +1 -0
- package/dist/executors/internal/git-cli-command-result.js +2 -0
- package/dist/executors/internal/git-cli-command-result.js.map +1 -0
- package/dist/executors/internal/git-cli-runner.d.ts +73 -0
- package/dist/executors/internal/git-cli-runner.d.ts.map +1 -0
- package/dist/executors/internal/git-cli-runner.js +157 -0
- package/dist/executors/internal/git-cli-runner.js.map +1 -0
- package/dist/executors/internal/git-cross-test-import-scanner.d.ts +68 -0
- package/dist/executors/internal/git-cross-test-import-scanner.d.ts.map +1 -0
- package/dist/executors/internal/git-cross-test-import-scanner.js +226 -0
- package/dist/executors/internal/git-cross-test-import-scanner.js.map +1 -0
- package/dist/executors/internal/git-executor.constants.d.ts +29 -0
- package/dist/executors/internal/git-executor.constants.d.ts.map +1 -0
- package/dist/executors/internal/git-executor.constants.js +40 -0
- package/dist/executors/internal/git-executor.constants.js.map +1 -0
- package/dist/executors/internal/git-merge-train-bisect.d.ts +51 -0
- package/dist/executors/internal/git-merge-train-bisect.d.ts.map +1 -0
- package/dist/executors/internal/git-merge-train-bisect.js +152 -0
- package/dist/executors/internal/git-merge-train-bisect.js.map +1 -0
- package/dist/executors/internal/git-tool-dispatchers.d.ts +26 -0
- package/dist/executors/internal/git-tool-dispatchers.d.ts.map +1 -0
- package/dist/executors/internal/git-tool-dispatchers.js +174 -0
- package/dist/executors/internal/git-tool-dispatchers.js.map +1 -0
- package/dist/executors/internal/git-worktree-acquire-root.d.ts +22 -0
- package/dist/executors/internal/git-worktree-acquire-root.d.ts.map +1 -0
- package/dist/executors/internal/git-worktree-acquire-root.js +67 -0
- package/dist/executors/internal/git-worktree-acquire-root.js.map +1 -0
- package/dist/executors/internal/git-worktree-commit-child.d.ts +26 -0
- package/dist/executors/internal/git-worktree-commit-child.d.ts.map +1 -0
- package/dist/executors/internal/git-worktree-commit-child.js +88 -0
- package/dist/executors/internal/git-worktree-commit-child.js.map +1 -0
- package/dist/executors/internal/git-worktree-flush-and-prune.d.ts +43 -0
- package/dist/executors/internal/git-worktree-flush-and-prune.d.ts.map +1 -0
- package/dist/executors/internal/git-worktree-flush-and-prune.js +169 -0
- package/dist/executors/internal/git-worktree-flush-and-prune.js.map +1 -0
- package/dist/executors/internal/git-worktree-fork-and-release.d.ts +37 -0
- package/dist/executors/internal/git-worktree-fork-and-release.d.ts.map +1 -0
- package/dist/executors/internal/git-worktree-fork-and-release.js +159 -0
- package/dist/executors/internal/git-worktree-fork-and-release.js.map +1 -0
- package/dist/executors/internal/git-worktree-materialize-merge.d.ts +51 -0
- package/dist/executors/internal/git-worktree-materialize-merge.d.ts.map +1 -0
- package/dist/executors/internal/git-worktree-materialize-merge.js +161 -0
- package/dist/executors/internal/git-worktree-materialize-merge.js.map +1 -0
- package/dist/executors/internal/git-worktree-reattach.d.ts +57 -0
- package/dist/executors/internal/git-worktree-reattach.d.ts.map +1 -0
- package/dist/executors/internal/git-worktree-reattach.js +324 -0
- package/dist/executors/internal/git-worktree-reattach.js.map +1 -0
- package/dist/executors/internal/git-worktree-sync-child-and-root.d.ts +26 -0
- package/dist/executors/internal/git-worktree-sync-child-and-root.d.ts.map +1 -0
- package/dist/executors/internal/git-worktree-sync-child-and-root.js +82 -0
- package/dist/executors/internal/git-worktree-sync-child-and-root.js.map +1 -0
- package/dist/executors/internal/host-repository-head-state.d.ts +10 -0
- package/dist/executors/internal/host-repository-head-state.d.ts.map +1 -0
- package/dist/executors/internal/host-repository-head-state.js +2 -0
- package/dist/executors/internal/host-repository-head-state.js.map +1 -0
- package/dist/executors/internal/merge-train-candidate.d.ts +14 -0
- package/dist/executors/internal/merge-train-candidate.d.ts.map +1 -0
- package/dist/executors/internal/merge-train-candidate.js +2 -0
- package/dist/executors/internal/merge-train-candidate.js.map +1 -0
- package/dist/executors/internal/merge-train-chain-entry.d.ts +13 -0
- package/dist/executors/internal/merge-train-chain-entry.d.ts.map +1 -0
- package/dist/executors/internal/merge-train-chain-entry.js +2 -0
- package/dist/executors/internal/merge-train-chain-entry.js.map +1 -0
- package/dist/executors/internal/merge-train-result.d.ts +19 -0
- package/dist/executors/internal/merge-train-result.d.ts.map +1 -0
- package/dist/executors/internal/merge-train-result.js +2 -0
- package/dist/executors/internal/merge-train-result.js.map +1 -0
- package/dist/executors/internal/merge-train-runner.d.ts +16 -0
- package/dist/executors/internal/merge-train-runner.d.ts.map +1 -0
- package/dist/executors/internal/merge-train-runner.js +141 -0
- package/dist/executors/internal/merge-train-runner.js.map +1 -0
- package/dist/executors/internal/merge-tree-materializer-params.d.ts +19 -0
- package/dist/executors/internal/merge-tree-materializer-params.d.ts.map +1 -0
- package/dist/executors/internal/merge-tree-materializer-params.js +2 -0
- package/dist/executors/internal/merge-tree-materializer-params.js.map +1 -0
- package/dist/executors/internal/parent-fast-forward.d.ts +47 -0
- package/dist/executors/internal/parent-fast-forward.d.ts.map +1 -0
- package/dist/executors/internal/parent-fast-forward.js +138 -0
- package/dist/executors/internal/parent-fast-forward.js.map +1 -0
- package/dist/executors/internal/porcelain-v2-parser.d.ts +49 -0
- package/dist/executors/internal/porcelain-v2-parser.d.ts.map +1 -0
- package/dist/executors/internal/porcelain-v2-parser.js +165 -0
- package/dist/executors/internal/porcelain-v2-parser.js.map +1 -0
- package/dist/executors/internal/resolve-effective-base-branch.d.ts +13 -0
- package/dist/executors/internal/resolve-effective-base-branch.d.ts.map +1 -0
- package/dist/executors/internal/resolve-effective-base-branch.js +38 -0
- package/dist/executors/internal/resolve-effective-base-branch.js.map +1 -0
- package/dist/executors/internal/squash-rebase-and-push.d.ts +14 -0
- package/dist/executors/internal/squash-rebase-and-push.d.ts.map +1 -0
- package/dist/executors/internal/squash-rebase-and-push.js +192 -0
- package/dist/executors/internal/squash-rebase-and-push.js.map +1 -0
- package/dist/executors/internal/staged-checkpoint-tree-result.d.ts +13 -0
- package/dist/executors/internal/staged-checkpoint-tree-result.d.ts.map +1 -0
- package/dist/executors/internal/staged-checkpoint-tree-result.js +2 -0
- package/dist/executors/internal/staged-checkpoint-tree-result.js.map +1 -0
- package/dist/executors/internal/stateless-merge-tree-result.d.ts +12 -0
- package/dist/executors/internal/stateless-merge-tree-result.d.ts.map +1 -0
- package/dist/executors/internal/stateless-merge-tree-result.js +2 -0
- package/dist/executors/internal/stateless-merge-tree-result.js.map +1 -0
- package/dist/executors/internal/synthesized-working-tree-commit.d.ts +10 -0
- package/dist/executors/internal/synthesized-working-tree-commit.d.ts.map +1 -0
- package/dist/executors/internal/synthesized-working-tree-commit.js +2 -0
- package/dist/executors/internal/synthesized-working-tree-commit.js.map +1 -0
- package/dist/executors/internal/worktree-integrity-verdict.d.ts +10 -0
- package/dist/executors/internal/worktree-integrity-verdict.d.ts.map +1 -0
- package/dist/executors/internal/worktree-integrity-verdict.js +2 -0
- package/dist/executors/internal/worktree-integrity-verdict.js.map +1 -0
- package/dist/executors/internal/worktree-status-snapshot.d.ts +17 -0
- package/dist/executors/internal/worktree-status-snapshot.d.ts.map +1 -0
- package/dist/executors/internal/worktree-status-snapshot.js +2 -0
- package/dist/executors/internal/worktree-status-snapshot.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/git-receipts.schema.d.ts +174 -0
- package/dist/schemas/git-receipts.schema.d.ts.map +1 -0
- package/dist/schemas/git-receipts.schema.js +123 -0
- package/dist/schemas/git-receipts.schema.js.map +1 -0
- package/package.json +71 -3
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { lstat, readFile, rm } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { computeNodeModulesDigest, copyFileCowOrValue, } from './file-digest-and-globs.js';
|
|
5
|
+
import { readHarnessMeta, runGitCommand } from './git-cli-runner.js';
|
|
6
|
+
/**
|
|
7
|
+
* Stages tracked dirty files and size-bounded untracked files into a temporary git index to produce `treeSha`.
|
|
8
|
+
*
|
|
9
|
+
* Spills untracked (`?`) files exceeding `maxUntrackedBytes` into `<gitdir>/harness-ckpt-blobs/` via CoW/value copy.
|
|
10
|
+
*
|
|
11
|
+
* @param {GitWorktreeHandle} handle - Active worktree handle.
|
|
12
|
+
* @param {WorktreeStatusSnapshot} snapshot - Porcelain v2 status snapshot of the worktree.
|
|
13
|
+
* @param {number} maxUntrackedBytes - Byte threshold above which untracked files spill to `harness-ckpt-blobs/`.
|
|
14
|
+
*
|
|
15
|
+
* @returns {Promise<StagedCheckpointTreeResult>} Synthesized tree SHA and spilled blob map.
|
|
16
|
+
*/
|
|
17
|
+
export async function stageCheckpointTreeAndOversizedBlobs(handle, snapshot, maxUntrackedBytes) {
|
|
18
|
+
const headSha = (await runGitCommand({ cwd: handle.worktreePath, args: ['rev-parse', 'HEAD'] })).stdout.trim();
|
|
19
|
+
const tmpIndex = path.join(handle.gitDirPath, `harness-ckpt-idx.${process.pid}.${randomUUID()}`);
|
|
20
|
+
const toAdd = [];
|
|
21
|
+
const toRemove = [];
|
|
22
|
+
const oversized = {};
|
|
23
|
+
try {
|
|
24
|
+
await runGitCommand({ cwd: handle.worktreePath, args: ['read-tree', headSha], env: { GIT_INDEX_FILE: tmpIndex } });
|
|
25
|
+
for (const [relPath, digest] of Object.entries(snapshot.statusMap)) {
|
|
26
|
+
if (digest === 'DELETED') {
|
|
27
|
+
toRemove.push(relPath);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const absPath = path.join(handle.worktreePath, relPath);
|
|
31
|
+
const stat = await lstat(absPath);
|
|
32
|
+
if (snapshot.untrackedPaths.has(relPath) && stat.isFile() && stat.size > maxUntrackedBytes) {
|
|
33
|
+
const blobKey = `${stat.size}_${Math.trunc(stat.mtimeMs)}_${digest.replace(':', '_')}`;
|
|
34
|
+
await copyFileCowOrValue(absPath, path.join(handle.gitDirPath, 'harness-ckpt-blobs', blobKey), stat.mode);
|
|
35
|
+
oversized[relPath] = Object.freeze({ blobKey, mode: stat.mode, size: stat.size });
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
toAdd.push(relPath);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (toRemove.length > 0)
|
|
42
|
+
await runGitCommand({ cwd: handle.worktreePath, args: ['update-index', '--force-remove', '-z', '--stdin'], env: { GIT_INDEX_FILE: tmpIndex }, stdin: `${toRemove.join('\0')}\0` });
|
|
43
|
+
if (toAdd.length > 0)
|
|
44
|
+
await runGitCommand({ cwd: handle.worktreePath, args: ['update-index', '--add', '-z', '--stdin'], env: { GIT_INDEX_FILE: tmpIndex }, stdin: `${toAdd.join('\0')}\0` });
|
|
45
|
+
const treeOutput = await runGitCommand({ cwd: handle.worktreePath, args: ['write-tree'], env: { GIT_INDEX_FILE: tmpIndex } });
|
|
46
|
+
return Object.freeze({ headSha, treeSha: treeOutput.stdout.trim(), oversizedUntrackedBlobs: Object.freeze(oversized) });
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
await rm(tmpIndex, { force: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Compares two `Readonly<Record<string, string>>` maps for exact key and value equality.
|
|
54
|
+
*
|
|
55
|
+
* @param {Readonly<Record<string, string>>} left - First string map.
|
|
56
|
+
* @param {Readonly<Record<string, string>>} right - Second string map.
|
|
57
|
+
*
|
|
58
|
+
* @returns {boolean} `true` when both maps contain the exact same keys and values.
|
|
59
|
+
*/
|
|
60
|
+
function isStringRecordEqual(left, right) {
|
|
61
|
+
const leftKeys = Object.keys(left);
|
|
62
|
+
const rightKeys = Object.keys(right);
|
|
63
|
+
if (leftKeys.length !== rightKeys.length)
|
|
64
|
+
return false;
|
|
65
|
+
for (const key of leftKeys) {
|
|
66
|
+
if (left[key] !== right[key])
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Compares two `HarnessMetaRecord` instances for structural equality without `JSON.stringify` key-order sensitivity.
|
|
73
|
+
*
|
|
74
|
+
* @param {HarnessMetaRecord} left - Current metadata record read from disk.
|
|
75
|
+
* @param {HarnessMetaRecord} right - Baseline metadata record stored in the checkpoint.
|
|
76
|
+
*
|
|
77
|
+
* @returns {boolean} `true` when both metadata records are structurally identical.
|
|
78
|
+
*/
|
|
79
|
+
function isHarnessMetaEqual(left, right) {
|
|
80
|
+
if (left.baseRef !== right.baseRef ||
|
|
81
|
+
left.baseBranch !== right.baseBranch ||
|
|
82
|
+
left.branchName !== right.branchName ||
|
|
83
|
+
left.pendingParentHeadSha !== right.pendingParentHeadSha) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
if (!isStringRecordEqual(left.unresolvedConflictPaths, right.unresolvedConflictPaths)) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if ((left.inFlightMerge === undefined) !== (right.inFlightMerge === undefined)) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (left.inFlightMerge !== undefined && right.inFlightMerge !== undefined) {
|
|
93
|
+
if (left.inFlightMerge.targetHeadSha !== right.inFlightMerge.targetHeadSha ||
|
|
94
|
+
left.inFlightMerge.mergedTreeSha !== right.inFlightMerge.mergedTreeSha ||
|
|
95
|
+
left.inFlightMerge.priorTreeSha !== right.inFlightMerge.priorTreeSha ||
|
|
96
|
+
!isStringRecordEqual(left.inFlightMerge.unresolvedConflictPaths, right.inFlightMerge.unresolvedConflictPaths)) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if ((left.inFlightCommitAndPush === undefined) !== (right.inFlightCommitAndPush === undefined)) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
if (left.inFlightCommitAndPush !== undefined && right.inFlightCommitAndPush !== undefined) {
|
|
104
|
+
return (left.inFlightCommitAndPush.preStepHeadSha === right.inFlightCommitAndPush.preStepHeadSha &&
|
|
105
|
+
left.inFlightCommitAndPush.preStepBaseRef === right.inFlightCommitAndPush.preStepBaseRef &&
|
|
106
|
+
left.inFlightCommitAndPush.targetBranch === right.inFlightCommitAndPush.targetBranch);
|
|
107
|
+
}
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Verifies worktree-local `.git` metadata (`HEAD`, `indexTreeSha`, `info/exclude`, `harness-meta.json`) and `node_modules` integrity.
|
|
112
|
+
*
|
|
113
|
+
* Returns `{ intact: false, reason }` if any worktree-local metadata or `node_modules` tree was mutated by a subprocess.
|
|
114
|
+
*
|
|
115
|
+
* @param {GitWorktreeHandle} handle - Active worktree handle.
|
|
116
|
+
* @param {GitCheckpointPayload} fromCheckpoint - Parsed baseline checkpoint payload.
|
|
117
|
+
*
|
|
118
|
+
* @returns {Promise<WorktreeIntegrityVerdict>} Integrity verification result.
|
|
119
|
+
*/
|
|
120
|
+
export async function verifyWorktreeLocalGitIntegrity(handle, fromCheckpoint) {
|
|
121
|
+
try {
|
|
122
|
+
const headRaw = await readFile(path.join(handle.gitDirPath, 'HEAD'), 'utf8');
|
|
123
|
+
if (headRaw !== fromCheckpoint.headRawContent)
|
|
124
|
+
return { intact: false, reason: '<gitdir>/HEAD raw content was modified' };
|
|
125
|
+
const headOutput = await runGitCommand({ cwd: handle.worktreePath, args: ['rev-parse', 'HEAD'], allowNonZeroExit: true });
|
|
126
|
+
if (headOutput.exitCode !== 0 || headOutput.stdout.trim() !== fromCheckpoint.headSha)
|
|
127
|
+
return { intact: false, reason: 'HEAD commit SHA was mutated' };
|
|
128
|
+
const idxTreeOutput = await runGitCommand({ cwd: handle.worktreePath, args: ['write-tree'], allowNonZeroExit: true });
|
|
129
|
+
if (idxTreeOutput.exitCode !== 0 || idxTreeOutput.stdout.trim() !== fromCheckpoint.indexTreeSha)
|
|
130
|
+
return { intact: false, reason: '<gitdir>/index was mutated' };
|
|
131
|
+
const infoExclude = await readFile(path.join(handle.gitDirPath, 'info', 'exclude'), 'utf8').catch(() => null);
|
|
132
|
+
if (infoExclude !== fromCheckpoint.infoExcludeContent)
|
|
133
|
+
return { intact: false, reason: '<gitdir>/info/exclude was mutated' };
|
|
134
|
+
const meta = await readHarnessMeta(handle.gitDirPath);
|
|
135
|
+
if (!isHarnessMetaEqual(meta, fromCheckpoint.meta))
|
|
136
|
+
return { intact: false, reason: '<gitdir>/harness-meta.json was mutated' };
|
|
137
|
+
const nmDigest = await computeNodeModulesDigest(handle.worktreePath);
|
|
138
|
+
if (nmDigest !== fromCheckpoint.nodeModulesDigest)
|
|
139
|
+
return { intact: false, reason: 'node_modules tree was mutated' };
|
|
140
|
+
return { intact: true };
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
return { intact: false, reason: err instanceof Error ? err.message : String(err) };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Lists all repository-relative file paths recorded inside a Git tree object (`git ls-tree -r --name-only -z`).
|
|
148
|
+
*
|
|
149
|
+
* Returns a `ReadonlySet<string>` for $O(1)$ membership queries during checkpoint restoration and merge materialization.
|
|
150
|
+
*
|
|
151
|
+
* @param {string} worktreePath - Worktree directory path.
|
|
152
|
+
* @param {string} treeOrCommit - Git tree or commit SHA to list.
|
|
153
|
+
*
|
|
154
|
+
* @returns {Promise<ReadonlySet<string>>} Set of repository-relative file paths in `treeOrCommit`.
|
|
155
|
+
*/
|
|
156
|
+
export async function listTreePaths(worktreePath, treeOrCommit) {
|
|
157
|
+
const lsTreeOutput = await runGitCommand({
|
|
158
|
+
cwd: worktreePath,
|
|
159
|
+
args: ['ls-tree', '-r', '--name-only', '-z', treeOrCommit],
|
|
160
|
+
});
|
|
161
|
+
const paths = new Set();
|
|
162
|
+
for (const entry of lsTreeOutput.stdout.split('\0')) {
|
|
163
|
+
if (entry.length > 0)
|
|
164
|
+
paths.add(entry);
|
|
165
|
+
}
|
|
166
|
+
return paths;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Computes the sorted symmetric difference of paths whose `${mode}:${sha256}` status changed between two status maps.
|
|
170
|
+
*
|
|
171
|
+
* Includes paths added, deleted, modified, or reverted back to clean `HEAD` between `beforeMap` and `afterMap`.
|
|
172
|
+
*
|
|
173
|
+
* @param {Readonly<Record<string, string>>} beforeMap - Baseline status map from `fromCheckpoint`.
|
|
174
|
+
* @param {Readonly<Record<string, string>>} afterMap - Current worktree status map.
|
|
175
|
+
*
|
|
176
|
+
* @returns {readonly string[]} Lexicographically sorted list of changed repository-relative paths.
|
|
177
|
+
*/
|
|
178
|
+
export function computeSymmetricStatusDiff(beforeMap, afterMap) {
|
|
179
|
+
const changed = new Set();
|
|
180
|
+
for (const [relPath, digest] of Object.entries(beforeMap)) {
|
|
181
|
+
if (afterMap[relPath] !== digest)
|
|
182
|
+
changed.add(relPath);
|
|
183
|
+
}
|
|
184
|
+
for (const [relPath, digest] of Object.entries(afterMap)) {
|
|
185
|
+
if (beforeMap[relPath] !== digest)
|
|
186
|
+
changed.add(relPath);
|
|
187
|
+
}
|
|
188
|
+
const sorted = [...changed];
|
|
189
|
+
sorted.sort();
|
|
190
|
+
return Object.freeze(sorted);
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=checkpoint-staging-and-integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-staging-and-integrity.js","sourceRoot":"","sources":["../../../src/executors/internal/checkpoint-staging-and-integrity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for `computeWorktreeStatusMap` when scanning a worktree via `git status --porcelain=v2 -z`.
|
|
3
|
+
*
|
|
4
|
+
* Configures optional user `excludeGlobs`, whether `repo` is `'.'`, and whether `--ignored=matching`
|
|
5
|
+
* should be enabled to surface newly gitignored files.
|
|
6
|
+
*/
|
|
7
|
+
export interface ComputeWorktreeStatusOptions {
|
|
8
|
+
/** Optional glob patterns excluded from the status map (except `**\/.gitignore`). */
|
|
9
|
+
readonly excludeGlobs?: readonly string[];
|
|
10
|
+
/** Optional paths that were already ignored at checkpoint creation time. */
|
|
11
|
+
readonly baselineIgnoredPaths?: ReadonlySet<string>;
|
|
12
|
+
/** When `true`, passes `--ignored=matching` to `git status` to detect files hidden behind `.gitignore` edits. */
|
|
13
|
+
readonly includeMatchingIgnored?: boolean;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=compute-worktree-status-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-worktree-status-options.d.ts","sourceRoot":"","sources":["../../../src/executors/internal/compute-worktree-status-options.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,4BAA4B;IAC3C,qFAAqF;IACrF,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,4EAA4E;IAC5E,QAAQ,CAAC,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpD,iHAAiH;IACjH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAC3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-worktree-status-options.js","sourceRoot":"","sources":["../../../src/executors/internal/compute-worktree-status-options.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ASTNode, GitCowWorktreeNode } from '@paraharness/core';
|
|
2
|
+
/**
|
|
3
|
+
* Recursively clones `srcNodeModules` into `destNodeModules` using hardlinks (`link`) for regular files and `symlink` for links.
|
|
4
|
+
*
|
|
5
|
+
* Copies `.prisma` directories by value and skips any paths matching `excludeGlobs`.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} srcRoot - Source repository or parent worktree path.
|
|
8
|
+
* @param {string} destRoot - Destination worktree path.
|
|
9
|
+
* @param {readonly string[] | undefined} [excludeGlobs] - Optional glob patterns excluded from cloning.
|
|
10
|
+
*
|
|
11
|
+
* @returns {Promise<void>} Resolves once `node_modules` is cloned into `destRoot`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function cloneNodeModulesTree(srcRoot: string, destRoot: string, excludeGlobs?: readonly string[]): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Evaluates `.lockfileGate(lockfilePath)` between `repoPath` and `worktreePath` and hydrates `node_modules` or runs `setupCommands`.
|
|
16
|
+
*
|
|
17
|
+
* On a lockfile hash hit, hardlinks `node_modules` and skips setup; on a miss, unlinks any hardlinked `node_modules` and runs `setupCommands`.
|
|
18
|
+
*
|
|
19
|
+
* @param {GitCowWorktreeNode} node - Worktree scope AST node configuration.
|
|
20
|
+
* @param {string} repoPath - Host repository root path.
|
|
21
|
+
* @param {string} worktreePath - Newly created root worktree path.
|
|
22
|
+
*
|
|
23
|
+
* @returns {Promise<void>} Resolves once `node_modules` hydration and any required setup commands complete.
|
|
24
|
+
*/
|
|
25
|
+
export declare function hydrateWorktreeDependencies(node: GitCowWorktreeNode, repoPath: string, worktreePath: string): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Checks whether the lockfile at `lockfileGatePath` in `worktreePath` matches the host repository's warm `node_modules` cache hash.
|
|
28
|
+
*
|
|
29
|
+
* Records the initial host lockfile hash in `<hostGitDir>/harness-warm-lockfile.sha256` when `repoPath/node_modules` is first observed.
|
|
30
|
+
*
|
|
31
|
+
* @param {string} repoPath - Host repository root path.
|
|
32
|
+
* @param {string} worktreePath - Target worktree path.
|
|
33
|
+
* @param {string} lockfileGatePath - Repository-relative path to the lockfile (such as `'pnpm-lock.yaml'`).
|
|
34
|
+
*
|
|
35
|
+
* @returns {Promise<boolean>} `true` on a lockfile cache hit, or `false` on a gate miss.
|
|
36
|
+
*/
|
|
37
|
+
export declare function evaluateLockfileGateHit(repoPath: string, worktreePath: string, lockfileGatePath: string): Promise<boolean>;
|
|
38
|
+
/**
|
|
39
|
+
* Executes a single setup command AST node (`node:command` or `harness:command`) inside `worktreePath`.
|
|
40
|
+
*
|
|
41
|
+
* Spawns `argv` with the isolated worktree Git environment when `cmdNode` is a `LocalCommandNode`.
|
|
42
|
+
*
|
|
43
|
+
* @param {ASTNode} cmdNode - Setup command AST node from `GitCowWorktreeNode.setupCommands`.
|
|
44
|
+
* @param {string} worktreePath - Target root worktree path.
|
|
45
|
+
*
|
|
46
|
+
* @returns {Promise<void>} Resolves once the setup command finishes with exit code `0`.
|
|
47
|
+
*
|
|
48
|
+
* @throws {Error} If the setup command exits with a non-zero status code.
|
|
49
|
+
*/
|
|
50
|
+
export declare function executeSetupCommandNode(cmdNode: ASTNode, worktreePath: string): Promise<void>;
|
|
51
|
+
//# sourceMappingURL=cow-worktree-hydrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cow-worktree-hydrator.d.ts","sourceRoot":"","sources":["../../../src/executors/internal/cow-worktree-hydrator.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAwDrE;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAC/B,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,kBAAkB,EACxB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC,CAoBlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAsBf"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { link, lstat, mkdir, readdir, readFile, readlink, rm, symlink, } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { withFileLock } from '@paraharness/lockfile';
|
|
6
|
+
import writeFileAtomic from 'write-file-atomic';
|
|
7
|
+
import { compileWorktreeExcludeMatcher, copyFileCowOrValue, } from './file-digest-and-globs.js';
|
|
8
|
+
import { buildIsolatedWorktreeGitEnv, runGitCommand } from './git-cli-runner.js';
|
|
9
|
+
/**
|
|
10
|
+
* Clones a single directory entry inside `node_modules` using symlink recreation, `.prisma` value copy, or hardlinking.
|
|
11
|
+
*
|
|
12
|
+
* @param {CloneSingleNodeModulesEntryParams} params - Single `node_modules` entry clone parameters.
|
|
13
|
+
*
|
|
14
|
+
* @returns {Promise<void>} Resolves once the entry is cloned or pushed onto `params.stack`.
|
|
15
|
+
*/
|
|
16
|
+
async function cloneSingleNodeModulesEntry(params) {
|
|
17
|
+
if (params.entry.isDirectory()) {
|
|
18
|
+
params.stack.push(params.childRel);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const srcAbs = path.join(params.srcRoot, params.childRel);
|
|
22
|
+
const destAbs = path.join(params.destRoot, params.childRel);
|
|
23
|
+
if (params.entry.isSymbolicLink()) {
|
|
24
|
+
await mkdir(path.dirname(destAbs), { recursive: true });
|
|
25
|
+
await rm(destAbs, { force: true });
|
|
26
|
+
await symlink(await readlink(srcAbs, 'utf8'), destAbs);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (params.childRel.includes('/.prisma/')) {
|
|
30
|
+
await copyFileCowOrValue(srcAbs, destAbs);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
await mkdir(path.dirname(destAbs), { recursive: true });
|
|
34
|
+
await rm(destAbs, { force: true });
|
|
35
|
+
await link(srcAbs, destAbs).catch(() => copyFileCowOrValue(srcAbs, destAbs));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Recursively clones `srcNodeModules` into `destNodeModules` using hardlinks (`link`) for regular files and `symlink` for links.
|
|
39
|
+
*
|
|
40
|
+
* Copies `.prisma` directories by value and skips any paths matching `excludeGlobs`.
|
|
41
|
+
*
|
|
42
|
+
* @param {string} srcRoot - Source repository or parent worktree path.
|
|
43
|
+
* @param {string} destRoot - Destination worktree path.
|
|
44
|
+
* @param {readonly string[] | undefined} [excludeGlobs] - Optional glob patterns excluded from cloning.
|
|
45
|
+
*
|
|
46
|
+
* @returns {Promise<void>} Resolves once `node_modules` is cloned into `destRoot`.
|
|
47
|
+
*/
|
|
48
|
+
export async function cloneNodeModulesTree(srcRoot, destRoot, excludeGlobs) {
|
|
49
|
+
const srcNm = path.join(srcRoot, 'node_modules');
|
|
50
|
+
const stat = await lstat(srcNm).catch(() => null);
|
|
51
|
+
if (stat === null || !stat.isDirectory())
|
|
52
|
+
return;
|
|
53
|
+
const isExcluded = compileWorktreeExcludeMatcher(excludeGlobs);
|
|
54
|
+
const stack = ['node_modules'];
|
|
55
|
+
while (stack.length > 0) {
|
|
56
|
+
const relDir = stack.pop() ?? '';
|
|
57
|
+
if (isExcluded(relDir))
|
|
58
|
+
continue;
|
|
59
|
+
const entries = await readdir(path.join(srcRoot, relDir), { withFileTypes: true });
|
|
60
|
+
for (const entry of entries) {
|
|
61
|
+
const childRel = `${relDir}/${entry.name}`;
|
|
62
|
+
if (isExcluded(childRel))
|
|
63
|
+
continue;
|
|
64
|
+
await cloneSingleNodeModulesEntry({
|
|
65
|
+
entry,
|
|
66
|
+
childRel,
|
|
67
|
+
srcRoot,
|
|
68
|
+
destRoot,
|
|
69
|
+
stack,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Evaluates `.lockfileGate(lockfilePath)` between `repoPath` and `worktreePath` and hydrates `node_modules` or runs `setupCommands`.
|
|
76
|
+
*
|
|
77
|
+
* On a lockfile hash hit, hardlinks `node_modules` and skips setup; on a miss, unlinks any hardlinked `node_modules` and runs `setupCommands`.
|
|
78
|
+
*
|
|
79
|
+
* @param {GitCowWorktreeNode} node - Worktree scope AST node configuration.
|
|
80
|
+
* @param {string} repoPath - Host repository root path.
|
|
81
|
+
* @param {string} worktreePath - Newly created root worktree path.
|
|
82
|
+
*
|
|
83
|
+
* @returns {Promise<void>} Resolves once `node_modules` hydration and any required setup commands complete.
|
|
84
|
+
*/
|
|
85
|
+
export async function hydrateWorktreeDependencies(node, repoPath, worktreePath) {
|
|
86
|
+
await cloneNodeModulesTree(repoPath, worktreePath, node.excludeFromCloneGlobs);
|
|
87
|
+
if (node.lockfileGatePath !== undefined) {
|
|
88
|
+
const isHit = await evaluateLockfileGateHit(repoPath, worktreePath, node.lockfileGatePath);
|
|
89
|
+
if (isHit)
|
|
90
|
+
return;
|
|
91
|
+
await rm(path.join(worktreePath, 'node_modules'), { recursive: true, force: true });
|
|
92
|
+
}
|
|
93
|
+
else if (node.setupCommands.length > 0) {
|
|
94
|
+
await rm(path.join(worktreePath, 'node_modules'), { recursive: true, force: true });
|
|
95
|
+
}
|
|
96
|
+
for (const cmdNode of node.setupCommands) {
|
|
97
|
+
await executeSetupCommandNode(cmdNode, worktreePath);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Checks whether the lockfile at `lockfileGatePath` in `worktreePath` matches the host repository's warm `node_modules` cache hash.
|
|
102
|
+
*
|
|
103
|
+
* Records the initial host lockfile hash in `<hostGitDir>/harness-warm-lockfile.sha256` when `repoPath/node_modules` is first observed.
|
|
104
|
+
*
|
|
105
|
+
* @param {string} repoPath - Host repository root path.
|
|
106
|
+
* @param {string} worktreePath - Target worktree path.
|
|
107
|
+
* @param {string} lockfileGatePath - Repository-relative path to the lockfile (such as `'pnpm-lock.yaml'`).
|
|
108
|
+
*
|
|
109
|
+
* @returns {Promise<boolean>} `true` on a lockfile cache hit, or `false` on a gate miss.
|
|
110
|
+
*/
|
|
111
|
+
export async function evaluateLockfileGateHit(repoPath, worktreePath, lockfileGatePath) {
|
|
112
|
+
const hostNmStat = await lstat(path.join(repoPath, 'node_modules')).catch(() => null);
|
|
113
|
+
if (hostNmStat === null || !hostNmStat.isDirectory())
|
|
114
|
+
return false;
|
|
115
|
+
const wtLockBuf = await readFile(path.join(worktreePath, lockfileGatePath)).catch(() => null);
|
|
116
|
+
const hostLockBuf = await readFile(path.join(repoPath, lockfileGatePath)).catch(() => null);
|
|
117
|
+
if (wtLockBuf === null || hostLockBuf === null)
|
|
118
|
+
return false;
|
|
119
|
+
const wtHash = createHash('sha256').update(wtLockBuf).digest('hex');
|
|
120
|
+
const hostHash = createHash('sha256').update(hostLockBuf).digest('hex');
|
|
121
|
+
const gitCommonOutput = await runGitCommand({ cwd: repoPath, args: ['rev-parse', '--git-common-dir'] });
|
|
122
|
+
const commonGitDir = path.resolve(repoPath, gitCommonOutput.stdout.trim());
|
|
123
|
+
const cacheFile = path.join(commonGitDir, 'harness-warm-lockfile.sha256');
|
|
124
|
+
const lockPath = path.join(commonGitDir, 'harness-warm-lockfile.lock');
|
|
125
|
+
return withFileLock(lockPath, async () => {
|
|
126
|
+
const cachedHash = await readFile(cacheFile, 'utf8').catch(() => null);
|
|
127
|
+
if (cachedHash === null) {
|
|
128
|
+
await writeFileAtomic(cacheFile, hostHash, { encoding: 'utf8' });
|
|
129
|
+
return wtHash === hostHash;
|
|
130
|
+
}
|
|
131
|
+
return wtHash === cachedHash.trim() && wtHash === hostHash;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Executes a single setup command AST node (`node:command` or `harness:command`) inside `worktreePath`.
|
|
136
|
+
*
|
|
137
|
+
* Spawns `argv` with the isolated worktree Git environment when `cmdNode` is a `LocalCommandNode`.
|
|
138
|
+
*
|
|
139
|
+
* @param {ASTNode} cmdNode - Setup command AST node from `GitCowWorktreeNode.setupCommands`.
|
|
140
|
+
* @param {string} worktreePath - Target root worktree path.
|
|
141
|
+
*
|
|
142
|
+
* @returns {Promise<void>} Resolves once the setup command finishes with exit code `0`.
|
|
143
|
+
*
|
|
144
|
+
* @throws {Error} If the setup command exits with a non-zero status code.
|
|
145
|
+
*/
|
|
146
|
+
export async function executeSetupCommandNode(cmdNode, worktreePath) {
|
|
147
|
+
if (!('argv' in cmdNode))
|
|
148
|
+
return;
|
|
149
|
+
const rawArgv = typeof cmdNode.argv === 'function' ? cmdNode.argv(undefined) : cmdNode.argv;
|
|
150
|
+
if (!Array.isArray(rawArgv) || rawArgv.length === 0)
|
|
151
|
+
return;
|
|
152
|
+
const argv = rawArgv.map(String);
|
|
153
|
+
const bin = argv[0];
|
|
154
|
+
if (bin === undefined)
|
|
155
|
+
return;
|
|
156
|
+
const env = buildIsolatedWorktreeGitEnv(worktreePath);
|
|
157
|
+
await new Promise((resolve, reject) => {
|
|
158
|
+
const child = spawn(bin, argv.slice(1), { cwd: worktreePath, env, stdio: 'pipe' });
|
|
159
|
+
const stderrChunks = [];
|
|
160
|
+
child.stderr.on('data', (chunk) => {
|
|
161
|
+
stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk), 'utf8'));
|
|
162
|
+
});
|
|
163
|
+
child.on('error', reject);
|
|
164
|
+
child.on('close', (code) => {
|
|
165
|
+
const stderrText = Buffer.concat(stderrChunks).toString('utf8').trim();
|
|
166
|
+
if ((code ?? 1) !== 0)
|
|
167
|
+
reject(new Error(`Worktree setup command '${argv.join(' ')}' failed (exit ${code ?? 1}): ${stderrText}`));
|
|
168
|
+
else
|
|
169
|
+
resolve();
|
|
170
|
+
});
|
|
171
|
+
child.stdin.end();
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=cow-worktree-hydrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cow-worktree-hydrator.js","sourceRoot":"","sources":["../../../src/executors/internal/cow-worktree-hydrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computes the `${mode}:${sha256}` digest for a worktree path using `lstat(2)` and `readlink(2)` / `readFile(2)`.
|
|
3
|
+
*
|
|
4
|
+
* Returns `'DELETED'` when the path does not exist on disk (`ENOENT`), and hashes symlink target strings
|
|
5
|
+
* without dereferencing broken or external symlinks.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} fullPath - Absolute filesystem path to inspect.
|
|
8
|
+
*
|
|
9
|
+
* @returns {Promise<string>} Formatted `${mode}:${sha256}` digest string or `'DELETED'`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function computePathModeAndSha256(fullPath: string): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Compiles a reusable predicate testing whether a repository-relative path should be excluded from checkpoints/clones.
|
|
14
|
+
*
|
|
15
|
+
* Always returns `false` for `.gitignore` and `**\/.gitignore` so gitignore tampering is never masked.
|
|
16
|
+
*
|
|
17
|
+
* @param {readonly string[] | undefined} excludeGlobs - Configured glob patterns to exclude.
|
|
18
|
+
*
|
|
19
|
+
* @returns {(relPath: string) => boolean} Synchronous path exclusion predicate.
|
|
20
|
+
*/
|
|
21
|
+
export declare function compileWorktreeExcludeMatcher(excludeGlobs: readonly string[] | undefined): (relPath: string) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Computes a structural SHA-256 digest of `<worktreePath>/node_modules`.
|
|
24
|
+
*
|
|
25
|
+
* Walks regular files and symlinks inside `node_modules` (excluding top-level and nested `.cache`, `.vite`, and `.vitest`)
|
|
26
|
+
* so `diffEffects` and `restoreCheckpoint` can detect `node_modules` tampering without performing backup I/O.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} worktreePath - Worktree root directory path.
|
|
29
|
+
*
|
|
30
|
+
* @returns {Promise<string>} Hex SHA-256 digest of the `node_modules` tree, or `'ABSENT'` when not present.
|
|
31
|
+
*/
|
|
32
|
+
export declare function computeNodeModulesDigest(worktreePath: string): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Mirrors `<worktreePath>/node_modules` into `<backupRootDir>/<digest>` via Copy-on-Write if not already backed up.
|
|
35
|
+
*
|
|
36
|
+
* Skips transient `.cache`, `.vite`, and `.vitest` subdirectories and short-circuits when `digest === 'ABSENT'`
|
|
37
|
+
* or `<backupRootDir>/<digest>` already exists on disk.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} worktreePath - Worktree root directory path.
|
|
40
|
+
* @param {string} digest - Precomputed structural SHA-256 digest of `node_modules`.
|
|
41
|
+
* @param {string} backupRootDir - `<gitdir>/harness-ckpt-nm` backup root directory.
|
|
42
|
+
*
|
|
43
|
+
* @returns {Promise<void>} Resolves once the content-addressed backup directory is populated.
|
|
44
|
+
*/
|
|
45
|
+
export declare function snapshotNodeModulesForCheckpoint(worktreePath: string, digest: string, backupRootDir: string): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Copies a single file or symbolic link using Copy-on-Write (`COPYFILE_FICLONE`) when supported, falling back to value copy.
|
|
48
|
+
*
|
|
49
|
+
* Preserves symbolic links via `readlink` + `symlink` and applies POSIX file permission bits (`mode`) for regular files.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} srcPath - Source file or symlink path.
|
|
52
|
+
* @param {string} destPath - Destination file or symlink path.
|
|
53
|
+
* @param {number} [mode] - Optional POSIX permission mode to apply.
|
|
54
|
+
*
|
|
55
|
+
* @returns {Promise<void>} Resolves once the file or symlink is copied.
|
|
56
|
+
*/
|
|
57
|
+
export declare function copyFileCowOrValue(srcPath: string, destPath: string, mode?: number): Promise<void>;
|
|
58
|
+
//# sourceMappingURL=file-digest-and-globs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-digest-and-globs.d.ts","sourceRoot":"","sources":["../../../src/executors/internal/file-digest-and-globs.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBhF;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAC3C,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAC1C,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAqB9B;AAsBD;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gCAAgC,CACpD,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|