@ricsam/r5d-worker 0.0.82 → 0.0.83
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/cjs/main.cjs +422 -30
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/workspace-git-sync.cjs +69 -1
- package/dist/mjs/main.mjs +425 -31
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/workspace-git-sync.mjs +67 -1
- package/dist/types/main.d.ts +332 -0
- package/dist/types/workspace-git-sync.d.ts +28 -0
- package/package.json +1 -1
package/dist/cjs/package.json
CHANGED
|
@@ -34,6 +34,8 @@ __export(workspace_git_sync_exports, {
|
|
|
34
34
|
WORKSPACE_GIT_CONFIRMED_LARGE_DIFF_PUSH_OPTION: () => WORKSPACE_GIT_CONFIRMED_LARGE_DIFF_PUSH_OPTION,
|
|
35
35
|
WORKSPACE_GIT_HYDRATED_RECEIPT: () => WORKSPACE_GIT_HYDRATED_RECEIPT,
|
|
36
36
|
WORKSPACE_GIT_HYDRATION_TRANSACTION: () => WORKSPACE_GIT_HYDRATION_TRANSACTION,
|
|
37
|
+
WorkspaceRemediationAncestryError: () => WorkspaceRemediationAncestryError,
|
|
38
|
+
configureExistingWorkspaceGitForRemediation: () => configureExistingWorkspaceGitForRemediation,
|
|
37
39
|
ensureWorkspaceGitClone: () => ensureWorkspaceGitClone,
|
|
38
40
|
hydrateWorkspaceGitMounts: () => hydrateWorkspaceGitMounts,
|
|
39
41
|
recoverWorkspaceGitHydration: () => recoverWorkspaceGitHydration,
|
|
@@ -56,6 +58,12 @@ const WORKSPACE_GIT_INTEGRATED_REF = "refs/r5d/workspace-local/integrated";
|
|
|
56
58
|
const WORKSPACE_GIT_HYDRATED_RECEIPT = "r5d/workspace-hydrated-head";
|
|
57
59
|
const WORKSPACE_GIT_HYDRATION_TRANSACTION = "r5d/workspace-hydration-transaction";
|
|
58
60
|
const WORKSPACE_GIT_CHECKOUT_DURABILITY = "r5d/workspace-checkout-durability";
|
|
61
|
+
class WorkspaceRemediationAncestryError extends Error {
|
|
62
|
+
constructor(message) {
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = "WorkspaceRemediationAncestryError";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
59
67
|
const NON_RECURSIVE_GIT_CONFIG = [
|
|
60
68
|
"-c",
|
|
61
69
|
"submodule.recurse=false",
|
|
@@ -95,6 +103,29 @@ function revParse(workspacePath, revision) {
|
|
|
95
103
|
const result = gitResult(workspacePath, ["rev-parse", "--verify", revision]);
|
|
96
104
|
return result.exitCode === 0 ? result.stdout : null;
|
|
97
105
|
}
|
|
106
|
+
function requiredWorkspaceAncestorHeads(value) {
|
|
107
|
+
if (value === void 0) return [];
|
|
108
|
+
if (!Array.isArray(value) || value.length === 0 || value.some((head) => typeof head !== "string" || !/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(head)) || new Set(value).size !== value.length) {
|
|
109
|
+
throw new WorkspaceRemediationAncestryError("Workspace remediation ancestor requirements are invalid");
|
|
110
|
+
}
|
|
111
|
+
return [...value];
|
|
112
|
+
}
|
|
113
|
+
function assertWorkspaceRemediationAncestry(input) {
|
|
114
|
+
if (input.requiredAncestorHeads.length === 0) return;
|
|
115
|
+
if (!input.currentHead) throw new WorkspaceRemediationAncestryError("Workspace remediation has no resolved HEAD to verify");
|
|
116
|
+
for (const requiredHead of input.requiredAncestorHeads) {
|
|
117
|
+
if (!tryGit(input.workspacePath, ["cat-file", "-e", `${requiredHead}^{commit}`]) || !tryGit(input.workspacePath, ["merge-base", "--is-ancestor", requiredHead, input.currentHead])) {
|
|
118
|
+
throw new WorkspaceRemediationAncestryError(
|
|
119
|
+
`Workspace remediation HEAD does not descend from required conflict commit ${requiredHead}`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (!input.remoteHead || !tryGit(input.workspacePath, ["cat-file", "-e", `${input.remoteHead}^{commit}`]) || !tryGit(input.workspacePath, ["merge-base", "--is-ancestor", input.remoteHead, input.currentHead])) {
|
|
124
|
+
throw new WorkspaceRemediationAncestryError(
|
|
125
|
+
"Fetched workspace head is not an ancestor of the resolved remediation HEAD; merge it explicitly before synchronizing"
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
98
129
|
function updateIntegratedWorkspaceHead(workspacePath, head) {
|
|
99
130
|
git(workspacePath, ["update-ref", WORKSPACE_GIT_INTEGRATED_REF, head], "record integrated workspace head");
|
|
100
131
|
}
|
|
@@ -964,6 +995,15 @@ function configureWorkspaceRepository(input) {
|
|
|
964
995
|
);
|
|
965
996
|
git(input.workspacePath, ["config", "--local", "core.fsyncMethod", "fsync"], "configure workspace fsync method");
|
|
966
997
|
}
|
|
998
|
+
function configureExistingWorkspaceGitForRemediation(input) {
|
|
999
|
+
const workspacePath = import_node_path.default.resolve(input.workspacePath);
|
|
1000
|
+
const workspaceStatus = lstatIfExists(workspacePath);
|
|
1001
|
+
const gitStatus = lstatIfExists(import_node_path.default.join(workspacePath, ".git"));
|
|
1002
|
+
if (!workspaceStatus?.isDirectory() || workspaceStatus.isSymbolicLink() || !gitStatus?.isDirectory() || gitStatus.isSymbolicLink()) {
|
|
1003
|
+
throw new Error("Active workspace remediation requires a regular existing canonical synchronization checkout");
|
|
1004
|
+
}
|
|
1005
|
+
configureWorkspaceRepository({ ...input, workspacePath });
|
|
1006
|
+
}
|
|
967
1007
|
function fetchWorkspaceHead(workspacePath, remoteUrl, credentialHelper, credentialUsername) {
|
|
968
1008
|
const result = gitResult(workspacePath, [
|
|
969
1009
|
...(0, import_git_process_environment.gitTransportSecurityArgs)(remoteUrl, credentialHelper, credentialUsername),
|
|
@@ -1465,8 +1505,16 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
1465
1505
|
const maxDiffBytes = input.maxDiffBytes ?? MAX_WORKSPACE_GIT_DIFF_BYTES;
|
|
1466
1506
|
const maxPushAttempts = Math.max(1, input.maxPushAttempts ?? 4);
|
|
1467
1507
|
validateMounts(workspacePath, input.mounts);
|
|
1508
|
+
const requiredAncestorHeads = requiredWorkspaceAncestorHeads(input.requiredAncestorHeads);
|
|
1468
1509
|
const preserveResolutionInProgress = input.skipMountMirror === true;
|
|
1469
1510
|
const initial = ensureWorkspaceGitClone({ ...input, workspacePath, preserveResolutionInProgress });
|
|
1511
|
+
assertWorkspaceRemediationAncestry({
|
|
1512
|
+
workspacePath,
|
|
1513
|
+
currentHead: initial.localHead,
|
|
1514
|
+
remoteHead: initial.remoteHead,
|
|
1515
|
+
requiredAncestorHeads
|
|
1516
|
+
});
|
|
1517
|
+
const verifiedAncestorHeads = requiredAncestorHeads.length > 0 ? requiredAncestorHeads : void 0;
|
|
1470
1518
|
const startingHead = initial.localHead;
|
|
1471
1519
|
const receiptBeforeInitialHydration = readHydratedWorkspaceReceipt(workspacePath);
|
|
1472
1520
|
const deferredMountIds = /* @__PURE__ */ new Set();
|
|
@@ -1558,6 +1606,7 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
1558
1606
|
conflictPaths: merged.conflictPaths,
|
|
1559
1607
|
conflictSnapshotRefs: refs,
|
|
1560
1608
|
conflictKind: "projection_merge",
|
|
1609
|
+
...verifiedAncestorHeads ? { verifiedAncestorHeads } : {},
|
|
1561
1610
|
error: merged.error
|
|
1562
1611
|
};
|
|
1563
1612
|
}
|
|
@@ -1681,6 +1730,12 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
1681
1730
|
let rebaseCount = 0;
|
|
1682
1731
|
let updated = false;
|
|
1683
1732
|
for (let pushAttempt = 0; pushAttempt < maxPushAttempts; pushAttempt += 1) {
|
|
1733
|
+
assertWorkspaceRemediationAncestry({
|
|
1734
|
+
workspacePath,
|
|
1735
|
+
currentHead: revParse(workspacePath, "HEAD"),
|
|
1736
|
+
remoteHead,
|
|
1737
|
+
requiredAncestorHeads
|
|
1738
|
+
});
|
|
1684
1739
|
const reconciled = synchronizeWithFetchedHead({ workspacePath, remoteHead, attemptId });
|
|
1685
1740
|
if (reconciled.kind === "conflict") {
|
|
1686
1741
|
const localHead2 = revParse(workspacePath, "HEAD");
|
|
@@ -1698,6 +1753,7 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
1698
1753
|
conflictPaths: reconciled.conflictPaths,
|
|
1699
1754
|
conflictSnapshotRefs: reconciled.refs,
|
|
1700
1755
|
conflictKind: "integration_rebase",
|
|
1756
|
+
...verifiedAncestorHeads ? { verifiedAncestorHeads } : {},
|
|
1701
1757
|
error: reconciled.error
|
|
1702
1758
|
};
|
|
1703
1759
|
}
|
|
@@ -1717,11 +1773,13 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
1717
1773
|
diffSizeBytes: 0,
|
|
1718
1774
|
affectedPaths: [],
|
|
1719
1775
|
...classifiedMounts,
|
|
1776
|
+
...verifiedAncestorHeads ? { verifiedAncestorHeads } : {},
|
|
1720
1777
|
...projectionWarning ? { error: projectionWarning } : {}
|
|
1721
1778
|
};
|
|
1722
1779
|
}
|
|
1723
1780
|
const paths = changedPaths(workspacePath, remoteHead, localHead);
|
|
1724
|
-
const size = paths.length > 0 ? await diffSizeBytes(workspacePath, remoteHead, localHead, maxDiffBytes) : 0;
|
|
1781
|
+
const size = paths.length > 0 ? await (input.measureDiffSize ?? diffSizeBytes)(workspacePath, remoteHead, localHead, maxDiffBytes) : 0;
|
|
1782
|
+
input.assertStillAdmitted?.();
|
|
1725
1783
|
if (paths.length > 0 && size > maxDiffBytes && !input.allowLargeDiff) {
|
|
1726
1784
|
const classifiedMounts = classifyMounts([...selected.active, ...selected.tombstones]);
|
|
1727
1785
|
return {
|
|
@@ -1734,15 +1792,18 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
1734
1792
|
diffSizeBytes: size,
|
|
1735
1793
|
affectedPaths: paths,
|
|
1736
1794
|
...classifiedMounts,
|
|
1795
|
+
...verifiedAncestorHeads ? { verifiedAncestorHeads } : {},
|
|
1737
1796
|
error: `Workspace diff exceeds the ${maxDiffBytes}-byte automatic publication limit`
|
|
1738
1797
|
};
|
|
1739
1798
|
}
|
|
1740
1799
|
if (localHead === remoteHead) {
|
|
1800
|
+
assertWorkspaceRemediationAncestry({ workspacePath, currentHead: localHead, remoteHead, requiredAncestorHeads });
|
|
1741
1801
|
const completedMounts = completedMountSelection(Boolean(input.skipMountMirror));
|
|
1742
1802
|
await input.afterWorkspacePublished?.({
|
|
1743
1803
|
publishedHead: localHead,
|
|
1744
1804
|
activeMountIds: completedMounts.activeMountIds
|
|
1745
1805
|
});
|
|
1806
|
+
input.assertStillAdmitted?.();
|
|
1746
1807
|
return {
|
|
1747
1808
|
outcome: updated ? "updated" : "no_change",
|
|
1748
1809
|
startingHead,
|
|
@@ -1753,9 +1814,11 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
1753
1814
|
diffSizeBytes: size,
|
|
1754
1815
|
affectedPaths: paths,
|
|
1755
1816
|
...completedMounts,
|
|
1817
|
+
...verifiedAncestorHeads ? { verifiedAncestorHeads } : {},
|
|
1756
1818
|
...projectionWarning ? { error: projectionWarning } : {}
|
|
1757
1819
|
};
|
|
1758
1820
|
}
|
|
1821
|
+
assertWorkspaceRemediationAncestry({ workspacePath, currentHead: localHead, remoteHead, requiredAncestorHeads });
|
|
1759
1822
|
const pushArgs = [
|
|
1760
1823
|
...(0, import_git_process_environment.gitTransportSecurityArgs)(input.remoteUrl, input.credentialHelper, input.credentialUsername),
|
|
1761
1824
|
"push",
|
|
@@ -1765,12 +1828,14 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
1765
1828
|
pushArgs.push("origin", `HEAD:refs/heads/${WORKSPACE_GIT_BRANCH}`);
|
|
1766
1829
|
const push = gitResult(workspacePath, pushArgs);
|
|
1767
1830
|
if (push.exitCode === 0) {
|
|
1831
|
+
assertWorkspaceRemediationAncestry({ workspacePath, currentHead: localHead, remoteHead, requiredAncestorHeads });
|
|
1768
1832
|
updateIntegratedWorkspaceHead(workspacePath, localHead);
|
|
1769
1833
|
const completedMounts = completedMountSelection(Boolean(input.skipMountMirror));
|
|
1770
1834
|
await input.afterWorkspacePublished?.({
|
|
1771
1835
|
publishedHead: localHead,
|
|
1772
1836
|
activeMountIds: completedMounts.activeMountIds
|
|
1773
1837
|
});
|
|
1838
|
+
input.assertStillAdmitted?.();
|
|
1774
1839
|
return {
|
|
1775
1840
|
outcome: "pushed",
|
|
1776
1841
|
startingHead,
|
|
@@ -1781,6 +1846,7 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
1781
1846
|
diffSizeBytes: size,
|
|
1782
1847
|
affectedPaths: paths,
|
|
1783
1848
|
...completedMounts,
|
|
1849
|
+
...verifiedAncestorHeads ? { verifiedAncestorHeads } : {},
|
|
1784
1850
|
...projectionWarning ? { error: projectionWarning } : {}
|
|
1785
1851
|
};
|
|
1786
1852
|
}
|
|
@@ -1807,6 +1873,8 @@ const workspaceGitSyncTestHarness = {
|
|
|
1807
1873
|
WORKSPACE_GIT_CONFIRMED_LARGE_DIFF_PUSH_OPTION,
|
|
1808
1874
|
WORKSPACE_GIT_HYDRATED_RECEIPT,
|
|
1809
1875
|
WORKSPACE_GIT_HYDRATION_TRANSACTION,
|
|
1876
|
+
WorkspaceRemediationAncestryError,
|
|
1877
|
+
configureExistingWorkspaceGitForRemediation,
|
|
1810
1878
|
ensureWorkspaceGitClone,
|
|
1811
1879
|
hydrateWorkspaceGitMounts,
|
|
1812
1880
|
recoverWorkspaceGitHydration,
|