@fern-api/generator-cli 0.10.2 → 0.10.4
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.js +279 -116
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -18618,10 +18618,10 @@ var require_resolve_block_map = __commonJS({
|
|
|
18618
18618
|
let offset = bm.offset;
|
|
18619
18619
|
let commentEnd = null;
|
|
18620
18620
|
for (const collItem of bm.items) {
|
|
18621
|
-
const { start, key, sep:
|
|
18621
|
+
const { start, key, sep: sep4, value } = collItem;
|
|
18622
18622
|
const keyProps = resolveProps.resolveProps(start, {
|
|
18623
18623
|
indicator: "explicit-key-ind",
|
|
18624
|
-
next: key ??
|
|
18624
|
+
next: key ?? sep4?.[0],
|
|
18625
18625
|
offset,
|
|
18626
18626
|
onError: onError2,
|
|
18627
18627
|
parentIndent: bm.indent,
|
|
@@ -18635,7 +18635,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
18635
18635
|
else if ("indent" in key && key.indent !== bm.indent)
|
|
18636
18636
|
onError2(offset, "BAD_INDENT", startColMsg);
|
|
18637
18637
|
}
|
|
18638
|
-
if (!keyProps.anchor && !keyProps.tag && !
|
|
18638
|
+
if (!keyProps.anchor && !keyProps.tag && !sep4) {
|
|
18639
18639
|
commentEnd = keyProps.end;
|
|
18640
18640
|
if (keyProps.comment) {
|
|
18641
18641
|
if (map.comment)
|
|
@@ -18659,7 +18659,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
18659
18659
|
ctx.atKey = false;
|
|
18660
18660
|
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
|
|
18661
18661
|
onError2(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
|
18662
|
-
const valueProps = resolveProps.resolveProps(
|
|
18662
|
+
const valueProps = resolveProps.resolveProps(sep4 ?? [], {
|
|
18663
18663
|
indicator: "map-value-ind",
|
|
18664
18664
|
next: value,
|
|
18665
18665
|
offset: keyNode.range[2],
|
|
@@ -18675,7 +18675,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
18675
18675
|
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
|
|
18676
18676
|
onError2(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
|
|
18677
18677
|
}
|
|
18678
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError2) : composeEmptyNode(ctx, offset,
|
|
18678
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError2) : composeEmptyNode(ctx, offset, sep4, null, valueProps, onError2);
|
|
18679
18679
|
if (ctx.schema.compat)
|
|
18680
18680
|
utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError2);
|
|
18681
18681
|
offset = valueNode.range[2];
|
|
@@ -18766,7 +18766,7 @@ var require_resolve_end = __commonJS({
|
|
|
18766
18766
|
let comment = "";
|
|
18767
18767
|
if (end) {
|
|
18768
18768
|
let hasSpace = false;
|
|
18769
|
-
let
|
|
18769
|
+
let sep4 = "";
|
|
18770
18770
|
for (const token of end) {
|
|
18771
18771
|
const { source, type } = token;
|
|
18772
18772
|
switch (type) {
|
|
@@ -18780,13 +18780,13 @@ var require_resolve_end = __commonJS({
|
|
|
18780
18780
|
if (!comment)
|
|
18781
18781
|
comment = cb;
|
|
18782
18782
|
else
|
|
18783
|
-
comment +=
|
|
18784
|
-
|
|
18783
|
+
comment += sep4 + cb;
|
|
18784
|
+
sep4 = "";
|
|
18785
18785
|
break;
|
|
18786
18786
|
}
|
|
18787
18787
|
case "newline":
|
|
18788
18788
|
if (comment)
|
|
18789
|
-
|
|
18789
|
+
sep4 += source;
|
|
18790
18790
|
hasSpace = true;
|
|
18791
18791
|
break;
|
|
18792
18792
|
default:
|
|
@@ -18829,18 +18829,18 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
18829
18829
|
let offset = fc.offset + fc.start.source.length;
|
|
18830
18830
|
for (let i2 = 0; i2 < fc.items.length; ++i2) {
|
|
18831
18831
|
const collItem = fc.items[i2];
|
|
18832
|
-
const { start, key, sep:
|
|
18832
|
+
const { start, key, sep: sep4, value } = collItem;
|
|
18833
18833
|
const props = resolveProps.resolveProps(start, {
|
|
18834
18834
|
flow: fcName,
|
|
18835
18835
|
indicator: "explicit-key-ind",
|
|
18836
|
-
next: key ??
|
|
18836
|
+
next: key ?? sep4?.[0],
|
|
18837
18837
|
offset,
|
|
18838
18838
|
onError: onError2,
|
|
18839
18839
|
parentIndent: fc.indent,
|
|
18840
18840
|
startOnNewline: false
|
|
18841
18841
|
});
|
|
18842
18842
|
if (!props.found) {
|
|
18843
|
-
if (!props.anchor && !props.tag && !
|
|
18843
|
+
if (!props.anchor && !props.tag && !sep4 && !value) {
|
|
18844
18844
|
if (i2 === 0 && props.comma)
|
|
18845
18845
|
onError2(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
|
18846
18846
|
else if (i2 < fc.items.length - 1)
|
|
@@ -18894,8 +18894,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
18894
18894
|
}
|
|
18895
18895
|
}
|
|
18896
18896
|
}
|
|
18897
|
-
if (!isMap && !
|
|
18898
|
-
const valueNode = value ? composeNode(ctx, value, props, onError2) : composeEmptyNode(ctx, props.end,
|
|
18897
|
+
if (!isMap && !sep4 && !props.found) {
|
|
18898
|
+
const valueNode = value ? composeNode(ctx, value, props, onError2) : composeEmptyNode(ctx, props.end, sep4, null, props, onError2);
|
|
18899
18899
|
coll.items.push(valueNode);
|
|
18900
18900
|
offset = valueNode.range[2];
|
|
18901
18901
|
if (isBlock(value))
|
|
@@ -18907,7 +18907,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
18907
18907
|
if (isBlock(key))
|
|
18908
18908
|
onError2(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
18909
18909
|
ctx.atKey = false;
|
|
18910
|
-
const valueProps = resolveProps.resolveProps(
|
|
18910
|
+
const valueProps = resolveProps.resolveProps(sep4 ?? [], {
|
|
18911
18911
|
flow: fcName,
|
|
18912
18912
|
indicator: "map-value-ind",
|
|
18913
18913
|
next: value,
|
|
@@ -18918,8 +18918,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
18918
18918
|
});
|
|
18919
18919
|
if (valueProps.found) {
|
|
18920
18920
|
if (!isMap && !props.found && ctx.options.strict) {
|
|
18921
|
-
if (
|
|
18922
|
-
for (const st of
|
|
18921
|
+
if (sep4)
|
|
18922
|
+
for (const st of sep4) {
|
|
18923
18923
|
if (st === valueProps.found)
|
|
18924
18924
|
break;
|
|
18925
18925
|
if (st.type === "newline") {
|
|
@@ -18936,7 +18936,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
18936
18936
|
else
|
|
18937
18937
|
onError2(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
|
|
18938
18938
|
}
|
|
18939
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError2) : valueProps.found ? composeEmptyNode(ctx, valueProps.end,
|
|
18939
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError2) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep4, null, valueProps, onError2) : null;
|
|
18940
18940
|
if (valueNode) {
|
|
18941
18941
|
if (isBlock(value))
|
|
18942
18942
|
onError2(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
@@ -19116,7 +19116,7 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
19116
19116
|
chompStart = i2 + 1;
|
|
19117
19117
|
}
|
|
19118
19118
|
let value = "";
|
|
19119
|
-
let
|
|
19119
|
+
let sep4 = "";
|
|
19120
19120
|
let prevMoreIndented = false;
|
|
19121
19121
|
for (let i2 = 0; i2 < contentStart; ++i2)
|
|
19122
19122
|
value += lines[i2][0].slice(trimIndent) + "\n";
|
|
@@ -19133,24 +19133,24 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
19133
19133
|
indent = "";
|
|
19134
19134
|
}
|
|
19135
19135
|
if (type === Scalar.Scalar.BLOCK_LITERAL) {
|
|
19136
|
-
value +=
|
|
19137
|
-
|
|
19136
|
+
value += sep4 + indent.slice(trimIndent) + content;
|
|
19137
|
+
sep4 = "\n";
|
|
19138
19138
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
19139
|
-
if (
|
|
19140
|
-
|
|
19141
|
-
else if (!prevMoreIndented &&
|
|
19142
|
-
|
|
19143
|
-
value +=
|
|
19144
|
-
|
|
19139
|
+
if (sep4 === " ")
|
|
19140
|
+
sep4 = "\n";
|
|
19141
|
+
else if (!prevMoreIndented && sep4 === "\n")
|
|
19142
|
+
sep4 = "\n\n";
|
|
19143
|
+
value += sep4 + indent.slice(trimIndent) + content;
|
|
19144
|
+
sep4 = "\n";
|
|
19145
19145
|
prevMoreIndented = true;
|
|
19146
19146
|
} else if (content === "") {
|
|
19147
|
-
if (
|
|
19147
|
+
if (sep4 === "\n")
|
|
19148
19148
|
value += "\n";
|
|
19149
19149
|
else
|
|
19150
|
-
|
|
19150
|
+
sep4 = "\n";
|
|
19151
19151
|
} else {
|
|
19152
|
-
value +=
|
|
19153
|
-
|
|
19152
|
+
value += sep4 + content;
|
|
19153
|
+
sep4 = " ";
|
|
19154
19154
|
prevMoreIndented = false;
|
|
19155
19155
|
}
|
|
19156
19156
|
}
|
|
@@ -19332,25 +19332,25 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
19332
19332
|
if (!match2)
|
|
19333
19333
|
return source;
|
|
19334
19334
|
let res = match2[1];
|
|
19335
|
-
let
|
|
19335
|
+
let sep4 = " ";
|
|
19336
19336
|
let pos = first2.lastIndex;
|
|
19337
19337
|
line.lastIndex = pos;
|
|
19338
19338
|
while (match2 = line.exec(source)) {
|
|
19339
19339
|
if (match2[1] === "") {
|
|
19340
|
-
if (
|
|
19341
|
-
res +=
|
|
19340
|
+
if (sep4 === "\n")
|
|
19341
|
+
res += sep4;
|
|
19342
19342
|
else
|
|
19343
|
-
|
|
19343
|
+
sep4 = "\n";
|
|
19344
19344
|
} else {
|
|
19345
|
-
res +=
|
|
19346
|
-
|
|
19345
|
+
res += sep4 + match2[1];
|
|
19346
|
+
sep4 = " ";
|
|
19347
19347
|
}
|
|
19348
19348
|
pos = line.lastIndex;
|
|
19349
19349
|
}
|
|
19350
19350
|
const last2 = /[ \t]*(.*)/sy;
|
|
19351
19351
|
last2.lastIndex = pos;
|
|
19352
19352
|
match2 = last2.exec(source);
|
|
19353
|
-
return res +
|
|
19353
|
+
return res + sep4 + (match2?.[1] ?? "");
|
|
19354
19354
|
}
|
|
19355
19355
|
function doubleQuotedValue(source, onError2) {
|
|
19356
19356
|
let res = "";
|
|
@@ -20157,14 +20157,14 @@ var require_cst_stringify = __commonJS({
|
|
|
20157
20157
|
}
|
|
20158
20158
|
}
|
|
20159
20159
|
}
|
|
20160
|
-
function stringifyItem({ start, key, sep:
|
|
20160
|
+
function stringifyItem({ start, key, sep: sep4, value }) {
|
|
20161
20161
|
let res = "";
|
|
20162
20162
|
for (const st of start)
|
|
20163
20163
|
res += st.source;
|
|
20164
20164
|
if (key)
|
|
20165
20165
|
res += stringifyToken(key);
|
|
20166
|
-
if (
|
|
20167
|
-
for (const st of
|
|
20166
|
+
if (sep4)
|
|
20167
|
+
for (const st of sep4)
|
|
20168
20168
|
res += st.source;
|
|
20169
20169
|
if (value)
|
|
20170
20170
|
res += stringifyToken(value);
|
|
@@ -21314,18 +21314,18 @@ var require_parser = __commonJS({
|
|
|
21314
21314
|
if (this.type === "map-value-ind") {
|
|
21315
21315
|
const prev = getPrevProps(this.peek(2));
|
|
21316
21316
|
const start = getFirstKeyStartProps(prev);
|
|
21317
|
-
let
|
|
21317
|
+
let sep4;
|
|
21318
21318
|
if (scalar.end) {
|
|
21319
|
-
|
|
21320
|
-
|
|
21319
|
+
sep4 = scalar.end;
|
|
21320
|
+
sep4.push(this.sourceToken);
|
|
21321
21321
|
delete scalar.end;
|
|
21322
21322
|
} else
|
|
21323
|
-
|
|
21323
|
+
sep4 = [this.sourceToken];
|
|
21324
21324
|
const map = {
|
|
21325
21325
|
type: "block-map",
|
|
21326
21326
|
offset: scalar.offset,
|
|
21327
21327
|
indent: scalar.indent,
|
|
21328
|
-
items: [{ start, key: scalar, sep:
|
|
21328
|
+
items: [{ start, key: scalar, sep: sep4 }]
|
|
21329
21329
|
};
|
|
21330
21330
|
this.onKeyLine = true;
|
|
21331
21331
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -21478,15 +21478,15 @@ var require_parser = __commonJS({
|
|
|
21478
21478
|
} else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
|
|
21479
21479
|
const start2 = getFirstKeyStartProps(it.start);
|
|
21480
21480
|
const key = it.key;
|
|
21481
|
-
const
|
|
21482
|
-
|
|
21481
|
+
const sep4 = it.sep;
|
|
21482
|
+
sep4.push(this.sourceToken);
|
|
21483
21483
|
delete it.key;
|
|
21484
21484
|
delete it.sep;
|
|
21485
21485
|
this.stack.push({
|
|
21486
21486
|
type: "block-map",
|
|
21487
21487
|
offset: this.offset,
|
|
21488
21488
|
indent: this.indent,
|
|
21489
|
-
items: [{ start: start2, key, sep:
|
|
21489
|
+
items: [{ start: start2, key, sep: sep4 }]
|
|
21490
21490
|
});
|
|
21491
21491
|
} else if (start.length > 0) {
|
|
21492
21492
|
it.sep = it.sep.concat(start, this.sourceToken);
|
|
@@ -21680,13 +21680,13 @@ var require_parser = __commonJS({
|
|
|
21680
21680
|
const prev = getPrevProps(parent);
|
|
21681
21681
|
const start = getFirstKeyStartProps(prev);
|
|
21682
21682
|
fixFlowSeqItems(fc);
|
|
21683
|
-
const
|
|
21684
|
-
|
|
21683
|
+
const sep4 = fc.end.splice(1, fc.end.length);
|
|
21684
|
+
sep4.push(this.sourceToken);
|
|
21685
21685
|
const map = {
|
|
21686
21686
|
type: "block-map",
|
|
21687
21687
|
offset: fc.offset,
|
|
21688
21688
|
indent: fc.indent,
|
|
21689
|
-
items: [{ start, key: fc, sep:
|
|
21689
|
+
items: [{ start, key: fc, sep: sep4 }]
|
|
21690
21690
|
};
|
|
21691
21691
|
this.onKeyLine = true;
|
|
21692
21692
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -36523,6 +36523,11 @@ function escape3(string2) {
|
|
|
36523
36523
|
return escape2(toString(string2));
|
|
36524
36524
|
}
|
|
36525
36525
|
|
|
36526
|
+
// ../../node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/escapeRegExp.mjs
|
|
36527
|
+
function escapeRegExp(str) {
|
|
36528
|
+
return str.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
|
|
36529
|
+
}
|
|
36530
|
+
|
|
36526
36531
|
// ../../node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/snakeCase.mjs
|
|
36527
36532
|
function snakeCase(str) {
|
|
36528
36533
|
const words$1 = words(str);
|
|
@@ -40740,6 +40745,9 @@ function countFilesInDiff(diffContent) {
|
|
|
40740
40745
|
function formatSizeKB(charLength) {
|
|
40741
40746
|
return (charLength / 1024).toFixed(1);
|
|
40742
40747
|
}
|
|
40748
|
+
function magicVersionRegExp(mappedMagicVersion) {
|
|
40749
|
+
return new RegExp(`(?<![0-9.])${escapeRegExp(mappedMagicVersion)}(?![0-9A-Za-z-]|\\.[0-9A-Za-z])`, "g");
|
|
40750
|
+
}
|
|
40743
40751
|
var EXCLUDED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
40744
40752
|
// Version control
|
|
40745
40753
|
".git",
|
|
@@ -41524,7 +41532,10 @@ var AutoVersioningService = class _AutoVersioningService {
|
|
|
41524
41532
|
*/
|
|
41525
41533
|
async replaceMagicVersion(workingDirectory, mappedMagicVersion, finalVersion) {
|
|
41526
41534
|
this.logger.debug(`Replacing placeholder version ${mappedMagicVersion} with final version: ${finalVersion}`);
|
|
41527
|
-
const
|
|
41535
|
+
const allFiles = await this.walkDirectory(workingDirectory, () => true);
|
|
41536
|
+
const fernignoredFiles = await this.getFernignoredFiles(workingDirectory, allFiles);
|
|
41537
|
+
const files = allFiles.filter((filePath) => !fernignoredFiles.has(filePath));
|
|
41538
|
+
const magicVersionPattern = magicVersionRegExp(mappedMagicVersion);
|
|
41528
41539
|
const replaceInFile = async (filePath) => {
|
|
41529
41540
|
if (await this.isBinaryFile(filePath)) {
|
|
41530
41541
|
return false;
|
|
@@ -41533,7 +41544,10 @@ var AutoVersioningService = class _AutoVersioningService {
|
|
|
41533
41544
|
if (!content.includes(mappedMagicVersion)) {
|
|
41534
41545
|
return false;
|
|
41535
41546
|
}
|
|
41536
|
-
const updated = content.
|
|
41547
|
+
const updated = content.replace(magicVersionPattern, () => finalVersion);
|
|
41548
|
+
if (updated === content) {
|
|
41549
|
+
return false;
|
|
41550
|
+
}
|
|
41537
41551
|
await (0, import_promises15.writeFile)(filePath, updated, "utf-8");
|
|
41538
41552
|
return true;
|
|
41539
41553
|
};
|
|
@@ -41638,6 +41652,28 @@ var AutoVersioningService = class _AutoVersioningService {
|
|
|
41638
41652
|
this.logger.debug(`Updated go.mod: added ${suffix} to module path`);
|
|
41639
41653
|
}
|
|
41640
41654
|
}
|
|
41655
|
+
/**
|
|
41656
|
+
* Files protected by `.fernignore` hold customer-owned content, so the placeholder
|
|
41657
|
+
* must never be rewritten inside them (e.g. docs that mention `0.0.0-fern-placeholder`).
|
|
41658
|
+
*/
|
|
41659
|
+
async getFernignoredFiles(workingDirectory, files) {
|
|
41660
|
+
const fernignorePath = (0, import_path23.join)(workingDirectory, ".fernignore");
|
|
41661
|
+
let fernignoreContent;
|
|
41662
|
+
try {
|
|
41663
|
+
fernignoreContent = await (0, import_promises15.readFile)(fernignorePath, "utf-8");
|
|
41664
|
+
} catch {
|
|
41665
|
+
return /* @__PURE__ */ new Set();
|
|
41666
|
+
}
|
|
41667
|
+
const relativePaths = new Map(
|
|
41668
|
+
files.map((filePath) => [(0, import_path23.relative)(workingDirectory, filePath).split(import_path23.sep).join("/"), filePath])
|
|
41669
|
+
);
|
|
41670
|
+
return /* @__PURE__ */ new Set([
|
|
41671
|
+
fernignorePath,
|
|
41672
|
+
...expandFernignorePatterns(fernignoreContent, [...relativePaths.keys()]).map(
|
|
41673
|
+
(relativePath) => relativePaths.get(relativePath) ?? relativePath
|
|
41674
|
+
)
|
|
41675
|
+
]);
|
|
41676
|
+
}
|
|
41641
41677
|
/**
|
|
41642
41678
|
* Recursively walks a directory and returns all file paths matching a filter.
|
|
41643
41679
|
*/
|
|
@@ -42017,36 +42053,24 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42017
42053
|
});
|
|
42018
42054
|
}
|
|
42019
42055
|
if (cleanedBytes > MAX_RAW_DIFF_BYTES) {
|
|
42020
|
-
|
|
42021
|
-
|
|
42022
|
-
);
|
|
42056
|
+
const warning = `diff too large for FAI (${formatSizeKB(cleanedBytes)}KB, limit ${formatSizeKB(MAX_RAW_DIFF_BYTES)}KB)`;
|
|
42057
|
+
this.logger.warn(`AutoVersionStep: ${warning}. Falling back to PATCH.`);
|
|
42023
42058
|
return await this.finalizeWithBump({
|
|
42024
42059
|
service,
|
|
42025
42060
|
language,
|
|
42026
42061
|
mappedMagicVersion,
|
|
42027
42062
|
previousVersion,
|
|
42028
|
-
analysis:
|
|
42063
|
+
analysis: this.fallbackPatchAnalysis(),
|
|
42064
|
+
analysisWarning: warning
|
|
42029
42065
|
});
|
|
42030
42066
|
}
|
|
42031
|
-
|
|
42032
|
-
|
|
42033
|
-
|
|
42034
|
-
|
|
42035
|
-
|
|
42036
|
-
|
|
42037
|
-
|
|
42038
|
-
const skippedChunks = chunks.length - cappedChunks.length;
|
|
42039
|
-
if (chunks.length > 1) {
|
|
42040
|
-
this.logger.info(
|
|
42041
|
-
`AutoVersionStep: split diff into ${chunks.length} chunks` + (skippedChunks > 0 ? ` (capped at ${MAX_CHUNKS}, skipping ${skippedChunks})` : "")
|
|
42042
|
-
);
|
|
42043
|
-
}
|
|
42044
|
-
analysis = cappedChunks.length <= 1 ? await this.analyzeSingle(cleanedDiff, language, previousVersion) : await this.analyzeChunks(cappedChunks, language, previousVersion);
|
|
42045
|
-
}
|
|
42046
|
-
} catch (error) {
|
|
42047
|
-
this.logger.warn(`AutoVersionStep: FAI analysis failed (${String(error)}); falling back to PATCH bump.`);
|
|
42048
|
-
analysis = { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") };
|
|
42049
|
-
}
|
|
42067
|
+
const { analysis, analysisWarning } = await this.analyze({
|
|
42068
|
+
service,
|
|
42069
|
+
cleanedDiff,
|
|
42070
|
+
language,
|
|
42071
|
+
previousVersion,
|
|
42072
|
+
label: "AutoVersionStep"
|
|
42073
|
+
});
|
|
42050
42074
|
if (analysis == null) {
|
|
42051
42075
|
this.logger.info(`AutoVersionStep: FAI returned NO_CHANGE; rewriting placeholder to ${previousVersion}.`);
|
|
42052
42076
|
return await this.finalizeNoChange({
|
|
@@ -42054,7 +42078,8 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42054
42078
|
language,
|
|
42055
42079
|
mappedMagicVersion,
|
|
42056
42080
|
previousVersion,
|
|
42057
|
-
reason: "FAI returned NO_CHANGE"
|
|
42081
|
+
reason: "FAI returned NO_CHANGE",
|
|
42082
|
+
analysisWarning
|
|
42058
42083
|
});
|
|
42059
42084
|
}
|
|
42060
42085
|
return await this.finalizeWithBump({
|
|
@@ -42062,7 +42087,8 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42062
42087
|
language,
|
|
42063
42088
|
mappedMagicVersion,
|
|
42064
42089
|
previousVersion,
|
|
42065
|
-
analysis
|
|
42090
|
+
analysis,
|
|
42091
|
+
analysisWarning
|
|
42066
42092
|
});
|
|
42067
42093
|
}
|
|
42068
42094
|
/**
|
|
@@ -42113,38 +42139,24 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42113
42139
|
});
|
|
42114
42140
|
}
|
|
42115
42141
|
if (cleanedBytes > MAX_RAW_DIFF_BYTES) {
|
|
42116
|
-
|
|
42117
|
-
|
|
42118
|
-
);
|
|
42142
|
+
const warning = `diff too large for FAI (${formatSizeKB(cleanedBytes)}KB, limit ${formatSizeKB(MAX_RAW_DIFF_BYTES)}KB)`;
|
|
42143
|
+
this.logger.warn(`AutoVersionStep (non-replay): ${warning}. Falling back to PATCH.`);
|
|
42119
42144
|
return await this.finalizeWithBumpNonReplay({
|
|
42120
42145
|
service,
|
|
42121
42146
|
language,
|
|
42122
42147
|
mappedMagicVersion,
|
|
42123
42148
|
previousVersion,
|
|
42124
|
-
analysis:
|
|
42149
|
+
analysis: this.fallbackPatchAnalysis(),
|
|
42150
|
+
analysisWarning: warning
|
|
42125
42151
|
});
|
|
42126
42152
|
}
|
|
42127
|
-
|
|
42128
|
-
|
|
42129
|
-
|
|
42130
|
-
|
|
42131
|
-
|
|
42132
|
-
|
|
42133
|
-
|
|
42134
|
-
const skippedChunks = chunks.length - cappedChunks.length;
|
|
42135
|
-
if (chunks.length > 1) {
|
|
42136
|
-
this.logger.info(
|
|
42137
|
-
`AutoVersionStep (non-replay): split diff into ${chunks.length} chunks` + (skippedChunks > 0 ? ` (capped at ${MAX_CHUNKS}, skipping ${skippedChunks})` : "")
|
|
42138
|
-
);
|
|
42139
|
-
}
|
|
42140
|
-
analysis = cappedChunks.length <= 1 ? await this.analyzeSingle(cleanedDiff, language, previousVersion) : await this.analyzeChunks(cappedChunks, language, previousVersion);
|
|
42141
|
-
}
|
|
42142
|
-
} catch (error) {
|
|
42143
|
-
this.logger.warn(
|
|
42144
|
-
`AutoVersionStep (non-replay): FAI analysis failed (${String(error)}); falling back to PATCH bump.`
|
|
42145
|
-
);
|
|
42146
|
-
analysis = { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") };
|
|
42147
|
-
}
|
|
42153
|
+
const { analysis, analysisWarning } = await this.analyze({
|
|
42154
|
+
service,
|
|
42155
|
+
cleanedDiff,
|
|
42156
|
+
language,
|
|
42157
|
+
previousVersion,
|
|
42158
|
+
label: "AutoVersionStep (non-replay)"
|
|
42159
|
+
});
|
|
42148
42160
|
if (analysis == null) {
|
|
42149
42161
|
this.logger.info(
|
|
42150
42162
|
`AutoVersionStep (non-replay): FAI returned NO_CHANGE; rewriting placeholder to ${previousVersion}.`
|
|
@@ -42154,7 +42166,8 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42154
42166
|
language,
|
|
42155
42167
|
mappedMagicVersion,
|
|
42156
42168
|
previousVersion,
|
|
42157
|
-
reason: "FAI returned NO_CHANGE"
|
|
42169
|
+
reason: "FAI returned NO_CHANGE",
|
|
42170
|
+
analysisWarning
|
|
42158
42171
|
});
|
|
42159
42172
|
}
|
|
42160
42173
|
return await this.finalizeWithBumpNonReplay({
|
|
@@ -42162,9 +42175,72 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42162
42175
|
language,
|
|
42163
42176
|
mappedMagicVersion,
|
|
42164
42177
|
previousVersion,
|
|
42165
|
-
analysis
|
|
42178
|
+
analysis,
|
|
42179
|
+
analysisWarning
|
|
42166
42180
|
});
|
|
42167
42181
|
}
|
|
42182
|
+
fallbackPatchAnalysis() {
|
|
42183
|
+
return { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") };
|
|
42184
|
+
}
|
|
42185
|
+
/**
|
|
42186
|
+
* Runs FAI analysis over the cleaned diff. Never throws: when analysis cannot be
|
|
42187
|
+
* obtained at all, returns a PATCH fallback together with an `analysisWarning`
|
|
42188
|
+
* describing why, so callers can surface it in the step result / PR body instead
|
|
42189
|
+
* of shipping a silent PATCH for what may be a breaking change.
|
|
42190
|
+
*/
|
|
42191
|
+
async analyze(params) {
|
|
42192
|
+
const { service, cleanedDiff, language, previousVersion, label } = params;
|
|
42193
|
+
const chunks = service.chunkDiff(cleanedDiff, MAX_AI_DIFF_BYTES);
|
|
42194
|
+
const cappedChunks = chunks.slice(0, MAX_CHUNKS);
|
|
42195
|
+
const skippedChunks = chunks.length - cappedChunks.length;
|
|
42196
|
+
const logSplit = () => {
|
|
42197
|
+
if (chunks.length > 1) {
|
|
42198
|
+
this.logger.info(
|
|
42199
|
+
`${label}: split diff into ${chunks.length} chunks` + (skippedChunks > 0 ? ` (capped at ${MAX_CHUNKS}, skipping ${skippedChunks})` : "")
|
|
42200
|
+
);
|
|
42201
|
+
}
|
|
42202
|
+
};
|
|
42203
|
+
try {
|
|
42204
|
+
if (this.config.ai == null && this.config.fernToken != null) {
|
|
42205
|
+
try {
|
|
42206
|
+
return { analysis: await this.analyzeViaFaiService(cleanedDiff, language, previousVersion) };
|
|
42207
|
+
} catch (error) {
|
|
42208
|
+
if (cappedChunks.length <= 1) {
|
|
42209
|
+
throw error;
|
|
42210
|
+
}
|
|
42211
|
+
this.logger.warn(
|
|
42212
|
+
`${label}: FAI analysis of the full diff failed (${String(error)}); retrying in ${cappedChunks.length} chunks.`
|
|
42213
|
+
);
|
|
42214
|
+
logSplit();
|
|
42215
|
+
const chunked = await this.analyzeChunksViaFaiService(
|
|
42216
|
+
cappedChunks,
|
|
42217
|
+
language,
|
|
42218
|
+
previousVersion,
|
|
42219
|
+
label
|
|
42220
|
+
);
|
|
42221
|
+
const warnings = [chunked.analysisWarning];
|
|
42222
|
+
if (skippedChunks > 0) {
|
|
42223
|
+
warnings.push(
|
|
42224
|
+
`${skippedChunks} of ${chunks.length} diff chunks were not analyzed (capped at ${MAX_CHUNKS})`
|
|
42225
|
+
);
|
|
42226
|
+
}
|
|
42227
|
+
const analysisWarning = warnings.filter(hasText).join("; ");
|
|
42228
|
+
return {
|
|
42229
|
+
analysis: chunked.analysis,
|
|
42230
|
+
analysisWarning: analysisWarning.length > 0 ? analysisWarning : void 0
|
|
42231
|
+
};
|
|
42232
|
+
}
|
|
42233
|
+
}
|
|
42234
|
+
logSplit();
|
|
42235
|
+
return {
|
|
42236
|
+
analysis: cappedChunks.length <= 1 ? await this.analyzeSingle(cleanedDiff, language, previousVersion) : await this.analyzeChunks(cappedChunks, language, previousVersion)
|
|
42237
|
+
};
|
|
42238
|
+
} catch (error) {
|
|
42239
|
+
const warning = `FAI analysis failed (${String(error)})`;
|
|
42240
|
+
this.logger.warn(`${label}: ${warning}; falling back to PATCH bump.`);
|
|
42241
|
+
return { analysis: this.fallbackPatchAnalysis(), analysisWarning: warning };
|
|
42242
|
+
}
|
|
42243
|
+
}
|
|
42168
42244
|
/**
|
|
42169
42245
|
* Terminal path for runs that determine no semver bump is needed. The
|
|
42170
42246
|
* current working tree still contains `0.0.0-fern-placeholder` from this
|
|
@@ -42175,7 +42251,7 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42175
42251
|
* `[fern-autoversion]` so the replay + github steps see a stable base.
|
|
42176
42252
|
*/
|
|
42177
42253
|
async finalizeNoChange(params) {
|
|
42178
|
-
const { service, language, mappedMagicVersion, previousVersion, reason } = params;
|
|
42254
|
+
const { service, language, mappedMagicVersion, previousVersion, reason, analysisWarning } = params;
|
|
42179
42255
|
if (!isValidSemver(previousVersion)) {
|
|
42180
42256
|
const errorMessage = `AutoVersionStep: resolved previousVersion ${JSON.stringify(previousVersion)} is not a valid semver string. Refusing to rewrite placeholder to avoid shell injection.`;
|
|
42181
42257
|
this.logger.error(errorMessage);
|
|
@@ -42194,11 +42270,12 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42194
42270
|
previousVersion,
|
|
42195
42271
|
versionBump: "NO_CHANGE",
|
|
42196
42272
|
commitMessage,
|
|
42197
|
-
commitSha
|
|
42273
|
+
commitSha,
|
|
42274
|
+
analysisWarning
|
|
42198
42275
|
};
|
|
42199
42276
|
}
|
|
42200
42277
|
async finalizeWithBump(params) {
|
|
42201
|
-
const { service, language, mappedMagicVersion, previousVersion } = params;
|
|
42278
|
+
const { service, language, mappedMagicVersion, previousVersion, analysisWarning } = params;
|
|
42202
42279
|
const analysis = this.withChangelogFallback(params.analysis);
|
|
42203
42280
|
const newVersion = incrementVersion(previousVersion, analysis.versionBump);
|
|
42204
42281
|
this.logger.info(`AutoVersionStep: ${analysis.versionBump} bump: ${previousVersion} \u2192 ${newVersion}`);
|
|
@@ -42220,6 +42297,7 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42220
42297
|
versionBump: analysis.versionBump,
|
|
42221
42298
|
prDescription: analysis.prDescription,
|
|
42222
42299
|
versionBumpReason: analysis.versionBumpReason,
|
|
42300
|
+
analysisWarning,
|
|
42223
42301
|
commitSha
|
|
42224
42302
|
};
|
|
42225
42303
|
}
|
|
@@ -42228,7 +42306,7 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42228
42306
|
* `previousVersion` but does NOT commit — GithubStep handles the commit.
|
|
42229
42307
|
*/
|
|
42230
42308
|
async finalizeNoChangeNonReplay(params) {
|
|
42231
|
-
const { service, language, mappedMagicVersion, previousVersion, reason } = params;
|
|
42309
|
+
const { service, language, mappedMagicVersion, previousVersion, reason, analysisWarning } = params;
|
|
42232
42310
|
if (!isValidSemver(previousVersion)) {
|
|
42233
42311
|
const errorMessage = `AutoVersionStep: resolved previousVersion ${JSON.stringify(previousVersion)} is not a valid semver string. Refusing to rewrite placeholder to avoid shell injection.`;
|
|
42234
42312
|
this.logger.error(errorMessage);
|
|
@@ -42245,7 +42323,8 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42245
42323
|
version: previousVersion,
|
|
42246
42324
|
previousVersion,
|
|
42247
42325
|
versionBump: "NO_CHANGE",
|
|
42248
|
-
commitMessage
|
|
42326
|
+
commitMessage,
|
|
42327
|
+
analysisWarning
|
|
42249
42328
|
};
|
|
42250
42329
|
}
|
|
42251
42330
|
/**
|
|
@@ -42253,7 +42332,7 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42253
42332
|
* the bumped version but does NOT commit — GithubStep handles the commit.
|
|
42254
42333
|
*/
|
|
42255
42334
|
async finalizeWithBumpNonReplay(params) {
|
|
42256
|
-
const { service, language, mappedMagicVersion, previousVersion } = params;
|
|
42335
|
+
const { service, language, mappedMagicVersion, previousVersion, analysisWarning } = params;
|
|
42257
42336
|
const analysis = this.withChangelogFallback(params.analysis);
|
|
42258
42337
|
const newVersion = incrementVersion(previousVersion, analysis.versionBump);
|
|
42259
42338
|
this.logger.info(
|
|
@@ -42275,7 +42354,8 @@ var AutoVersionStep = class extends BaseStep {
|
|
|
42275
42354
|
previousVersion,
|
|
42276
42355
|
versionBump: analysis.versionBump,
|
|
42277
42356
|
prDescription: analysis.prDescription,
|
|
42278
|
-
versionBumpReason: analysis.versionBumpReason
|
|
42357
|
+
versionBumpReason: analysis.versionBumpReason,
|
|
42358
|
+
analysisWarning
|
|
42279
42359
|
};
|
|
42280
42360
|
}
|
|
42281
42361
|
/**
|
|
@@ -42676,6 +42756,68 @@ ${body}` : `${COMMIT_MARKER} ${subject}`;
|
|
|
42676
42756
|
};
|
|
42677
42757
|
}
|
|
42678
42758
|
}
|
|
42759
|
+
/**
|
|
42760
|
+
* Chunked retry for the hosted FAI path. Each chunk is analyzed independently;
|
|
42761
|
+
* chunks whose request fails are skipped as long as at least one chunk succeeds,
|
|
42762
|
+
* and the partial coverage is reported via `analysisWarning` so the PR is flagged
|
|
42763
|
+
* and never automerged. Results are aggregated with the same max-bump rule as the
|
|
42764
|
+
* BAML path; entries are joined rather than consolidated (no hosted rollup endpoint).
|
|
42765
|
+
*/
|
|
42766
|
+
async analyzeChunksViaFaiService(chunks, language, previousVersion, label) {
|
|
42767
|
+
const chunkAnalyses = [];
|
|
42768
|
+
let attemptedChunks = 0;
|
|
42769
|
+
let failedChunks = 0;
|
|
42770
|
+
let lastError;
|
|
42771
|
+
for (let i2 = 0; i2 < chunks.length; i2++) {
|
|
42772
|
+
const chunk = chunks[i2];
|
|
42773
|
+
if (!chunk) {
|
|
42774
|
+
continue;
|
|
42775
|
+
}
|
|
42776
|
+
attemptedChunks++;
|
|
42777
|
+
let analysis;
|
|
42778
|
+
try {
|
|
42779
|
+
analysis = await this.analyzeViaFaiService(chunk, language, previousVersion);
|
|
42780
|
+
} catch (error) {
|
|
42781
|
+
failedChunks++;
|
|
42782
|
+
lastError = error;
|
|
42783
|
+
this.logger.warn(
|
|
42784
|
+
`${label}: FAI analysis of chunk ${i2 + 1}/${chunks.length} failed (${String(error)}).`
|
|
42785
|
+
);
|
|
42786
|
+
continue;
|
|
42787
|
+
}
|
|
42788
|
+
if (analysis == null) {
|
|
42789
|
+
continue;
|
|
42790
|
+
}
|
|
42791
|
+
chunkAnalyses.push(analysis);
|
|
42792
|
+
}
|
|
42793
|
+
if (failedChunks > 0 && failedChunks === attemptedChunks) {
|
|
42794
|
+
throw new Error(`all ${attemptedChunks} FAI chunk requests failed; last error: ${String(lastError)}`);
|
|
42795
|
+
}
|
|
42796
|
+
const analysisWarning = failedChunks > 0 ? `${failedChunks} of ${attemptedChunks} FAI chunk requests failed; last error: ${String(lastError)}` : void 0;
|
|
42797
|
+
if (chunkAnalyses.length === 0) {
|
|
42798
|
+
return { analysis: null, analysisWarning };
|
|
42799
|
+
}
|
|
42800
|
+
const { bestBump, bestMessage, bestVersionBumpReason, changelogEntries, usedBumpReasonAsEntry } = aggregateChunkAnalyses(chunkAnalyses);
|
|
42801
|
+
if (usedBumpReasonAsEntry) {
|
|
42802
|
+
this.logger.warn(
|
|
42803
|
+
`${label}: no chunk produced a changelog entry for the ${bestBump} bump; using its version bump reason instead.`
|
|
42804
|
+
);
|
|
42805
|
+
}
|
|
42806
|
+
if (analysisWarning != null) {
|
|
42807
|
+
this.logger.warn(`${label}: ${analysisWarning}; the ${bestBump} bump is based on the remaining chunks.`);
|
|
42808
|
+
}
|
|
42809
|
+
const prDescriptions = chunkAnalyses.filter((analysis) => analysis.versionBump === bestBump && hasText(analysis.prDescription)).map((analysis) => analysis.prDescription?.trim() ?? "");
|
|
42810
|
+
return {
|
|
42811
|
+
analysis: {
|
|
42812
|
+
versionBump: bestBump,
|
|
42813
|
+
message: bestMessage,
|
|
42814
|
+
changelogEntry: changelogEntries.length > 0 ? changelogEntries.join("\n\n") : void 0,
|
|
42815
|
+
prDescription: prDescriptions.length > 0 ? prDescriptions.join("\n\n") : void 0,
|
|
42816
|
+
versionBumpReason: bestVersionBumpReason
|
|
42817
|
+
},
|
|
42818
|
+
analysisWarning
|
|
42819
|
+
};
|
|
42820
|
+
}
|
|
42679
42821
|
/**
|
|
42680
42822
|
* Calls the hosted FAI service (`/sdks/analyze-commit-diff`) with the fern token.
|
|
42681
42823
|
* Used when no BAML `ai` config is supplied (remote generation via fiddle). FAI
|
|
@@ -42700,7 +42842,10 @@ ${body}` : `${COMMIT_MARKER} ${subject}`;
|
|
|
42700
42842
|
});
|
|
42701
42843
|
if (!response.ok) {
|
|
42702
42844
|
const body = await response.text().catch(() => "");
|
|
42703
|
-
|
|
42845
|
+
if (body.length > 0) {
|
|
42846
|
+
this.logger.debug(`AutoVersionStep: FAI analyze-commit-diff response body: ${body.slice(0, 500)}`);
|
|
42847
|
+
}
|
|
42848
|
+
throw new Error(`FAI analyze-commit-diff failed with status ${response.status}`);
|
|
42704
42849
|
}
|
|
42705
42850
|
const parsed = await response.json();
|
|
42706
42851
|
if (!isFaiAnalyzeResponse(parsed)) {
|
|
@@ -43500,6 +43645,7 @@ var GithubStep = class extends BaseStep {
|
|
|
43500
43645
|
);
|
|
43501
43646
|
const replaySection = formatReplayPrBody(replayResult, { branchName: prBranch, repoUri: this.config.uri });
|
|
43502
43647
|
let enrichedBody = replaySection != null ? prBody + "\n\n---\n\n" + replaySection : prBody;
|
|
43648
|
+
enrichedBody = appendAutoVersionWarning(enrichedBody, resolved.analysisWarning);
|
|
43503
43649
|
enrichedBody = enrichPrBodyForAutomation(enrichedBody, this.config, resolved);
|
|
43504
43650
|
if (isUpdatingExistingPR && existingPR != null) {
|
|
43505
43651
|
this.logger.info(`Updated existing pull request: ${existingPR.htmlUrl}`);
|
|
@@ -43758,9 +43904,25 @@ function resolvePrFields(config, autoVersion) {
|
|
|
43758
43904
|
newVersion: config.newVersion ?? autoVersion?.version,
|
|
43759
43905
|
versionBump: config.versionBump ?? autoVersion?.versionBump,
|
|
43760
43906
|
hasBreakingChanges: config.hasBreakingChanges ?? autoVersionBreaking,
|
|
43761
|
-
breakingChangesSummary: config.breakingChangesSummary ?? autoVersion?.prDescription
|
|
43907
|
+
breakingChangesSummary: config.breakingChangesSummary ?? autoVersion?.prDescription,
|
|
43908
|
+
analysisWarning: autoVersion?.analysisWarning
|
|
43762
43909
|
};
|
|
43763
43910
|
}
|
|
43911
|
+
function appendAutoVersionWarning(body, analysisWarning) {
|
|
43912
|
+
if (analysisWarning == null || analysisWarning.trim().length === 0) {
|
|
43913
|
+
return body;
|
|
43914
|
+
}
|
|
43915
|
+
const reason = analysisWarning.replace(/[`\s]+/g, " ").trim().slice(0, 300);
|
|
43916
|
+
return body + `
|
|
43917
|
+
|
|
43918
|
+
---
|
|
43919
|
+
|
|
43920
|
+
## \u26A0\uFE0F Version bump not verified
|
|
43921
|
+
|
|
43922
|
+
Automatic version analysis was unavailable or incomplete for this generation, so the version bump and changelog may understate the changes (a **PATCH** bump with no changelog is applied when no analysis is available). If this change is breaking or adds features, adjust the version and changelog before merging.
|
|
43923
|
+
|
|
43924
|
+
Reason: \`${reason}\``;
|
|
43925
|
+
}
|
|
43764
43926
|
function enrichPrBodyForAutomation(body, config, breaking = {}) {
|
|
43765
43927
|
if (!config.automationMode) {
|
|
43766
43928
|
return body;
|
|
@@ -43782,7 +43944,8 @@ _Fern Run ID: \`${config.runId}\`_`;
|
|
|
43782
43944
|
}
|
|
43783
43945
|
function shouldEnableAutomerge(config, breaking = {}) {
|
|
43784
43946
|
const hasBreakingChanges = breaking.hasBreakingChanges ?? config.hasBreakingChanges;
|
|
43785
|
-
|
|
43947
|
+
const analysisUnavailable = breaking.analysisWarning != null && breaking.analysisWarning.length > 0;
|
|
43948
|
+
return config.automationMode === true && config.autoMerge === true && hasBreakingChanges !== true && !analysisUnavailable;
|
|
43786
43949
|
}
|
|
43787
43950
|
function shouldCheckNoDiff(config) {
|
|
43788
43951
|
return config.skipIfNoDiff === true;
|