gitlab-ai-review 3.9.1 → 4.0.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/index.js +58 -10
- package/lib/diff-parser.js +12 -0
- package/lib/gitlab-client.js +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -205,19 +205,53 @@ export class GitLabAIReview {
|
|
|
205
205
|
// 调用 AI 一次性审查整个文件的所有变更(按文件批量)
|
|
206
206
|
const fileReview = await this.reviewFileChanges(change, meaningfulChanges);
|
|
207
207
|
|
|
208
|
+
// 智能合并修改块的评论
|
|
209
|
+
const mergedReviews = this.mergeModificationReviews(fileReview.reviews, meaningfulChanges);
|
|
210
|
+
|
|
208
211
|
// 根据 AI 返回的结果,只对有问题的行添加评论
|
|
209
|
-
for (const review of
|
|
212
|
+
for (const review of mergedReviews) {
|
|
210
213
|
if (review.hasIssue) {
|
|
211
214
|
try {
|
|
215
|
+
// 找到对应的变更
|
|
216
|
+
const relatedChange = meaningfulChanges.find(c =>
|
|
217
|
+
c.lineNumber === review.lineNumber ||
|
|
218
|
+
c.lineNumber === review.oldLine ||
|
|
219
|
+
c.lineNumber === review.newLine
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
// 构建评论位置参数
|
|
223
|
+
const positionParams = {
|
|
224
|
+
filePath: fileName,
|
|
225
|
+
oldPath: change.old_path,
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// 优先使用 hunk 的起始行(让评论定位到 diff 块的开头)
|
|
229
|
+
if (relatedChange && relatedChange.hunkRange) {
|
|
230
|
+
const isDeletion = relatedChange.type === 'deletion';
|
|
231
|
+
if (isDeletion) {
|
|
232
|
+
positionParams.oldLine = relatedChange.hunkRange.oldStart;
|
|
233
|
+
} else {
|
|
234
|
+
positionParams.newLine = relatedChange.hunkRange.newStart;
|
|
235
|
+
}
|
|
236
|
+
} else if (review.oldLine && review.newLine) {
|
|
237
|
+
// 修改块:同时指定两个行号
|
|
238
|
+
positionParams.oldLine = review.oldLine;
|
|
239
|
+
positionParams.newLine = review.newLine;
|
|
240
|
+
} else if (review.lineNumber) {
|
|
241
|
+
// 单独的删除或新增(fallback)
|
|
242
|
+
const isDeletion = relatedChange && relatedChange.type === 'deletion';
|
|
243
|
+
if (isDeletion) {
|
|
244
|
+
positionParams.oldLine = review.lineNumber;
|
|
245
|
+
} else {
|
|
246
|
+
positionParams.newLine = review.lineNumber;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
212
250
|
const commentResult = await this.gitlabClient.createLineComment(
|
|
213
251
|
this.config.project.projectId,
|
|
214
252
|
this.config.project.mergeRequestIid,
|
|
215
253
|
`🤖 **AI 代码审查**\n\n${review.comment}`,
|
|
216
|
-
|
|
217
|
-
filePath: fileName,
|
|
218
|
-
oldPath: change.old_path,
|
|
219
|
-
newLine: review.lineNumber,
|
|
220
|
-
}
|
|
254
|
+
positionParams
|
|
221
255
|
);
|
|
222
256
|
|
|
223
257
|
results.push({
|
|
@@ -464,19 +498,33 @@ export class GitLabAIReview {
|
|
|
464
498
|
for (const review of mergedReviews) {
|
|
465
499
|
if (review.hasIssue) {
|
|
466
500
|
try {
|
|
501
|
+
// 找到对应的变更
|
|
502
|
+
const relatedChange = meaningfulChanges.find(c =>
|
|
503
|
+
c.lineNumber === review.lineNumber ||
|
|
504
|
+
c.lineNumber === review.oldLine ||
|
|
505
|
+
c.lineNumber === review.newLine
|
|
506
|
+
);
|
|
507
|
+
|
|
467
508
|
// 构建评论位置参数
|
|
468
509
|
const positionParams = {
|
|
469
510
|
filePath: fileName,
|
|
470
511
|
oldPath: change.old_path,
|
|
471
512
|
};
|
|
472
513
|
|
|
473
|
-
//
|
|
474
|
-
if (
|
|
514
|
+
// 优先使用 hunk 的起始行(让评论定位到 diff 块的开头)
|
|
515
|
+
if (relatedChange && relatedChange.hunkRange) {
|
|
516
|
+
const isDeletion = relatedChange.type === 'deletion';
|
|
517
|
+
if (isDeletion) {
|
|
518
|
+
positionParams.oldLine = relatedChange.hunkRange.oldStart;
|
|
519
|
+
} else {
|
|
520
|
+
positionParams.newLine = relatedChange.hunkRange.newStart;
|
|
521
|
+
}
|
|
522
|
+
} else if (review.oldLine && review.newLine) {
|
|
523
|
+
// 修改块:同时指定两个行号
|
|
475
524
|
positionParams.oldLine = review.oldLine;
|
|
476
525
|
positionParams.newLine = review.newLine;
|
|
477
526
|
} else if (review.lineNumber) {
|
|
478
|
-
//
|
|
479
|
-
const relatedChange = meaningfulChanges.find(c => c.lineNumber === review.lineNumber);
|
|
527
|
+
// 单独的删除或新增(fallback)
|
|
480
528
|
const isDeletion = relatedChange && relatedChange.type === 'deletion';
|
|
481
529
|
if (isDeletion) {
|
|
482
530
|
positionParams.oldLine = review.lineNumber;
|
package/lib/diff-parser.js
CHANGED
|
@@ -128,6 +128,12 @@ export function extractMeaningfulChanges(hunks) {
|
|
|
128
128
|
content: change.content,
|
|
129
129
|
lineNumber: currentNewLine,
|
|
130
130
|
hunk: hunk.header,
|
|
131
|
+
hunkRange: { // 添加 hunk 的范围信息
|
|
132
|
+
oldStart: hunk.oldStart,
|
|
133
|
+
oldEnd: hunk.oldStart + hunk.oldLines - 1,
|
|
134
|
+
newStart: hunk.newStart,
|
|
135
|
+
newEnd: hunk.newStart + hunk.newLines - 1,
|
|
136
|
+
},
|
|
131
137
|
context: {
|
|
132
138
|
before: hunk.changes.slice(Math.max(0, index - 2), index).map(c => c.content),
|
|
133
139
|
after: hunk.changes.slice(index + 1, index + 3).map(c => c.content),
|
|
@@ -144,6 +150,12 @@ export function extractMeaningfulChanges(hunks) {
|
|
|
144
150
|
content: change.content,
|
|
145
151
|
lineNumber: currentOldLine, // 使用旧文件的行号
|
|
146
152
|
hunk: hunk.header,
|
|
153
|
+
hunkRange: { // 添加 hunk 的范围信息
|
|
154
|
+
oldStart: hunk.oldStart,
|
|
155
|
+
oldEnd: hunk.oldStart + hunk.oldLines - 1,
|
|
156
|
+
newStart: hunk.newStart,
|
|
157
|
+
newEnd: hunk.newStart + hunk.newLines - 1,
|
|
158
|
+
},
|
|
147
159
|
context: {
|
|
148
160
|
before: hunk.changes.slice(Math.max(0, index - 2), index).map(c => c.content),
|
|
149
161
|
after: hunk.changes.slice(index + 1, index + 3).map(c => c.content),
|
package/lib/gitlab-client.js
CHANGED