@fern-api/generator-cli 0.6.10 → 0.6.11
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/api.d.ts +15 -19
- package/dist/api.js +116 -354
- package/dist/cli.js +274 -323
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -19568,7 +19568,7 @@ var init_diff3 = __esm({
|
|
|
19568
19568
|
}
|
|
19569
19569
|
});
|
|
19570
19570
|
|
|
19571
|
-
// ../../node_modules/.pnpm/@fern-api+replay@0.
|
|
19571
|
+
// ../../node_modules/.pnpm/@fern-api+replay@0.7.0/node_modules/@fern-api/replay/dist/index.js
|
|
19572
19572
|
var dist_exports = {};
|
|
19573
19573
|
__export(dist_exports, {
|
|
19574
19574
|
FERN_BOT_EMAIL: () => FERN_BOT_EMAIL2,
|
|
@@ -19891,17 +19891,82 @@ async function resolve7(outputDir, options) {
|
|
|
19891
19891
|
return { success: false, reason: "no-patches" };
|
|
19892
19892
|
}
|
|
19893
19893
|
const git = new GitClient(outputDir);
|
|
19894
|
+
const unresolvedPatches = lockManager.getUnresolvedPatches();
|
|
19895
|
+
const resolvingPatches = lockManager.getResolvingPatches();
|
|
19896
|
+
if (unresolvedPatches.length > 0) {
|
|
19897
|
+
const applicator = new ReplayApplicator(git, lockManager, outputDir);
|
|
19898
|
+
await applicator.applyPatches(unresolvedPatches);
|
|
19899
|
+
const markerFiles = await findConflictMarkerFiles(git);
|
|
19900
|
+
if (markerFiles.length > 0) {
|
|
19901
|
+
for (const patch of unresolvedPatches) {
|
|
19902
|
+
lockManager.updatePatch(patch.id, { status: "resolving" });
|
|
19903
|
+
}
|
|
19904
|
+
lockManager.save();
|
|
19905
|
+
return {
|
|
19906
|
+
success: false,
|
|
19907
|
+
reason: "conflicts-applied",
|
|
19908
|
+
unresolvedFiles: markerFiles,
|
|
19909
|
+
phase: "applied",
|
|
19910
|
+
patchesApplied: unresolvedPatches.length
|
|
19911
|
+
};
|
|
19912
|
+
}
|
|
19913
|
+
}
|
|
19894
19914
|
if (options?.checkMarkers !== false) {
|
|
19895
|
-
const
|
|
19896
|
-
if (
|
|
19897
|
-
|
|
19898
|
-
|
|
19915
|
+
const currentMarkerFiles = await findConflictMarkerFiles(git);
|
|
19916
|
+
if (currentMarkerFiles.length > 0) {
|
|
19917
|
+
return { success: false, reason: "unresolved-conflicts", unresolvedFiles: currentMarkerFiles };
|
|
19918
|
+
}
|
|
19919
|
+
}
|
|
19920
|
+
const patchesToCommit = [...resolvingPatches, ...unresolvedPatches];
|
|
19921
|
+
if (patchesToCommit.length > 0) {
|
|
19922
|
+
const currentGen = lock.current_generation;
|
|
19923
|
+
const detector = new ReplayDetector(git, lockManager, outputDir);
|
|
19924
|
+
let patchesResolved = 0;
|
|
19925
|
+
for (const patch of patchesToCommit) {
|
|
19926
|
+
const diff = await git.exec(["diff", currentGen, "--", ...patch.files]).catch(() => null);
|
|
19927
|
+
if (!diff || !diff.trim()) {
|
|
19928
|
+
lockManager.removePatch(patch.id);
|
|
19929
|
+
continue;
|
|
19930
|
+
}
|
|
19931
|
+
const newContentHash = detector.computeContentHash(diff);
|
|
19932
|
+
const changedFiles = await getChangedFiles(git, currentGen, patch.files);
|
|
19933
|
+
lockManager.markPatchResolved(patch.id, {
|
|
19934
|
+
patch_content: diff,
|
|
19935
|
+
content_hash: newContentHash,
|
|
19936
|
+
base_generation: currentGen,
|
|
19937
|
+
files: changedFiles
|
|
19938
|
+
});
|
|
19939
|
+
patchesResolved++;
|
|
19899
19940
|
}
|
|
19941
|
+
lockManager.save();
|
|
19942
|
+
const committer2 = new ReplayCommitter(git, outputDir);
|
|
19943
|
+
await committer2.stageAll();
|
|
19944
|
+
const commitSha2 = await committer2.commitReplay(
|
|
19945
|
+
lock.patches.length,
|
|
19946
|
+
lock.patches,
|
|
19947
|
+
"[fern-replay] Resolved conflicts"
|
|
19948
|
+
);
|
|
19949
|
+
return {
|
|
19950
|
+
success: true,
|
|
19951
|
+
commitSha: commitSha2,
|
|
19952
|
+
phase: "committed",
|
|
19953
|
+
patchesResolved
|
|
19954
|
+
};
|
|
19900
19955
|
}
|
|
19901
19956
|
const committer = new ReplayCommitter(git, outputDir);
|
|
19902
19957
|
await committer.stageAll();
|
|
19903
19958
|
const commitSha = await committer.commitReplay(lock.patches.length, lock.patches);
|
|
19904
|
-
return { success: true, commitSha };
|
|
19959
|
+
return { success: true, commitSha, phase: "committed" };
|
|
19960
|
+
}
|
|
19961
|
+
async function findConflictMarkerFiles(git) {
|
|
19962
|
+
const output = await git.exec(["grep", "-l", "<<<<<<<", "--", "."]).catch(() => "");
|
|
19963
|
+
return output.trim() ? output.trim().split("\n").filter(Boolean) : [];
|
|
19964
|
+
}
|
|
19965
|
+
async function getChangedFiles(git, currentGen, files) {
|
|
19966
|
+
const filesOutput = await git.exec(["diff", "--name-only", currentGen, "--", ...files]).catch(() => null);
|
|
19967
|
+
if (!filesOutput || !filesOutput.trim()) return files;
|
|
19968
|
+
const changed = filesOutput.trim().split("\n").filter(Boolean).filter((f) => !f.startsWith(".fern/"));
|
|
19969
|
+
return changed.length > 0 ? changed : files;
|
|
19905
19970
|
}
|
|
19906
19971
|
function status(outputDir) {
|
|
19907
19972
|
const lockManager = new LockfileManager(outputDir);
|
|
@@ -19927,7 +19992,7 @@ function status(outputDir) {
|
|
|
19927
19992
|
}
|
|
19928
19993
|
var import_fs6, import_path8, import_yaml, import_crypto, import_promises4, import_os, import_path9, import_fs7, import_path10, import_crypto2, import_fs8, import_path11, import_yaml2, import_crypto3, import_fs9, import_path12, import_fs10, __defProp3, __getOwnPropNames3, __esm3, __export3, GitClient_exports, GitClient, init_GitClient, FERN_BOT_NAME2, FERN_BOT_EMAIL2, FERN_BOT_LOGIN2, FERN_SUPPORT_NAMES, LOCKFILE_HEADER, LockfileManager, INFRASTRUCTURE_FILES, ReplayDetector, BINARY_EXTENSIONS, ReplayApplicator, ReplayCommitter, ReplayService, FernignoreMigrator, REPLAY_FERNIGNORE_ENTRIES;
|
|
19929
19994
|
var init_dist = __esm({
|
|
19930
|
-
"../../node_modules/.pnpm/@fern-api+replay@0.
|
|
19995
|
+
"../../node_modules/.pnpm/@fern-api+replay@0.7.0/node_modules/@fern-api/replay/dist/index.js"() {
|
|
19931
19996
|
"use strict";
|
|
19932
19997
|
init_esm4();
|
|
19933
19998
|
import_fs6 = require("fs");
|
|
@@ -20158,6 +20223,26 @@ var init_dist = __esm({
|
|
|
20158
20223
|
this.ensureLoaded();
|
|
20159
20224
|
this.lock.patches = [];
|
|
20160
20225
|
}
|
|
20226
|
+
getUnresolvedPatches() {
|
|
20227
|
+
this.ensureLoaded();
|
|
20228
|
+
return this.lock.patches.filter((p) => p.status === "unresolved");
|
|
20229
|
+
}
|
|
20230
|
+
getResolvingPatches() {
|
|
20231
|
+
this.ensureLoaded();
|
|
20232
|
+
return this.lock.patches.filter((p) => p.status === "resolving");
|
|
20233
|
+
}
|
|
20234
|
+
markPatchUnresolved(patchId) {
|
|
20235
|
+
this.updatePatch(patchId, { status: "unresolved" });
|
|
20236
|
+
}
|
|
20237
|
+
markPatchResolved(patchId, updates) {
|
|
20238
|
+
this.ensureLoaded();
|
|
20239
|
+
const patch = this.lock.patches.find((p) => p.id === patchId);
|
|
20240
|
+
if (!patch) {
|
|
20241
|
+
throw new Error(`Patch not found: ${patchId}`);
|
|
20242
|
+
}
|
|
20243
|
+
delete patch.status;
|
|
20244
|
+
Object.assign(patch, updates);
|
|
20245
|
+
}
|
|
20161
20246
|
getPatches() {
|
|
20162
20247
|
this.ensureLoaded();
|
|
20163
20248
|
return this.lock.patches;
|
|
@@ -20801,12 +20886,12 @@ CLI Version: ${options.cliVersion}`;
|
|
|
20801
20886
|
await this.git.exec(["commit", "-m", fullMessage]);
|
|
20802
20887
|
return (await this.git.exec(["rev-parse", "HEAD"])).trim();
|
|
20803
20888
|
}
|
|
20804
|
-
async commitReplay(_patchCount, patches) {
|
|
20889
|
+
async commitReplay(_patchCount, patches, message) {
|
|
20805
20890
|
await this.stageAll();
|
|
20806
20891
|
if (!await this.hasStagedChanges()) {
|
|
20807
20892
|
return (await this.git.exec(["rev-parse", "HEAD"])).trim();
|
|
20808
20893
|
}
|
|
20809
|
-
let fullMessage = `[fern-replay] Applied customizations`;
|
|
20894
|
+
let fullMessage = message ?? `[fern-replay] Applied customizations`;
|
|
20810
20895
|
if (patches && patches.length > 0) {
|
|
20811
20896
|
fullMessage += "\n\nPatches replayed:";
|
|
20812
20897
|
for (const patch of patches) {
|
|
@@ -20896,13 +20981,27 @@ CLI Version: ${options.cliVersion}`;
|
|
|
20896
20981
|
this.lockManager.initializeInMemory(record2);
|
|
20897
20982
|
} else {
|
|
20898
20983
|
this.lockManager.read();
|
|
20984
|
+
const unresolvedPatches = [
|
|
20985
|
+
...this.lockManager.getUnresolvedPatches(),
|
|
20986
|
+
...this.lockManager.getResolvingPatches()
|
|
20987
|
+
];
|
|
20899
20988
|
this.lockManager.addGeneration(record2);
|
|
20900
20989
|
this.lockManager.clearPatches();
|
|
20990
|
+
for (const patch of unresolvedPatches) {
|
|
20991
|
+
this.lockManager.addPatch(patch);
|
|
20992
|
+
}
|
|
20901
20993
|
}
|
|
20902
20994
|
this.lockManager.save();
|
|
20903
20995
|
try {
|
|
20904
20996
|
const redetectedPatches = await this.detector.detectNewPatches();
|
|
20905
20997
|
if (redetectedPatches.length > 0) {
|
|
20998
|
+
const redetectedFiles = new Set(redetectedPatches.flatMap((p) => p.files));
|
|
20999
|
+
const currentPatches = this.lockManager.getPatches();
|
|
21000
|
+
for (const patch of currentPatches) {
|
|
21001
|
+
if (patch.status != null && patch.files.some((f) => redetectedFiles.has(f))) {
|
|
21002
|
+
this.lockManager.removePatch(patch.id);
|
|
21003
|
+
}
|
|
21004
|
+
}
|
|
20906
21005
|
for (const patch of redetectedPatches) {
|
|
20907
21006
|
this.lockManager.addPatch(patch);
|
|
20908
21007
|
}
|
|
@@ -21010,6 +21109,12 @@ CLI Version: ${options.cliVersion}`;
|
|
|
21010
21109
|
let results = [];
|
|
21011
21110
|
if (newPatches.length > 0) {
|
|
21012
21111
|
results = await this.applicator.applyPatches(newPatches);
|
|
21112
|
+
this.revertConflictingFiles(results);
|
|
21113
|
+
for (const result of results) {
|
|
21114
|
+
if (result.status === "conflict") {
|
|
21115
|
+
result.patch.status = "unresolved";
|
|
21116
|
+
}
|
|
21117
|
+
}
|
|
21013
21118
|
}
|
|
21014
21119
|
const rebaseCounts = await this.rebasePatches(results, genRecord.commit_sha);
|
|
21015
21120
|
for (const patch of newPatches) {
|
|
@@ -21020,10 +21125,8 @@ CLI Version: ${options.cliVersion}`;
|
|
|
21020
21125
|
this.lockManager.save();
|
|
21021
21126
|
if (newPatches.length > 0) {
|
|
21022
21127
|
if (!options?.stageOnly) {
|
|
21023
|
-
const appliedCount = results.filter((r) => r.status === "applied"
|
|
21024
|
-
|
|
21025
|
-
await this.committer.commitReplay(appliedCount, newPatches);
|
|
21026
|
-
}
|
|
21128
|
+
const appliedCount = results.filter((r) => r.status === "applied").length;
|
|
21129
|
+
await this.committer.commitReplay(appliedCount, newPatches);
|
|
21027
21130
|
} else {
|
|
21028
21131
|
await this.committer.stageAll();
|
|
21029
21132
|
}
|
|
@@ -21071,20 +21174,32 @@ CLI Version: ${options.cliVersion}`;
|
|
|
21071
21174
|
const genRecord = await this.committer.createGenerationRecord(commitOpts);
|
|
21072
21175
|
this.lockManager.addGeneration(genRecord);
|
|
21073
21176
|
const results = await this.applicator.applyPatches(allPatches);
|
|
21177
|
+
this.revertConflictingFiles(results);
|
|
21178
|
+
for (const result of results) {
|
|
21179
|
+
if (result.status === "conflict") {
|
|
21180
|
+
result.patch.status = "unresolved";
|
|
21181
|
+
}
|
|
21182
|
+
}
|
|
21074
21183
|
const rebaseCounts = await this.rebasePatches(results, genRecord.commit_sha);
|
|
21075
21184
|
for (const patch of newPatches) {
|
|
21076
21185
|
if (!rebaseCounts.absorbedPatchIds.has(patch.id)) {
|
|
21077
21186
|
this.lockManager.addPatch(patch);
|
|
21078
21187
|
}
|
|
21079
21188
|
}
|
|
21189
|
+
for (const result of results) {
|
|
21190
|
+
if (result.status === "conflict") {
|
|
21191
|
+
try {
|
|
21192
|
+
this.lockManager.markPatchUnresolved(result.patch.id);
|
|
21193
|
+
} catch {
|
|
21194
|
+
}
|
|
21195
|
+
}
|
|
21196
|
+
}
|
|
21080
21197
|
this.lockManager.save();
|
|
21081
21198
|
if (options?.stageOnly) {
|
|
21082
21199
|
await this.committer.stageAll();
|
|
21083
21200
|
} else {
|
|
21084
|
-
const appliedCount = results.filter((r) => r.status === "applied"
|
|
21085
|
-
|
|
21086
|
-
await this.committer.commitReplay(appliedCount, allPatches);
|
|
21087
|
-
}
|
|
21201
|
+
const appliedCount = results.filter((r) => r.status === "applied").length;
|
|
21202
|
+
await this.committer.commitReplay(appliedCount, allPatches);
|
|
21088
21203
|
}
|
|
21089
21204
|
return this.buildReport(
|
|
21090
21205
|
"normal-regeneration",
|
|
@@ -21232,6 +21347,10 @@ CLI Version: ${options.cliVersion}`;
|
|
|
21232
21347
|
let conflictAbsorbed = 0;
|
|
21233
21348
|
let contentRefreshed = 0;
|
|
21234
21349
|
for (const patch of patches) {
|
|
21350
|
+
if (patch.status != null) {
|
|
21351
|
+
delete patch.status;
|
|
21352
|
+
continue;
|
|
21353
|
+
}
|
|
21235
21354
|
if (patch.base_generation === currentGen) {
|
|
21236
21355
|
try {
|
|
21237
21356
|
const diff = await this.git.exec(["diff", currentGen, "HEAD", "--", ...patch.files]).catch(() => null);
|
|
@@ -21282,6 +21401,55 @@ CLI Version: ${options.cliVersion}`;
|
|
|
21282
21401
|
}
|
|
21283
21402
|
return { conflictResolved, conflictAbsorbed, contentRefreshed };
|
|
21284
21403
|
}
|
|
21404
|
+
/**
|
|
21405
|
+
* Strip conflict markers from file content, keeping the OURS (Generated) side.
|
|
21406
|
+
* Preserves clean patches' non-conflicting changes on shared files.
|
|
21407
|
+
*/
|
|
21408
|
+
stripConflictMarkers(content) {
|
|
21409
|
+
const lines = content.split("\n");
|
|
21410
|
+
const result = [];
|
|
21411
|
+
let inConflict = false;
|
|
21412
|
+
let inOurs = false;
|
|
21413
|
+
for (const line of lines) {
|
|
21414
|
+
if (line.startsWith("<<<<<<< ")) {
|
|
21415
|
+
inConflict = true;
|
|
21416
|
+
inOurs = true;
|
|
21417
|
+
continue;
|
|
21418
|
+
}
|
|
21419
|
+
if (inConflict && line === "=======") {
|
|
21420
|
+
inOurs = false;
|
|
21421
|
+
continue;
|
|
21422
|
+
}
|
|
21423
|
+
if (inConflict && line.startsWith(">>>>>>> ")) {
|
|
21424
|
+
inConflict = false;
|
|
21425
|
+
inOurs = false;
|
|
21426
|
+
continue;
|
|
21427
|
+
}
|
|
21428
|
+
if (!inConflict || inOurs) {
|
|
21429
|
+
result.push(line);
|
|
21430
|
+
}
|
|
21431
|
+
}
|
|
21432
|
+
return result.join("\n");
|
|
21433
|
+
}
|
|
21434
|
+
/**
|
|
21435
|
+
* After applyPatches(), strip conflict markers from conflicting files
|
|
21436
|
+
* so only clean content is committed. Keeps the Generated (OURS) side.
|
|
21437
|
+
*/
|
|
21438
|
+
revertConflictingFiles(results) {
|
|
21439
|
+
for (const result of results) {
|
|
21440
|
+
if (result.status !== "conflict" || !result.fileResults) continue;
|
|
21441
|
+
for (const fileResult of result.fileResults) {
|
|
21442
|
+
if (fileResult.status !== "conflict") continue;
|
|
21443
|
+
const filePath = (0, import_path10.join)(this.outputDir, fileResult.file);
|
|
21444
|
+
try {
|
|
21445
|
+
const content = (0, import_fs7.readFileSync)(filePath, "utf-8");
|
|
21446
|
+
const stripped = this.stripConflictMarkers(content);
|
|
21447
|
+
(0, import_fs7.writeFileSync)(filePath, stripped);
|
|
21448
|
+
} catch {
|
|
21449
|
+
}
|
|
21450
|
+
}
|
|
21451
|
+
}
|
|
21452
|
+
}
|
|
21285
21453
|
readFernignorePatterns() {
|
|
21286
21454
|
const fernignorePath = (0, import_path10.join)(this.outputDir, ".fernignore");
|
|
21287
21455
|
if (!(0, import_fs7.existsSync)(fernignorePath)) return [];
|
|
@@ -21316,6 +21484,12 @@ CLI Version: ${options.cliVersion}`;
|
|
|
21316
21484
|
patchesRefreshed: preRebaseCounts && preRebaseCounts.contentRefreshed > 0 ? preRebaseCounts.contentRefreshed : void 0,
|
|
21317
21485
|
conflicts: conflictResults.flatMap((r) => r.fileResults?.filter((f) => f.status === "conflict") ?? []),
|
|
21318
21486
|
conflictDetails: conflictDetails.length > 0 ? conflictDetails : void 0,
|
|
21487
|
+
unresolvedPatches: conflictResults.length > 0 ? conflictResults.map((r) => ({
|
|
21488
|
+
patchId: r.patch.id,
|
|
21489
|
+
patchMessage: r.patch.original_message,
|
|
21490
|
+
files: r.patch.files,
|
|
21491
|
+
conflictDetails: r.fileResults?.filter((f) => f.status === "conflict") ?? []
|
|
21492
|
+
})) : void 0,
|
|
21319
21493
|
wouldApply: options?.dryRun ? patches : void 0,
|
|
21320
21494
|
warnings: warnings && warnings.length > 0 ? warnings : void 0
|
|
21321
21495
|
};
|
|
@@ -27227,9 +27401,6 @@ async function githubRelease(params) {
|
|
|
27227
27401
|
await github.release();
|
|
27228
27402
|
}
|
|
27229
27403
|
|
|
27230
|
-
// src/api/generate-readme.ts
|
|
27231
|
-
var import_node_stream = require("stream");
|
|
27232
|
-
|
|
27233
27404
|
// ../../node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/predicate/isLength.mjs
|
|
27234
27405
|
function isLength(value) {
|
|
27235
27406
|
return Number.isSafeInteger(value) && value >= 0;
|
|
@@ -30048,16 +30219,25 @@ var ReadmeGenerator = class {
|
|
|
30048
30219
|
this.apiName = this.readmeConfig.apiName ?? this.organizationPascalCase;
|
|
30049
30220
|
}
|
|
30050
30221
|
async generateReadme({ output }) {
|
|
30222
|
+
const writer = new StreamWriter(output);
|
|
30223
|
+
await this.writeReadmeContent({ writer });
|
|
30224
|
+
await writer.end();
|
|
30225
|
+
}
|
|
30226
|
+
async generateReadmeToString() {
|
|
30227
|
+
const writer = new StringWriter();
|
|
30228
|
+
await this.writeReadmeContent({ writer });
|
|
30229
|
+
await writer.end();
|
|
30230
|
+
return writer.toString();
|
|
30231
|
+
}
|
|
30232
|
+
async writeReadmeContent({ writer }) {
|
|
30051
30233
|
const blocks = await this.generateBlocks();
|
|
30052
30234
|
const mergedBlocks = await this.mergeBlocks({ blocks });
|
|
30053
|
-
const writer = new StreamWriter(output);
|
|
30054
30235
|
await this.writeHeader({ writer });
|
|
30055
30236
|
await this.writeTableOfContents({ writer, blocks: mergedBlocks });
|
|
30056
30237
|
await this.writeBlocks({
|
|
30057
30238
|
writer,
|
|
30058
30239
|
blocks: mergedBlocks
|
|
30059
30240
|
});
|
|
30060
|
-
await writer.end();
|
|
30061
30241
|
}
|
|
30062
30242
|
async generateBlocks() {
|
|
30063
30243
|
const blocks = [];
|
|
@@ -30927,9 +31107,6 @@ async function generateReadmeToStream(params) {
|
|
|
30927
31107
|
});
|
|
30928
31108
|
}
|
|
30929
31109
|
|
|
30930
|
-
// src/api/generate-reference.ts
|
|
30931
|
-
var import_node_stream2 = require("stream");
|
|
30932
|
-
|
|
30933
31110
|
// src/reference/ReferenceGenerator.ts
|
|
30934
31111
|
var ReferenceGenerator = class {
|
|
30935
31112
|
referenceConfig;
|
|
@@ -30940,6 +31117,16 @@ var ReferenceGenerator = class {
|
|
|
30940
31117
|
}
|
|
30941
31118
|
async generate({ output }) {
|
|
30942
31119
|
const writer = new StreamWriter(output);
|
|
31120
|
+
await this.writeReferenceContent({ writer });
|
|
31121
|
+
await writer.end();
|
|
31122
|
+
}
|
|
31123
|
+
async generateToString() {
|
|
31124
|
+
const writer = new StringWriter();
|
|
31125
|
+
await this.writeReferenceContent({ writer });
|
|
31126
|
+
await writer.end();
|
|
31127
|
+
return writer.toString();
|
|
31128
|
+
}
|
|
31129
|
+
async writeReferenceContent({ writer }) {
|
|
30943
31130
|
await writer.writeLine("# Reference");
|
|
30944
31131
|
if (this.referenceConfig.rootSection != null) {
|
|
30945
31132
|
await this.writeRootSection({
|
|
@@ -30950,7 +31137,6 @@ var ReferenceGenerator = class {
|
|
|
30950
31137
|
for (const section of this.referenceConfig.sections) {
|
|
30951
31138
|
await this.writeSection({ section, writer });
|
|
30952
31139
|
}
|
|
30953
|
-
await writer.end();
|
|
30954
31140
|
}
|
|
30955
31141
|
async writeRootSection({
|
|
30956
31142
|
section,
|
|
@@ -31090,41 +31276,19 @@ var import_path7 = require("path");
|
|
|
31090
31276
|
|
|
31091
31277
|
// src/pipeline/github/createReplayBranch.ts
|
|
31092
31278
|
async function createReplayBranch(repository, branchName, commitMessage, replayConflictInfo, logger) {
|
|
31093
|
-
if (replayConflictInfo
|
|
31094
|
-
const parentSha = replayConflictInfo.previousGenerationSha;
|
|
31095
|
-
const lockfileRestoreSha = replayConflictInfo.baseBranchHead ?? replayConflictInfo.previousGenerationSha;
|
|
31096
|
-
logger.debug(`Creating divergent PR branch with generation tree (parent: ${parentSha.substring(0, 7)})`);
|
|
31097
|
-
const genTreeHash = await repository.getCommitTreeHash(replayConflictInfo.currentGenerationSha);
|
|
31098
|
-
const syntheticCommitSha = await repository.commitTree(
|
|
31099
|
-
genTreeHash,
|
|
31100
|
-
parentSha,
|
|
31101
|
-
`[fern-generated] ${commitMessage ?? "Update SDK"}`
|
|
31102
|
-
);
|
|
31103
|
-
await repository.createBranchFromCommit(branchName, syntheticCommitSha);
|
|
31104
|
-
try {
|
|
31105
|
-
await repository.restoreFilesFromCommit(lockfileRestoreSha, ".fern/replay.lock");
|
|
31106
|
-
await repository.commitAllChanges(`[fern-generated] ${commitMessage ?? "Update SDK"}`);
|
|
31107
|
-
} catch (error) {
|
|
31108
|
-
logger.debug(
|
|
31109
|
-
`Could not restore lockfile from base branch: ${error instanceof Error ? error.message : String(error)}`
|
|
31110
|
-
);
|
|
31111
|
-
}
|
|
31112
|
-
return syntheticCommitSha;
|
|
31113
|
-
} else if (replayConflictInfo != null) {
|
|
31114
|
-
const parentSha = replayConflictInfo.previousGenerationSha;
|
|
31115
|
-
logger.debug(`Creating linear PR branch from HEAD (no conflicts)`);
|
|
31116
|
-
await repository.createBranchFromHead(branchName);
|
|
31117
|
-
const genTreeHash = await repository.getCommitTreeHash(replayConflictInfo.currentGenerationSha);
|
|
31118
|
-
const tagCommitSha = await repository.commitTree(
|
|
31119
|
-
genTreeHash,
|
|
31120
|
-
parentSha,
|
|
31121
|
-
`[fern-generated] ${commitMessage ?? "Update SDK"}`
|
|
31122
|
-
);
|
|
31123
|
-
return tagCommitSha;
|
|
31124
|
-
} else {
|
|
31279
|
+
if (replayConflictInfo == null) {
|
|
31125
31280
|
await repository.createBranchFromHead(branchName);
|
|
31126
31281
|
return void 0;
|
|
31127
31282
|
}
|
|
31283
|
+
const parentSha = replayConflictInfo.previousGenerationSha;
|
|
31284
|
+
await repository.createBranchFromHead(branchName);
|
|
31285
|
+
const genTreeHash = await repository.getCommitTreeHash(replayConflictInfo.currentGenerationSha);
|
|
31286
|
+
const tagCommitSha = await repository.commitTree(
|
|
31287
|
+
genTreeHash,
|
|
31288
|
+
parentSha,
|
|
31289
|
+
`[fern-generated] ${commitMessage ?? "Update SDK"}`
|
|
31290
|
+
);
|
|
31291
|
+
return tagCommitSha;
|
|
31128
31292
|
}
|
|
31129
31293
|
|
|
31130
31294
|
// src/pipeline/github/findExistingUpdatablePR.ts
|
|
@@ -31219,11 +31383,11 @@ function formatConflictReason(reason) {
|
|
|
31219
31383
|
case "same-line-edit":
|
|
31220
31384
|
return "The new generation changed the same lines you edited";
|
|
31221
31385
|
case "new-file-both":
|
|
31222
|
-
return "
|
|
31386
|
+
return "Both the generator and your customization created this file";
|
|
31223
31387
|
case "base-generation-mismatch":
|
|
31224
|
-
return "
|
|
31388
|
+
return "This customization was from a previous generation";
|
|
31225
31389
|
case "patch-apply-failed":
|
|
31226
|
-
return "
|
|
31390
|
+
return "The customization could not be applied to the new code";
|
|
31227
31391
|
default:
|
|
31228
31392
|
return "Your edit overlaps with changes in the new generation";
|
|
31229
31393
|
}
|
|
@@ -31232,7 +31396,7 @@ function patchDescription(detail) {
|
|
|
31232
31396
|
if (detail.patchMessage && detail.patchMessage !== "update") {
|
|
31233
31397
|
return detail.patchMessage;
|
|
31234
31398
|
}
|
|
31235
|
-
const firstFile = detail.files[0]
|
|
31399
|
+
const firstFile = detail.files[0];
|
|
31236
31400
|
return firstFile != null ? `changes in ${firstFile}` : "customization";
|
|
31237
31401
|
}
|
|
31238
31402
|
function formatReplayPrBody(result, options) {
|
|
@@ -31241,70 +31405,66 @@ function formatReplayPrBody(result, options) {
|
|
|
31241
31405
|
}
|
|
31242
31406
|
const applied = result.patchesApplied ?? 0;
|
|
31243
31407
|
const absorbed = result.patchesAbsorbed ?? 0;
|
|
31244
|
-
const
|
|
31408
|
+
const unresolvedPatches = result.unresolvedPatches ?? [];
|
|
31409
|
+
const hasUnresolved = unresolvedPatches.length > 0;
|
|
31245
31410
|
const preserved = applied - absorbed;
|
|
31246
|
-
if (preserved === 0 &&
|
|
31411
|
+
if (preserved === 0 && !hasUnresolved) {
|
|
31247
31412
|
return void 0;
|
|
31248
31413
|
}
|
|
31249
31414
|
const parts = [];
|
|
31250
|
-
if (preserved > 0 &&
|
|
31415
|
+
if (preserved > 0 && !hasUnresolved) {
|
|
31251
31416
|
parts.push(`\u2705 Customizations automatically preserved in this update.`);
|
|
31252
31417
|
} else if (preserved > 0) {
|
|
31418
|
+
const totalFiles = unresolvedPatches.reduce((sum, patch) => sum + patch.conflictDetails.length, 0);
|
|
31253
31419
|
parts.push(
|
|
31254
|
-
`\u2705 Customizations automatically preserved, but ${plural(
|
|
31420
|
+
`\u2705 Customizations automatically preserved, but ${plural(totalFiles, "file")} ${totalFiles === 1 ? "needs" : "need"} your attention.`
|
|
31255
31421
|
);
|
|
31256
31422
|
}
|
|
31257
|
-
if (
|
|
31258
|
-
const
|
|
31259
|
-
const totalFiles = allFiles.length;
|
|
31423
|
+
if (hasUnresolved) {
|
|
31424
|
+
const totalFiles = unresolvedPatches.reduce((sum, patch) => sum + patch.conflictDetails.length, 0);
|
|
31260
31425
|
parts.push(`
|
|
31261
|
-
###
|
|
31426
|
+
### Action required: ${plural(totalFiles, "file")} with unresolved customization conflicts
|
|
31262
31427
|
`);
|
|
31263
31428
|
parts.push(
|
|
31264
|
-
`
|
|
31265
|
-
`
|
|
31266
|
-
);
|
|
31267
|
-
parts.push(
|
|
31268
|
-
`> \u26A0\uFE0F **Label guide:** In GitHub's conflict editor, \`<<<<<<< HEAD\` ("Accept current") = new generated code. \`>>>>>>> main\` ("Accept incoming") = your customization.
|
|
31429
|
+
`The new generation changed code you previously customized. Non-conflicting customizations have been applied automatically. The following files need manual resolution:
|
|
31269
31430
|
`
|
|
31270
31431
|
);
|
|
31271
31432
|
parts.push(`| File | Your customization | Why it conflicted |`);
|
|
31272
31433
|
parts.push(`|------|-------------------|-------------------|`);
|
|
31273
|
-
for (const
|
|
31274
|
-
const description = patchDescription(
|
|
31275
|
-
for (const
|
|
31276
|
-
parts.push(`| \`${
|
|
31434
|
+
for (const patch of unresolvedPatches) {
|
|
31435
|
+
const description = patchDescription(patch);
|
|
31436
|
+
for (const file of patch.conflictDetails) {
|
|
31437
|
+
parts.push(`| \`${file.file}\` | ${description} | ${formatConflictReason(file.conflictReason)} |`);
|
|
31277
31438
|
}
|
|
31278
31439
|
}
|
|
31279
31440
|
const branch = options?.branchName ?? "<branch-name>";
|
|
31441
|
+
const repoUri = options?.repoUri;
|
|
31442
|
+
const repoName = repoUri?.split("/").pop() ?? "<repo>";
|
|
31280
31443
|
parts.push(`
|
|
31281
|
-
#### How to
|
|
31282
|
-
`);
|
|
31283
|
-
parts.push(`**Option A: Resolve in GitHub (recommended for simple conflicts)**
|
|
31284
|
-
`);
|
|
31285
|
-
parts.push(`1. Click the **Resolve conflicts** button below`);
|
|
31286
|
-
parts.push(`2. For each file, choose which code to keep:`);
|
|
31287
|
-
parts.push(` - \`<<<<<<< HEAD\` / "Accept current changes" = **new generated code**`);
|
|
31288
|
-
parts.push(` - \`>>>>>>> main\` / "Accept incoming changes" = **your customization**`);
|
|
31289
|
-
parts.push(` - Or manually combine both, then delete the conflict markers`);
|
|
31290
|
-
parts.push(`3. Click **Mark as resolved** for each file, then **Commit merge**
|
|
31444
|
+
#### How to resolve
|
|
31291
31445
|
`);
|
|
31292
|
-
parts.push(
|
|
31293
|
-
`);
|
|
31294
|
-
parts.push(`1. Fetch and check out this branch:`);
|
|
31295
|
-
parts.push(` \`\`\`sh`);
|
|
31296
|
-
parts.push(` git fetch origin && git checkout ${branch}`);
|
|
31297
|
-
parts.push(` \`\`\``);
|
|
31298
|
-
parts.push(`2. Merge the base branch and resolve conflicts in your editor:`);
|
|
31446
|
+
parts.push(`1. Check out this branch:`);
|
|
31299
31447
|
parts.push(` \`\`\`sh`);
|
|
31300
|
-
parts.push(` git
|
|
31448
|
+
parts.push(` git fetch origin && git checkout -b ${branch} origin/${branch}`);
|
|
31301
31449
|
parts.push(` \`\`\``);
|
|
31302
|
-
|
|
31303
|
-
|
|
31304
|
-
|
|
31305
|
-
|
|
31450
|
+
if (repoUri != null) {
|
|
31451
|
+
parts.push(` Or if you don't have the repo cloned:`);
|
|
31452
|
+
parts.push(` \`\`\`sh`);
|
|
31453
|
+
parts.push(
|
|
31454
|
+
` git clone https://github.com/${repoUri}.git && cd ${repoName} && git checkout -b ${branch} origin/${branch}`
|
|
31455
|
+
);
|
|
31456
|
+
parts.push(` \`\`\``);
|
|
31457
|
+
}
|
|
31458
|
+
parts.push(`2. Run: \`fern replay resolve\``);
|
|
31459
|
+
parts.push(`3. Open the conflicting files in your editor \u2014 you'll see standard merge conflict markers`);
|
|
31460
|
+
parts.push(`4. Resolve using your editor's merge tools (VS Code, IntelliJ, etc.)`);
|
|
31461
|
+
parts.push(`5. Run: \`fern replay resolve\` again to finalize`);
|
|
31462
|
+
parts.push(`6. Push your changes
|
|
31306
31463
|
`);
|
|
31307
|
-
parts.push(`Your resolved
|
|
31464
|
+
parts.push(`Your resolved customizations will be remembered on future SDK generations.`);
|
|
31465
|
+
parts.push(
|
|
31466
|
+
`If you merge this PR without resolving, your unresolved customizations will conflict again on the next generation.`
|
|
31467
|
+
);
|
|
31308
31468
|
}
|
|
31309
31469
|
return parts.join("\n");
|
|
31310
31470
|
}
|
|
@@ -31440,16 +31600,9 @@ var GithubStep = class extends BaseStep {
|
|
|
31440
31600
|
}
|
|
31441
31601
|
}
|
|
31442
31602
|
}
|
|
31443
|
-
if (!this.config.previewMode) {
|
|
31444
|
-
const headSha = await repository.getHeadSha();
|
|
31445
|
-
await this.postReplayConflictStatus(octokit, owner, repo, headSha, replayConflictInfo, replayResult);
|
|
31446
|
-
if (isUpdatingExistingPR && existingPR != null) {
|
|
31447
|
-
await this.togglePrDraftState(octokit, existingPR, replayConflictInfo);
|
|
31448
|
-
}
|
|
31449
|
-
}
|
|
31450
31603
|
const finalCommitMessage = this.config.commitMessage ?? "SDK Generation";
|
|
31451
31604
|
const { prTitle, prBody } = parseCommitMessageForPR(finalCommitMessage);
|
|
31452
|
-
const replaySection = formatReplayPrBody(replayResult, { branchName: prBranch });
|
|
31605
|
+
const replaySection = formatReplayPrBody(replayResult, { branchName: prBranch, repoUri: this.config.uri });
|
|
31453
31606
|
const enrichedBody = replaySection != null ? prBody + "\n\n---\n\n" + replaySection : prBody;
|
|
31454
31607
|
if (isUpdatingExistingPR && existingPR != null) {
|
|
31455
31608
|
this.logger.info(`Updated existing pull request: ${existingPR.htmlUrl}`);
|
|
@@ -31471,7 +31624,6 @@ var GithubStep = class extends BaseStep {
|
|
|
31471
31624
|
}
|
|
31472
31625
|
} else {
|
|
31473
31626
|
const head = `${owner}:${prBranch}`;
|
|
31474
|
-
const hasConflicts = replayConflictInfo?.hasConflicts === true;
|
|
31475
31627
|
try {
|
|
31476
31628
|
const { data: pullRequest } = await octokit.pulls.create({
|
|
31477
31629
|
owner,
|
|
@@ -31479,8 +31631,7 @@ var GithubStep = class extends BaseStep {
|
|
|
31479
31631
|
title: prTitle,
|
|
31480
31632
|
body: enrichedBody,
|
|
31481
31633
|
head,
|
|
31482
|
-
base: baseBranch
|
|
31483
|
-
draft: hasConflicts
|
|
31634
|
+
base: baseBranch
|
|
31484
31635
|
});
|
|
31485
31636
|
this.logger.info(`Created pull request: ${pullRequest.html_url}`);
|
|
31486
31637
|
result.prUrl = pullRequest.html_url;
|
|
@@ -31494,17 +31645,6 @@ var GithubStep = class extends BaseStep {
|
|
|
31494
31645
|
}
|
|
31495
31646
|
}
|
|
31496
31647
|
}
|
|
31497
|
-
if (!this.config.previewMode && result.prNumber != null && replayConflictInfo?.hasConflicts === true && replayResult != null) {
|
|
31498
|
-
await this.postWebEditorFallbackComment(
|
|
31499
|
-
octokit,
|
|
31500
|
-
owner,
|
|
31501
|
-
repo,
|
|
31502
|
-
result.prNumber,
|
|
31503
|
-
prBranch,
|
|
31504
|
-
baseBranch,
|
|
31505
|
-
replayResult
|
|
31506
|
-
);
|
|
31507
|
-
}
|
|
31508
31648
|
return result;
|
|
31509
31649
|
}
|
|
31510
31650
|
async executePushMode(repository) {
|
|
@@ -31550,198 +31690,17 @@ var GithubStep = class extends BaseStep {
|
|
|
31550
31690
|
if (replayResult == null) {
|
|
31551
31691
|
return void 0;
|
|
31552
31692
|
}
|
|
31553
|
-
const hasConflicts = (replayResult.patchesWithConflicts ?? 0) > 0;
|
|
31554
31693
|
const previousGenerationSha = replayResult.previousGenerationSha;
|
|
31555
31694
|
const currentGenerationSha = replayResult.currentGenerationSha;
|
|
31556
31695
|
if (previousGenerationSha != null && currentGenerationSha != null) {
|
|
31557
31696
|
return {
|
|
31558
31697
|
previousGenerationSha,
|
|
31559
|
-
currentGenerationSha
|
|
31560
|
-
hasConflicts,
|
|
31561
|
-
baseBranchHead: replayResult.baseBranchHead
|
|
31698
|
+
currentGenerationSha
|
|
31562
31699
|
};
|
|
31563
31700
|
}
|
|
31564
31701
|
return void 0;
|
|
31565
31702
|
}
|
|
31566
|
-
async togglePrDraftState(octokit, existingPR, replayConflictInfo) {
|
|
31567
|
-
const hasConflicts = replayConflictInfo?.hasConflicts === true;
|
|
31568
|
-
if (hasConflicts && !existingPR.isDraft) {
|
|
31569
|
-
await this.convertPrToDraft(octokit, existingPR.nodeId, existingPR.number);
|
|
31570
|
-
} else if (!hasConflicts && existingPR.isDraft) {
|
|
31571
|
-
await this.markPrReady(octokit, existingPR.nodeId, existingPR.number);
|
|
31572
|
-
}
|
|
31573
|
-
}
|
|
31574
|
-
async convertPrToDraft(octokit, nodeId, prNumber) {
|
|
31575
|
-
try {
|
|
31576
|
-
await octokit.graphql(
|
|
31577
|
-
`mutation($id: ID!) {
|
|
31578
|
-
convertPullRequestToDraft(input: {pullRequestId: $id}) {
|
|
31579
|
-
pullRequest { isDraft }
|
|
31580
|
-
}
|
|
31581
|
-
}`,
|
|
31582
|
-
{ id: nodeId }
|
|
31583
|
-
);
|
|
31584
|
-
this.logger.info(`Converted PR #${prNumber} to draft due to replay conflicts`);
|
|
31585
|
-
} catch (error) {
|
|
31586
|
-
this.logger.debug(
|
|
31587
|
-
`Could not convert PR to draft: ${error instanceof Error ? error.message : String(error)}`
|
|
31588
|
-
);
|
|
31589
|
-
}
|
|
31590
|
-
}
|
|
31591
|
-
async markPrReady(octokit, nodeId, prNumber) {
|
|
31592
|
-
try {
|
|
31593
|
-
await octokit.graphql(
|
|
31594
|
-
`mutation($id: ID!) {
|
|
31595
|
-
markPullRequestReadyForReview(input: {pullRequestId: $id}) {
|
|
31596
|
-
pullRequest { isDraft }
|
|
31597
|
-
}
|
|
31598
|
-
}`,
|
|
31599
|
-
{ id: nodeId }
|
|
31600
|
-
);
|
|
31601
|
-
this.logger.info(`Marked PR #${prNumber} as ready (conflicts resolved)`);
|
|
31602
|
-
} catch (error) {
|
|
31603
|
-
this.logger.debug(`Could not mark PR as ready: ${error instanceof Error ? error.message : String(error)}`);
|
|
31604
|
-
}
|
|
31605
|
-
}
|
|
31606
|
-
async postReplayConflictStatus(octokit, owner, repo, sha, replayConflictInfo, replayResult) {
|
|
31607
|
-
if (replayResult == null || !replayResult.executed) {
|
|
31608
|
-
return;
|
|
31609
|
-
}
|
|
31610
|
-
const hasConflicts = replayConflictInfo?.hasConflicts === true;
|
|
31611
|
-
const conflictFileCount = (replayResult.conflictDetails ?? []).reduce(
|
|
31612
|
-
(sum, detail) => sum + detail.files.length,
|
|
31613
|
-
0
|
|
31614
|
-
);
|
|
31615
|
-
const sanitizedName = this.config.generatorName?.replace(/\//g, "--");
|
|
31616
|
-
const context = sanitizedName != null ? `fern / sdk customizations / ${sanitizedName}` : "fern / sdk customizations";
|
|
31617
|
-
try {
|
|
31618
|
-
await octokit.repos.createCommitStatus({
|
|
31619
|
-
owner,
|
|
31620
|
-
repo,
|
|
31621
|
-
sha,
|
|
31622
|
-
state: hasConflicts ? "failure" : "success",
|
|
31623
|
-
context,
|
|
31624
|
-
description: hasConflicts ? `${conflictFileCount} file(s) need manual conflict resolution \u2014 see PR description` : "All customizations applied"
|
|
31625
|
-
});
|
|
31626
|
-
this.logger.debug(`Posted ${hasConflicts ? "failing" : "passing"} commit status (${context})`);
|
|
31627
|
-
} catch (error) {
|
|
31628
|
-
this.logger.debug(
|
|
31629
|
-
`Could not post commit status: ${error instanceof Error ? error.message : String(error)}`
|
|
31630
|
-
);
|
|
31631
|
-
}
|
|
31632
|
-
}
|
|
31633
|
-
async postWebEditorFallbackComment(octokit, owner, repo, prNumber, branchName, baseBranch, replayResult) {
|
|
31634
|
-
try {
|
|
31635
|
-
const webEditorLikelyDisabled = await this.isWebEditorLikelyDisabled(
|
|
31636
|
-
octokit,
|
|
31637
|
-
owner,
|
|
31638
|
-
repo,
|
|
31639
|
-
prNumber,
|
|
31640
|
-
replayResult
|
|
31641
|
-
);
|
|
31642
|
-
if (!webEditorLikelyDisabled) {
|
|
31643
|
-
this.logger.debug(`PR #${prNumber}: web conflict editor appears usable, skipping fallback comment`);
|
|
31644
|
-
return;
|
|
31645
|
-
}
|
|
31646
|
-
const comment = buildWebEditorFallbackComment(branchName, baseBranch);
|
|
31647
|
-
await octokit.issues.createComment({
|
|
31648
|
-
owner,
|
|
31649
|
-
repo,
|
|
31650
|
-
issue_number: prNumber,
|
|
31651
|
-
body: comment
|
|
31652
|
-
});
|
|
31653
|
-
this.logger.info(`Posted web-editor fallback comment on PR #${prNumber}`);
|
|
31654
|
-
} catch (error) {
|
|
31655
|
-
this.logger.debug(
|
|
31656
|
-
`Could not post web-editor fallback comment: ${error instanceof Error ? error.message : String(error)}`
|
|
31657
|
-
);
|
|
31658
|
-
}
|
|
31659
|
-
}
|
|
31660
|
-
async isWebEditorLikelyDisabled(octokit, owner, repo, prNumber, replayResult) {
|
|
31661
|
-
const conflictDetails = replayResult.conflictDetails ?? [];
|
|
31662
|
-
const allConflictFiles = conflictDetails.flatMap((d) => d.files);
|
|
31663
|
-
const totalConflictFiles = allConflictFiles.length;
|
|
31664
|
-
const hasFileDeletionConflict = allConflictFiles.some((f) => {
|
|
31665
|
-
const status2 = (f.status ?? "").toLowerCase();
|
|
31666
|
-
const reason = (f.conflictReason ?? "").toLowerCase();
|
|
31667
|
-
return status2 === "skipped" || reason.includes("delete") || reason.includes("removed");
|
|
31668
|
-
});
|
|
31669
|
-
if (hasFileDeletionConflict) {
|
|
31670
|
-
this.logger.debug(`PR #${prNumber}: detected file deletion conflict, web editor likely disabled`);
|
|
31671
|
-
return true;
|
|
31672
|
-
}
|
|
31673
|
-
if (totalConflictFiles >= WEB_EDITOR_FILE_THRESHOLD) {
|
|
31674
|
-
this.logger.debug(
|
|
31675
|
-
`PR #${prNumber}: ${totalConflictFiles} conflicting files exceeds threshold (${WEB_EDITOR_FILE_THRESHOLD}), web editor likely disabled`
|
|
31676
|
-
);
|
|
31677
|
-
return true;
|
|
31678
|
-
}
|
|
31679
|
-
const totalHunks = (replayResult.conflicts ?? []).reduce(
|
|
31680
|
-
(sum, fileConflict) => sum + fileConflict.conflicts.length,
|
|
31681
|
-
0
|
|
31682
|
-
);
|
|
31683
|
-
if (totalHunks >= WEB_EDITOR_HUNK_THRESHOLD) {
|
|
31684
|
-
this.logger.debug(
|
|
31685
|
-
`PR #${prNumber}: ${totalHunks} conflict hunks exceeds threshold (${WEB_EDITOR_HUNK_THRESHOLD}), web editor likely disabled`
|
|
31686
|
-
);
|
|
31687
|
-
return true;
|
|
31688
|
-
}
|
|
31689
|
-
const mergeableState = await this.pollMergeableState(octokit, owner, repo, prNumber);
|
|
31690
|
-
if (mergeableState.mergeable === null) {
|
|
31691
|
-
this.logger.debug(`PR #${prNumber}: mergeable state still null after polling, web editor likely disabled`);
|
|
31692
|
-
return true;
|
|
31693
|
-
}
|
|
31694
|
-
return false;
|
|
31695
|
-
}
|
|
31696
|
-
async pollMergeableState(octokit, owner, repo, prNumber) {
|
|
31697
|
-
for (let attempt2 = 0; attempt2 < MERGEABLE_POLL_MAX_ATTEMPTS; attempt2++) {
|
|
31698
|
-
const { data: pr } = await octokit.pulls.get({
|
|
31699
|
-
owner,
|
|
31700
|
-
repo,
|
|
31701
|
-
pull_number: prNumber
|
|
31702
|
-
});
|
|
31703
|
-
if (pr.mergeable != null) {
|
|
31704
|
-
return {
|
|
31705
|
-
mergeable: pr.mergeable,
|
|
31706
|
-
mergeableState: pr.mergeable_state
|
|
31707
|
-
};
|
|
31708
|
-
}
|
|
31709
|
-
if (attempt2 < MERGEABLE_POLL_MAX_ATTEMPTS - 1) {
|
|
31710
|
-
await sleep(MERGEABLE_POLL_DELAY_MS);
|
|
31711
|
-
}
|
|
31712
|
-
}
|
|
31713
|
-
return { mergeable: null, mergeableState: "unknown" };
|
|
31714
|
-
}
|
|
31715
31703
|
};
|
|
31716
|
-
var WEB_EDITOR_FILE_THRESHOLD = 20;
|
|
31717
|
-
var WEB_EDITOR_HUNK_THRESHOLD = 50;
|
|
31718
|
-
var MERGEABLE_POLL_MAX_ATTEMPTS = 3;
|
|
31719
|
-
var MERGEABLE_POLL_DELAY_MS = 1500;
|
|
31720
|
-
function buildWebEditorFallbackComment(branchName, baseBranch) {
|
|
31721
|
-
const lines = [
|
|
31722
|
-
`> **Note:** These conflicts may be too complex for GitHub's web editor. To resolve locally:`,
|
|
31723
|
-
`>`,
|
|
31724
|
-
`> 1. Check out this branch:`,
|
|
31725
|
-
`> \`\`\`sh`,
|
|
31726
|
-
`> git fetch origin && git checkout ${branchName}`,
|
|
31727
|
-
`> \`\`\``,
|
|
31728
|
-
`> 2. Merge the base branch:`,
|
|
31729
|
-
`> \`\`\`sh`,
|
|
31730
|
-
`> git merge origin/${baseBranch}`,
|
|
31731
|
-
`> \`\`\``,
|
|
31732
|
-
`> 3. Resolve conflicts in your editor (VS Code, IntelliJ, etc. have built-in merge tools)`,
|
|
31733
|
-
`> 4. Commit and push:`,
|
|
31734
|
-
`> \`\`\`sh`,
|
|
31735
|
-
`> git add -A && git commit -m "resolve conflicts" && git push`,
|
|
31736
|
-
`> \`\`\``,
|
|
31737
|
-
`>`,
|
|
31738
|
-
`> **Label guide:** In your editor's merge view, "current" = new generated code, "incoming" = your customization.`
|
|
31739
|
-
];
|
|
31740
|
-
return lines.join("\n");
|
|
31741
|
-
}
|
|
31742
|
-
function sleep(ms) {
|
|
31743
|
-
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
31744
|
-
}
|
|
31745
31704
|
|
|
31746
31705
|
// src/replay/replay-run.ts
|
|
31747
31706
|
init_dist();
|
|
@@ -31950,8 +31909,7 @@ var ReplayStep = class extends BaseStep {
|
|
|
31950
31909
|
flow: "first-generation",
|
|
31951
31910
|
patchesDetected: 0,
|
|
31952
31911
|
patchesApplied: 0,
|
|
31953
|
-
patchesWithConflicts: 0
|
|
31954
|
-
conflicts: []
|
|
31912
|
+
patchesWithConflicts: 0
|
|
31955
31913
|
};
|
|
31956
31914
|
}
|
|
31957
31915
|
const report = result.report;
|
|
@@ -31969,22 +31927,12 @@ var ReplayStep = class extends BaseStep {
|
|
|
31969
31927
|
patchesRepointed: report.patchesRepointed,
|
|
31970
31928
|
patchesContentRebased: report.patchesContentRebased,
|
|
31971
31929
|
patchesKeptAsUserOwned: report.patchesKeptAsUserOwned,
|
|
31972
|
-
|
|
31973
|
-
|
|
31974
|
-
|
|
31975
|
-
|
|
31976
|
-
|
|
31977
|
-
ours: conflict.ours,
|
|
31978
|
-
theirs: conflict.theirs
|
|
31979
|
-
})) ?? []
|
|
31980
|
-
})),
|
|
31981
|
-
conflictDetails: report.conflictDetails?.map((detail) => ({
|
|
31982
|
-
patchId: detail.patchId,
|
|
31983
|
-
patchMessage: detail.patchMessage,
|
|
31984
|
-
reason: detail.reason,
|
|
31985
|
-
files: detail.files.map((f) => ({
|
|
31930
|
+
unresolvedPatches: report.unresolvedPatches?.map((info) => ({
|
|
31931
|
+
patchId: info.patchId,
|
|
31932
|
+
patchMessage: info.patchMessage,
|
|
31933
|
+
files: info.files,
|
|
31934
|
+
conflictDetails: info.conflictDetails.map((f) => ({
|
|
31986
31935
|
file: f.file,
|
|
31987
|
-
status: f.status,
|
|
31988
31936
|
conflictReason: f.conflictReason
|
|
31989
31937
|
}))
|
|
31990
31938
|
})),
|
|
@@ -32248,6 +32196,9 @@ function buildPrBody(result) {
|
|
|
32248
32196
|
return lines.join("\n");
|
|
32249
32197
|
}
|
|
32250
32198
|
|
|
32199
|
+
// src/replay/replay-resolve.ts
|
|
32200
|
+
init_dist();
|
|
32201
|
+
|
|
32251
32202
|
// src/configuration/loadGitHubConfig.ts
|
|
32252
32203
|
var import_promises6 = require("fs/promises");
|
|
32253
32204
|
async function loadGitHubConfig({
|