@fern-api/replay 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +16642 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/index.cjs +2014 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +463 -0
- package/dist/index.d.ts +463 -12
- package/dist/index.js +1968 -10
- package/dist/index.js.map +1 -1
- package/package.json +16 -6
- package/dist/FernignoreMigrator.d.ts +0 -38
- package/dist/FernignoreMigrator.d.ts.map +0 -1
- package/dist/FernignoreMigrator.js +0 -210
- package/dist/FernignoreMigrator.js.map +0 -1
- package/dist/LockfileManager.d.ts +0 -31
- package/dist/LockfileManager.d.ts.map +0 -1
- package/dist/LockfileManager.js +0 -124
- package/dist/LockfileManager.js.map +0 -1
- package/dist/ReplayApplicator.d.ts +0 -30
- package/dist/ReplayApplicator.d.ts.map +0 -1
- package/dist/ReplayApplicator.js +0 -544
- package/dist/ReplayApplicator.js.map +0 -1
- package/dist/ReplayCommitter.d.ts +0 -19
- package/dist/ReplayCommitter.d.ts.map +0 -1
- package/dist/ReplayCommitter.js +0 -64
- package/dist/ReplayCommitter.js.map +0 -1
- package/dist/ReplayDetector.d.ts +0 -22
- package/dist/ReplayDetector.d.ts.map +0 -1
- package/dist/ReplayDetector.js +0 -147
- package/dist/ReplayDetector.js.map +0 -1
- package/dist/ReplayService.d.ts +0 -100
- package/dist/ReplayService.d.ts.map +0 -1
- package/dist/ReplayService.js +0 -596
- package/dist/ReplayService.js.map +0 -1
- package/dist/ThreeWayMerge.d.ts +0 -11
- package/dist/ThreeWayMerge.d.ts.map +0 -1
- package/dist/ThreeWayMerge.js +0 -48
- package/dist/ThreeWayMerge.js.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -462
- package/dist/cli.js.map +0 -1
- package/dist/commands/bootstrap.d.ts +0 -46
- package/dist/commands/bootstrap.d.ts.map +0 -1
- package/dist/commands/bootstrap.js +0 -237
- package/dist/commands/bootstrap.js.map +0 -1
- package/dist/commands/forget.d.ts +0 -16
- package/dist/commands/forget.d.ts.map +0 -1
- package/dist/commands/forget.js +0 -27
- package/dist/commands/forget.js.map +0 -1
- package/dist/commands/index.d.ts +0 -6
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js +0 -6
- package/dist/commands/index.js.map +0 -1
- package/dist/commands/reset.d.ts +0 -16
- package/dist/commands/reset.d.ts.map +0 -1
- package/dist/commands/reset.js +0 -25
- package/dist/commands/reset.js.map +0 -1
- package/dist/commands/resolve.d.ts +0 -16
- package/dist/commands/resolve.d.ts.map +0 -1
- package/dist/commands/resolve.js +0 -28
- package/dist/commands/resolve.js.map +0 -1
- package/dist/commands/status.d.ts +0 -26
- package/dist/commands/status.d.ts.map +0 -1
- package/dist/commands/status.js +0 -24
- package/dist/commands/status.js.map +0 -1
- package/dist/git/CommitDetection.d.ts +0 -7
- package/dist/git/CommitDetection.d.ts.map +0 -1
- package/dist/git/CommitDetection.js +0 -26
- package/dist/git/CommitDetection.js.map +0 -1
- package/dist/git/GitClient.d.ts +0 -22
- package/dist/git/GitClient.d.ts.map +0 -1
- package/dist/git/GitClient.js +0 -109
- package/dist/git/GitClient.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/types.d.ts +0 -80
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
package/dist/ReplayApplicator.js
DELETED
|
@@ -1,544 +0,0 @@
|
|
|
1
|
-
import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
|
-
import { tmpdir } from "node:os";
|
|
3
|
-
import { dirname, extname, join } from "node:path";
|
|
4
|
-
import { minimatch } from "minimatch";
|
|
5
|
-
import { threeWayMerge } from "./ThreeWayMerge.js";
|
|
6
|
-
const BINARY_EXTENSIONS = new Set([
|
|
7
|
-
".png",
|
|
8
|
-
".jpg",
|
|
9
|
-
".jpeg",
|
|
10
|
-
".gif",
|
|
11
|
-
".bmp",
|
|
12
|
-
".ico",
|
|
13
|
-
".webp",
|
|
14
|
-
".svg",
|
|
15
|
-
".pdf",
|
|
16
|
-
".doc",
|
|
17
|
-
".docx",
|
|
18
|
-
".xls",
|
|
19
|
-
".xlsx",
|
|
20
|
-
".ppt",
|
|
21
|
-
".pptx",
|
|
22
|
-
".zip",
|
|
23
|
-
".gz",
|
|
24
|
-
".tar",
|
|
25
|
-
".bz2",
|
|
26
|
-
".7z",
|
|
27
|
-
".rar",
|
|
28
|
-
".jar",
|
|
29
|
-
".war",
|
|
30
|
-
".ear",
|
|
31
|
-
".class",
|
|
32
|
-
".exe",
|
|
33
|
-
".dll",
|
|
34
|
-
".so",
|
|
35
|
-
".dylib",
|
|
36
|
-
".o",
|
|
37
|
-
".a",
|
|
38
|
-
".woff",
|
|
39
|
-
".woff2",
|
|
40
|
-
".ttf",
|
|
41
|
-
".eot",
|
|
42
|
-
".otf",
|
|
43
|
-
".mp3",
|
|
44
|
-
".mp4",
|
|
45
|
-
".avi",
|
|
46
|
-
".mov",
|
|
47
|
-
".wav",
|
|
48
|
-
".flac",
|
|
49
|
-
".sqlite",
|
|
50
|
-
".db",
|
|
51
|
-
".pyc",
|
|
52
|
-
".pyo",
|
|
53
|
-
".DS_Store"
|
|
54
|
-
]);
|
|
55
|
-
export class ReplayApplicator {
|
|
56
|
-
git;
|
|
57
|
-
lockManager;
|
|
58
|
-
outputDir;
|
|
59
|
-
renameCache = new Map();
|
|
60
|
-
fileTheirsAccumulator = new Map();
|
|
61
|
-
constructor(git, lockManager, outputDir) {
|
|
62
|
-
this.git = git;
|
|
63
|
-
this.lockManager = lockManager;
|
|
64
|
-
this.outputDir = outputDir;
|
|
65
|
-
}
|
|
66
|
-
/** Reset inter-patch accumulator for a new cycle. */
|
|
67
|
-
resetAccumulator() {
|
|
68
|
-
this.fileTheirsAccumulator.clear();
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Apply all patches, returning results for each.
|
|
72
|
-
* Skips patches that match exclude patterns in replay.yml
|
|
73
|
-
*/
|
|
74
|
-
async applyPatches(patches) {
|
|
75
|
-
this.resetAccumulator(); // Clear accumulator for this apply cycle
|
|
76
|
-
const results = [];
|
|
77
|
-
for (const patch of patches) {
|
|
78
|
-
if (this.isExcluded(patch)) {
|
|
79
|
-
results.push({
|
|
80
|
-
patch,
|
|
81
|
-
status: "skipped",
|
|
82
|
-
method: "git-am"
|
|
83
|
-
});
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
const result = await this.applyPatchWithFallback(patch);
|
|
87
|
-
results.push(result);
|
|
88
|
-
}
|
|
89
|
-
return results;
|
|
90
|
-
}
|
|
91
|
-
/** Populate accumulator after git apply succeeds. */
|
|
92
|
-
async populateAccumulatorForPatch(patch, baseGen, currentTreeHash) {
|
|
93
|
-
if (!baseGen)
|
|
94
|
-
return;
|
|
95
|
-
// Create temp git repo to apply patches to base content
|
|
96
|
-
const tempDir = await mkdtemp(join(tmpdir(), "replay-acc-"));
|
|
97
|
-
const { GitClient } = await import("./git/GitClient.js");
|
|
98
|
-
const tempGit = new GitClient(tempDir);
|
|
99
|
-
await tempGit.exec(["init"]);
|
|
100
|
-
await tempGit.exec(["config", "user.email", "replay@fern.com"]);
|
|
101
|
-
await tempGit.exec(["config", "user.name", "Fern Replay"]);
|
|
102
|
-
try {
|
|
103
|
-
for (const filePath of patch.files) {
|
|
104
|
-
if (isBinaryFile(filePath))
|
|
105
|
-
continue;
|
|
106
|
-
const resolvedPath = await this.resolveFilePath(filePath, baseGen.tree_hash, currentTreeHash);
|
|
107
|
-
const base = await this.git.showFile(baseGen.tree_hash, filePath);
|
|
108
|
-
const theirs = await this.applyPatchToContent(base, patch.patch_content, filePath, tempGit, tempDir);
|
|
109
|
-
if (theirs && base) {
|
|
110
|
-
this.fileTheirsAccumulator.set(resolvedPath, {
|
|
111
|
-
content: theirs,
|
|
112
|
-
baseGeneration: patch.base_generation
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
finally {
|
|
118
|
-
await rm(tempDir, { recursive: true }).catch(() => { });
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
async applyPatchWithFallback(patch) {
|
|
122
|
-
// Resolve all file paths to check accumulator (need baseGen for resolution)
|
|
123
|
-
const baseGen = this.lockManager.getGeneration(patch.base_generation);
|
|
124
|
-
const lock = this.lockManager.read();
|
|
125
|
-
const currentGen = lock.generations.find((g) => g.commit_sha === lock.current_generation);
|
|
126
|
-
const currentTreeHash = currentGen?.tree_hash ?? baseGen?.tree_hash ?? "";
|
|
127
|
-
// Check if any file in this patch needs accumulation
|
|
128
|
-
// If so, skip fast path to ensure we benefit from pre-merge logic
|
|
129
|
-
const needsAccumulation = await Promise.all(patch.files.map(async (f) => {
|
|
130
|
-
if (!baseGen)
|
|
131
|
-
return false;
|
|
132
|
-
const resolved = await this.resolveFilePath(f, baseGen.tree_hash, currentTreeHash);
|
|
133
|
-
return this.fileTheirsAccumulator.has(resolved);
|
|
134
|
-
})).then((results) => results.some(Boolean));
|
|
135
|
-
// Strategy 1: Try git apply --3way (skip if accumulation needed)
|
|
136
|
-
if (!needsAccumulation) {
|
|
137
|
-
// Snapshot files before git apply (may leave conflict markers on failure)
|
|
138
|
-
const snapshots = new Map();
|
|
139
|
-
const resolvedFiles = {};
|
|
140
|
-
for (const filePath of patch.files) {
|
|
141
|
-
const resolvedPath = baseGen
|
|
142
|
-
? await this.resolveFilePath(filePath, baseGen.tree_hash, currentTreeHash)
|
|
143
|
-
: filePath;
|
|
144
|
-
if (resolvedPath !== filePath) {
|
|
145
|
-
resolvedFiles[filePath] = resolvedPath;
|
|
146
|
-
}
|
|
147
|
-
const fullPath = join(this.outputDir, resolvedPath);
|
|
148
|
-
snapshots.set(resolvedPath, await readFile(fullPath, "utf-8").catch(() => null));
|
|
149
|
-
}
|
|
150
|
-
try {
|
|
151
|
-
await this.git.execWithInput(["apply", "--3way"], patch.patch_content);
|
|
152
|
-
// Success! Populate accumulator so subsequent patches on these files
|
|
153
|
-
// will skip fast path and use the pre-merge logic instead
|
|
154
|
-
await this.populateAccumulatorForPatch(patch, baseGen, currentTreeHash);
|
|
155
|
-
return {
|
|
156
|
-
patch,
|
|
157
|
-
status: "applied",
|
|
158
|
-
method: "git-am",
|
|
159
|
-
...(Object.keys(resolvedFiles).length > 0 && { resolvedFiles })
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
163
|
-
// git apply --3way failed and may have left conflict markers on disk
|
|
164
|
-
// Restore files from snapshot to undo any corruption before fallback
|
|
165
|
-
for (const [resolvedPath, content] of snapshots) {
|
|
166
|
-
if (content != null) {
|
|
167
|
-
await writeFile(join(this.outputDir, resolvedPath), content);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
// Strategy 2: Fall back to file-by-file 3-way merge (uses accumulator)
|
|
173
|
-
return this.applyWithThreeWayMerge(patch);
|
|
174
|
-
}
|
|
175
|
-
async applyWithThreeWayMerge(patch) {
|
|
176
|
-
const fileResults = [];
|
|
177
|
-
const resolvedFiles = {};
|
|
178
|
-
const tempDir = await mkdtemp(join(tmpdir(), "replay-"));
|
|
179
|
-
const { GitClient } = await import("./git/GitClient.js");
|
|
180
|
-
const tempGit = new GitClient(tempDir);
|
|
181
|
-
await tempGit.exec(["init"]);
|
|
182
|
-
await tempGit.exec(["config", "user.email", "replay@fern.com"]);
|
|
183
|
-
await tempGit.exec(["config", "user.name", "Fern Replay"]);
|
|
184
|
-
try {
|
|
185
|
-
for (const filePath of patch.files) {
|
|
186
|
-
if (isBinaryFile(filePath)) {
|
|
187
|
-
fileResults.push({
|
|
188
|
-
file: filePath,
|
|
189
|
-
status: "skipped",
|
|
190
|
-
reason: "binary-file"
|
|
191
|
-
});
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
const result = await this.mergeFile(patch, filePath, tempGit, tempDir);
|
|
195
|
-
if (result.file !== filePath) {
|
|
196
|
-
resolvedFiles[filePath] = result.file;
|
|
197
|
-
}
|
|
198
|
-
fileResults.push(result);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
finally {
|
|
202
|
-
await rm(tempDir, { recursive: true }).catch(() => { });
|
|
203
|
-
}
|
|
204
|
-
const conflictFiles = fileResults.filter((r) => r.status === "conflict");
|
|
205
|
-
const hasConflicts = conflictFiles.length > 0;
|
|
206
|
-
// Aggregate conflict reason from file-level to patch-level
|
|
207
|
-
const conflictReason = hasConflicts
|
|
208
|
-
? conflictFiles.some((f) => f.conflictReason === "base-generation-mismatch")
|
|
209
|
-
? "base-generation-mismatch"
|
|
210
|
-
: conflictFiles[0]?.conflictReason
|
|
211
|
-
: undefined;
|
|
212
|
-
return {
|
|
213
|
-
patch,
|
|
214
|
-
status: hasConflicts ? "conflict" : "applied",
|
|
215
|
-
method: "3way-merge",
|
|
216
|
-
fileResults,
|
|
217
|
-
conflictReason,
|
|
218
|
-
...(Object.keys(resolvedFiles).length > 0 && { resolvedFiles })
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
async mergeFile(patch, filePath, tempGit, tempDir) {
|
|
222
|
-
try {
|
|
223
|
-
const baseGen = this.lockManager.getGeneration(patch.base_generation);
|
|
224
|
-
if (!baseGen) {
|
|
225
|
-
return { file: filePath, status: "skipped", reason: "base-generation-not-found" };
|
|
226
|
-
}
|
|
227
|
-
// Resolve file path in case the generator renamed it between generations
|
|
228
|
-
const lock = this.lockManager.read();
|
|
229
|
-
const currentGen = lock.generations.find((g) => g.commit_sha === lock.current_generation);
|
|
230
|
-
const currentTreeHash = currentGen?.tree_hash ?? baseGen.tree_hash;
|
|
231
|
-
const resolvedPath = await this.resolveFilePath(filePath, baseGen.tree_hash, currentTreeHash);
|
|
232
|
-
// Build conflict metadata for this file (used if conflict occurs)
|
|
233
|
-
const metadata = {
|
|
234
|
-
patchId: patch.id,
|
|
235
|
-
patchMessage: patch.original_message,
|
|
236
|
-
baseGeneration: patch.base_generation,
|
|
237
|
-
currentGeneration: lock.current_generation
|
|
238
|
-
};
|
|
239
|
-
// BASE: pristine state from when user made their edit (old path)
|
|
240
|
-
let base = await this.git.showFile(baseGen.tree_hash, filePath);
|
|
241
|
-
// If BASE is null, check if this file is the target of a rename in the patch.
|
|
242
|
-
// Rename diffs (e.g., git mv old new) have the content at the old path.
|
|
243
|
-
let renameSourcePath;
|
|
244
|
-
if (!base) {
|
|
245
|
-
const renameSource = this.extractRenameSource(patch.patch_content, filePath);
|
|
246
|
-
if (renameSource) {
|
|
247
|
-
base = await this.git.showFile(baseGen.tree_hash, renameSource);
|
|
248
|
-
renameSourcePath = renameSource;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
// OURS: current generated state on disk (resolved/new path)
|
|
252
|
-
const oursPath = join(this.outputDir, resolvedPath);
|
|
253
|
-
const ours = await readFile(oursPath, "utf-8").catch(() => null);
|
|
254
|
-
// THEIRS: user's version (apply patch to base using original path)
|
|
255
|
-
let theirs = await this.applyPatchToContent(base, patch.patch_content, filePath, tempGit, tempDir, renameSourcePath);
|
|
256
|
-
// Fall back to accumulator as merge base for incremental patches.
|
|
257
|
-
let useAccumulatorAsMergeBase = false;
|
|
258
|
-
const accumulatorEntry = this.fileTheirsAccumulator.get(resolvedPath);
|
|
259
|
-
if (!theirs && base && accumulatorEntry) {
|
|
260
|
-
theirs = await this.applyPatchToContent(accumulatorEntry.content, patch.patch_content, filePath, tempGit, tempDir);
|
|
261
|
-
if (theirs) {
|
|
262
|
-
useAccumulatorAsMergeBase = true;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
// Pre-merge with accumulated customizations (skip when accumulator is merge base).
|
|
266
|
-
let effective_theirs = theirs;
|
|
267
|
-
let baseMismatchSkipped = false;
|
|
268
|
-
if (theirs && base && !useAccumulatorAsMergeBase) {
|
|
269
|
-
if (accumulatorEntry && accumulatorEntry.baseGeneration === patch.base_generation) {
|
|
270
|
-
// Pre-merge: combine previous customizations with current patch
|
|
271
|
-
try {
|
|
272
|
-
const preMerged = threeWayMerge(base, accumulatorEntry.content, theirs);
|
|
273
|
-
if (!preMerged.hasConflicts) {
|
|
274
|
-
// Clean merge - use the combined result
|
|
275
|
-
effective_theirs = preMerged.content;
|
|
276
|
-
}
|
|
277
|
-
else {
|
|
278
|
-
// Pre-merge has conflicts - skip accumulator for this patch
|
|
279
|
-
// to avoid nested conflict markers. User patches conflict
|
|
280
|
-
// with each other and require manual resolution.
|
|
281
|
-
effective_theirs = theirs;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
catch {
|
|
285
|
-
// If pre-merge fails unexpectedly, fall back to current_theirs
|
|
286
|
-
effective_theirs = theirs;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
else if (accumulatorEntry) {
|
|
290
|
-
// Base generations differ - accumulator pre-merge skipped.
|
|
291
|
-
// The main merge below will still run, but if it conflicts
|
|
292
|
-
// we flag it as a base-generation-mismatch.
|
|
293
|
-
baseMismatchSkipped = true;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
// Handle new files (user created, didn't exist in generation)
|
|
297
|
-
if (!base && !ours && effective_theirs) {
|
|
298
|
-
const outDir = dirname(oursPath);
|
|
299
|
-
await mkdir(outDir, { recursive: true });
|
|
300
|
-
await writeFile(oursPath, effective_theirs);
|
|
301
|
-
return { file: resolvedPath, status: "merged", reason: "new-file" };
|
|
302
|
-
}
|
|
303
|
-
// Handle new file created by both user and generator (conflict)
|
|
304
|
-
if (!base && ours && effective_theirs) {
|
|
305
|
-
const merged = threeWayMerge("", ours, effective_theirs);
|
|
306
|
-
const outDir = dirname(oursPath);
|
|
307
|
-
await mkdir(outDir, { recursive: true });
|
|
308
|
-
await writeFile(oursPath, merged.content);
|
|
309
|
-
if (merged.hasConflicts) {
|
|
310
|
-
return {
|
|
311
|
-
file: resolvedPath,
|
|
312
|
-
status: "conflict",
|
|
313
|
-
conflicts: merged.conflicts,
|
|
314
|
-
conflictReason: "new-file-both",
|
|
315
|
-
conflictMetadata: metadata
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
return { file: resolvedPath, status: "merged" };
|
|
319
|
-
}
|
|
320
|
-
if (!effective_theirs) {
|
|
321
|
-
return {
|
|
322
|
-
file: resolvedPath,
|
|
323
|
-
status: "skipped",
|
|
324
|
-
reason: "missing-content"
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
if (!base || !ours) {
|
|
328
|
-
return {
|
|
329
|
-
file: resolvedPath,
|
|
330
|
-
status: "skipped",
|
|
331
|
-
reason: "missing-content"
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
// Perform 3-way merge.
|
|
335
|
-
// For incremental patches, use the accumulated state as the merge base
|
|
336
|
-
// so the diff is computed relative to prior patches, not the raw generation.
|
|
337
|
-
const mergeBase = useAccumulatorAsMergeBase && accumulatorEntry ? accumulatorEntry.content : base;
|
|
338
|
-
const merged = threeWayMerge(mergeBase, ours, effective_theirs);
|
|
339
|
-
// Write result to the resolved (current) path
|
|
340
|
-
const outDir = dirname(oursPath);
|
|
341
|
-
await mkdir(outDir, { recursive: true });
|
|
342
|
-
await writeFile(oursPath, merged.content);
|
|
343
|
-
// Update accumulator after successful merge
|
|
344
|
-
// This allows subsequent patches on the same file to benefit from pre-merge
|
|
345
|
-
if (effective_theirs && base) {
|
|
346
|
-
this.fileTheirsAccumulator.set(resolvedPath, {
|
|
347
|
-
content: effective_theirs,
|
|
348
|
-
baseGeneration: patch.base_generation
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
if (merged.hasConflicts) {
|
|
352
|
-
return {
|
|
353
|
-
file: resolvedPath,
|
|
354
|
-
status: "conflict",
|
|
355
|
-
conflicts: merged.conflicts,
|
|
356
|
-
conflictReason: baseMismatchSkipped ? "base-generation-mismatch" : "same-line-edit",
|
|
357
|
-
conflictMetadata: metadata
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
return { file: resolvedPath, status: "merged" };
|
|
361
|
-
}
|
|
362
|
-
catch (error) {
|
|
363
|
-
return {
|
|
364
|
-
file: filePath,
|
|
365
|
-
status: "skipped",
|
|
366
|
-
reason: `error: ${error instanceof Error ? error.message : String(error)}`
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
isExcluded(patch) {
|
|
371
|
-
const config = this.lockManager.getCustomizationsConfig();
|
|
372
|
-
if (!config.exclude)
|
|
373
|
-
return false;
|
|
374
|
-
return patch.files.some((file) => config.exclude.some((pattern) => minimatch(file, pattern)));
|
|
375
|
-
}
|
|
376
|
-
async resolveFilePath(filePath, baseTreeHash, currentTreeHash) {
|
|
377
|
-
// Priority 1: Manual moves from replay.yml
|
|
378
|
-
const config = this.lockManager.getCustomizationsConfig();
|
|
379
|
-
if (config.moves) {
|
|
380
|
-
for (const move of config.moves) {
|
|
381
|
-
if (minimatch(filePath, move.from) || filePath === move.from) {
|
|
382
|
-
// For exact matches, replace directly
|
|
383
|
-
if (filePath === move.from) {
|
|
384
|
-
return move.to;
|
|
385
|
-
}
|
|
386
|
-
// For glob matches, replace the matching prefix
|
|
387
|
-
// e.g., from: "src/api/**" to: "src/resources/**"
|
|
388
|
-
// filePath: "src/api/client.ts" → "src/resources/client.ts"
|
|
389
|
-
const fromBase = move.from.replace(/\*\*.*$/, "");
|
|
390
|
-
const toBase = move.to.replace(/\*\*.*$/, "");
|
|
391
|
-
if (filePath.startsWith(fromBase)) {
|
|
392
|
-
return toBase + filePath.slice(fromBase.length);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
// Priority 2: Git rename detection (cached per tree pair)
|
|
398
|
-
const cacheKey = `${baseTreeHash}:${currentTreeHash}`;
|
|
399
|
-
let renames = this.renameCache.get(cacheKey);
|
|
400
|
-
if (!renames) {
|
|
401
|
-
renames = await this.git.detectRenames(baseTreeHash, currentTreeHash);
|
|
402
|
-
this.renameCache.set(cacheKey, renames);
|
|
403
|
-
}
|
|
404
|
-
const gitRename = renames.find((r) => r.from === filePath);
|
|
405
|
-
if (gitRename) {
|
|
406
|
-
return gitRename.to;
|
|
407
|
-
}
|
|
408
|
-
// Priority 3: No rename detected
|
|
409
|
-
return filePath;
|
|
410
|
-
}
|
|
411
|
-
async applyPatchToContent(base, patchContent, filePath, tempGit, tempDir, sourceFilePath) {
|
|
412
|
-
if (!base) {
|
|
413
|
-
// New file - extract content directly from patch
|
|
414
|
-
return this.extractNewFileFromPatch(patchContent, filePath);
|
|
415
|
-
}
|
|
416
|
-
// Extract only the diff for this specific file
|
|
417
|
-
const fileDiff = this.extractFileDiff(patchContent, filePath);
|
|
418
|
-
if (!fileDiff)
|
|
419
|
-
return null;
|
|
420
|
-
try {
|
|
421
|
-
if (sourceFilePath) {
|
|
422
|
-
// Rename case: write base at the OLD path, apply the rename diff,
|
|
423
|
-
// then read from the NEW path (filePath).
|
|
424
|
-
const tempSourcePath = join(tempDir, sourceFilePath);
|
|
425
|
-
await mkdir(dirname(tempSourcePath), { recursive: true });
|
|
426
|
-
await writeFile(tempSourcePath, base);
|
|
427
|
-
await tempGit.exec(["add", sourceFilePath]);
|
|
428
|
-
await tempGit.exec([
|
|
429
|
-
"commit",
|
|
430
|
-
"-m",
|
|
431
|
-
`base for rename ${sourceFilePath} -> ${filePath}`,
|
|
432
|
-
"--allow-empty"
|
|
433
|
-
]);
|
|
434
|
-
await tempGit.execWithInput(["apply", "--allow-empty"], fileDiff);
|
|
435
|
-
const tempTargetPath = join(tempDir, filePath);
|
|
436
|
-
return await readFile(tempTargetPath, "utf-8");
|
|
437
|
-
}
|
|
438
|
-
// Normal case: write base at filePath, apply diff, read back
|
|
439
|
-
const tempFilePath = join(tempDir, filePath);
|
|
440
|
-
await mkdir(dirname(tempFilePath), { recursive: true });
|
|
441
|
-
await writeFile(tempFilePath, base);
|
|
442
|
-
// Stage and commit so git apply has a clean base
|
|
443
|
-
await tempGit.exec(["add", filePath]);
|
|
444
|
-
await tempGit.exec(["commit", "-m", `base for ${filePath}`, "--allow-empty"]);
|
|
445
|
-
// Apply this file's diff
|
|
446
|
-
await tempGit.execWithInput(["apply", "--allow-empty"], fileDiff);
|
|
447
|
-
return await readFile(tempFilePath, "utf-8");
|
|
448
|
-
}
|
|
449
|
-
catch {
|
|
450
|
-
return null;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
extractFileDiff(patchContent, filePath) {
|
|
454
|
-
const lines = patchContent.split("\n");
|
|
455
|
-
const diffLines = [];
|
|
456
|
-
let inTargetFile = false;
|
|
457
|
-
for (const line of lines) {
|
|
458
|
-
if (line.startsWith("diff --git")) {
|
|
459
|
-
if (inTargetFile) {
|
|
460
|
-
// Hit the next file's diff, stop collecting
|
|
461
|
-
break;
|
|
462
|
-
}
|
|
463
|
-
if (isDiffLineForFile(line, filePath)) {
|
|
464
|
-
inTargetFile = true;
|
|
465
|
-
diffLines.push(line);
|
|
466
|
-
}
|
|
467
|
-
continue;
|
|
468
|
-
}
|
|
469
|
-
if (inTargetFile) {
|
|
470
|
-
diffLines.push(line);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
return diffLines.length > 0 ? diffLines.join("\n") + "\n" : null;
|
|
474
|
-
}
|
|
475
|
-
extractRenameSource(patchContent, targetFilePath) {
|
|
476
|
-
const lines = patchContent.split("\n");
|
|
477
|
-
let inTargetFile = false;
|
|
478
|
-
for (const line of lines) {
|
|
479
|
-
if (line.startsWith("diff --git")) {
|
|
480
|
-
if (inTargetFile)
|
|
481
|
-
break; // past the target block
|
|
482
|
-
inTargetFile = isDiffLineForFile(line, targetFilePath);
|
|
483
|
-
continue;
|
|
484
|
-
}
|
|
485
|
-
if (!inTargetFile)
|
|
486
|
-
continue;
|
|
487
|
-
// Stop at first hunk — rename headers appear before @@
|
|
488
|
-
if (line.startsWith("@@"))
|
|
489
|
-
break;
|
|
490
|
-
if (line.startsWith("rename from ")) {
|
|
491
|
-
return line.slice("rename from ".length);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
return null;
|
|
495
|
-
}
|
|
496
|
-
extractNewFileFromPatch(patchContent, filePath) {
|
|
497
|
-
const lines = patchContent.split("\n");
|
|
498
|
-
const addedLines = [];
|
|
499
|
-
let inTargetFile = false;
|
|
500
|
-
let inHunk = false;
|
|
501
|
-
let noTrailingNewline = false;
|
|
502
|
-
for (const line of lines) {
|
|
503
|
-
if (line.startsWith("diff --git")) {
|
|
504
|
-
if (inTargetFile)
|
|
505
|
-
break; // hit next file's diff
|
|
506
|
-
inTargetFile = isDiffLineForFile(line, filePath);
|
|
507
|
-
inHunk = false;
|
|
508
|
-
continue;
|
|
509
|
-
}
|
|
510
|
-
if (!inTargetFile)
|
|
511
|
-
continue;
|
|
512
|
-
if (line.startsWith("@@")) {
|
|
513
|
-
inHunk = true;
|
|
514
|
-
continue;
|
|
515
|
-
}
|
|
516
|
-
if (!inHunk)
|
|
517
|
-
continue;
|
|
518
|
-
if (line === "\") {
|
|
519
|
-
noTrailingNewline = true;
|
|
520
|
-
continue;
|
|
521
|
-
}
|
|
522
|
-
if (line.startsWith("+") && !line.startsWith("+++")) {
|
|
523
|
-
addedLines.push(line.slice(1));
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
if (addedLines.length === 0)
|
|
527
|
-
return null;
|
|
528
|
-
return addedLines.join("\n") + (noTrailingNewline ? "" : "\n");
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
function isBinaryFile(filePath) {
|
|
532
|
-
const ext = extname(filePath).toLowerCase();
|
|
533
|
-
return BINARY_EXTENSIONS.has(ext);
|
|
534
|
-
}
|
|
535
|
-
/**
|
|
536
|
-
* Check if a `diff --git` line targets the given file path.
|
|
537
|
-
* Uses a regex anchored to the line format to avoid substring false positives
|
|
538
|
-
* (e.g., `lib/foo.ts` matching `b/lib/foo.ts-backup`).
|
|
539
|
-
*/
|
|
540
|
-
function isDiffLineForFile(diffLine, filePath) {
|
|
541
|
-
const match = diffLine.match(/^diff --git a\/.+ b\/(.+)$/);
|
|
542
|
-
return match !== null && match[1] === filePath;
|
|
543
|
-
}
|
|
544
|
-
//# sourceMappingURL=ReplayApplicator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ReplayApplicator.js","sourceRoot":"","sources":["../src/ReplayApplicator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { GitClient } from "./git/GitClient.js";
|
|
2
|
-
import type { GenerationRecord, StoredPatch } from "./types.js";
|
|
3
|
-
export interface CommitOptions {
|
|
4
|
-
cliVersion: string;
|
|
5
|
-
generatorVersions: Record<string, string>;
|
|
6
|
-
baseBranchHead?: string;
|
|
7
|
-
}
|
|
8
|
-
export declare class ReplayCommitter {
|
|
9
|
-
private git;
|
|
10
|
-
private outputDir;
|
|
11
|
-
constructor(git: GitClient, outputDir: string);
|
|
12
|
-
commitGeneration(message: string, options?: CommitOptions): Promise<string>;
|
|
13
|
-
commitReplay(patchCount: number, patches?: StoredPatch[]): Promise<string>;
|
|
14
|
-
createGenerationRecord(options?: CommitOptions): Promise<GenerationRecord>;
|
|
15
|
-
stageAll(): Promise<void>;
|
|
16
|
-
hasStagedChanges(): Promise<boolean>;
|
|
17
|
-
getTreeHash(commitSha: string): Promise<string>;
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=ReplayCommitter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ReplayCommitter.d.ts","sourceRoot":"","sources":["../src/ReplayCommitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,eAAe;IACxB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,SAAS,CAAS;gBAEd,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM;IAKvC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAwB3E,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB1E,sBAAsB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAc1E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAKpC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAGxD"}
|
package/dist/ReplayCommitter.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
export class ReplayCommitter {
|
|
2
|
-
git;
|
|
3
|
-
outputDir;
|
|
4
|
-
constructor(git, outputDir) {
|
|
5
|
-
this.git = git;
|
|
6
|
-
this.outputDir = outputDir;
|
|
7
|
-
}
|
|
8
|
-
async commitGeneration(message, options) {
|
|
9
|
-
await this.stageAll();
|
|
10
|
-
if (!(await this.hasStagedChanges())) {
|
|
11
|
-
return (await this.git.exec(["rev-parse", "HEAD"])).trim();
|
|
12
|
-
}
|
|
13
|
-
let fullMessage = `[fern-generated] ${message}\n\nGenerated by Fern`;
|
|
14
|
-
if (options?.cliVersion) {
|
|
15
|
-
fullMessage += `\nCLI Version: ${options.cliVersion}`;
|
|
16
|
-
}
|
|
17
|
-
if (options?.generatorVersions && Object.keys(options.generatorVersions).length > 0) {
|
|
18
|
-
fullMessage += "\nGenerators:";
|
|
19
|
-
for (const [name, version] of Object.entries(options.generatorVersions)) {
|
|
20
|
-
fullMessage += `\n - ${name}: ${version}`;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
await this.git.exec(["commit", "-m", fullMessage]);
|
|
24
|
-
return (await this.git.exec(["rev-parse", "HEAD"])).trim();
|
|
25
|
-
}
|
|
26
|
-
async commitReplay(patchCount, patches) {
|
|
27
|
-
await this.stageAll();
|
|
28
|
-
if (!(await this.hasStagedChanges())) {
|
|
29
|
-
return (await this.git.exec(["rev-parse", "HEAD"])).trim();
|
|
30
|
-
}
|
|
31
|
-
let fullMessage = `[fern-replay] Applied ${patchCount} customization(s)`;
|
|
32
|
-
if (patches && patches.length > 0) {
|
|
33
|
-
fullMessage += "\n\nPatches replayed:";
|
|
34
|
-
for (const patch of patches) {
|
|
35
|
-
fullMessage += `\n - ${patch.id}: ${patch.original_message}`;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
await this.git.exec(["commit", "-m", fullMessage]);
|
|
39
|
-
return (await this.git.exec(["rev-parse", "HEAD"])).trim();
|
|
40
|
-
}
|
|
41
|
-
async createGenerationRecord(options) {
|
|
42
|
-
const commitSha = (await this.git.exec(["rev-parse", "HEAD"])).trim();
|
|
43
|
-
const treeHash = await this.getTreeHash(commitSha);
|
|
44
|
-
return {
|
|
45
|
-
commit_sha: commitSha,
|
|
46
|
-
tree_hash: treeHash,
|
|
47
|
-
timestamp: new Date().toISOString(),
|
|
48
|
-
cli_version: options?.cliVersion ?? "unknown",
|
|
49
|
-
generator_versions: options?.generatorVersions ?? {},
|
|
50
|
-
base_branch_head: options?.baseBranchHead
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
async stageAll() {
|
|
54
|
-
await this.git.exec(["add", "-A", this.outputDir]);
|
|
55
|
-
}
|
|
56
|
-
async hasStagedChanges() {
|
|
57
|
-
const output = await this.git.exec(["diff", "--cached", "--name-only"]);
|
|
58
|
-
return output.trim().length > 0;
|
|
59
|
-
}
|
|
60
|
-
async getTreeHash(commitSha) {
|
|
61
|
-
return this.git.getTreeHash(commitSha);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=ReplayCommitter.js.map
|