Skip to content

Commit 459d4f5

Browse files
committed
getPullRequestEditedDiffRanges: compute diff ranges
1 parent 68378a3 commit 459d4f5

File tree

1 file changed

+82
-2
lines changed

1 file changed

+82
-2
lines changed

src/analyze.ts

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,19 @@ async function getPullRequestEditedDiffRanges(
294294
headLabel: string,
295295
logger: Logger,
296296
): Promise<DiffThunkRange[] | undefined> {
297-
await getFileDiffsWithBasehead(baseRef, headLabel, logger);
298-
return undefined;
297+
const fileDiffs = await getFileDiffsWithBasehead(baseRef, headLabel, logger);
298+
if (fileDiffs === undefined) {
299+
return undefined;
300+
}
301+
const results: DiffThunkRange[] = [];
302+
for (const filediff of fileDiffs) {
303+
const diffRanges = getDiffRanges(filediff, logger);
304+
if (diffRanges === undefined) {
305+
return undefined;
306+
}
307+
results.push(...diffRanges);
308+
}
309+
return results;
299310
}
300311

301312
/**
@@ -348,6 +359,75 @@ async function getFileDiffsWithBasehead(
348359
}
349360
}
350361

362+
function getDiffRanges(
363+
fileDiff: FileDiff,
364+
logger: Logger,
365+
): DiffThunkRange[] | undefined {
366+
if (fileDiff.patch === undefined) {
367+
return undefined;
368+
}
369+
370+
// Diff-informed queries expect the file path to be absolute.
371+
const filename = path.join(
372+
actionsUtil.getRequiredInput("checkout_path"),
373+
fileDiff.filename,
374+
);
375+
376+
// The 1-based file line number of the current line
377+
let currentLine = 0;
378+
// The 1-based file line number that starts the current range of added lines
379+
let additionRangeStartLine: number | undefined = undefined;
380+
const diffRanges: DiffThunkRange[] = [];
381+
382+
const diffLines = fileDiff.patch.split("\n");
383+
// Adding a fake context line at the end ensures that the following loop will
384+
// always terminate the last range of added lines.
385+
diffLines.push(" ");
386+
387+
for (const diffLine of diffLines) {
388+
if (diffLine.startsWith("-")) {
389+
// Ignore deletions completely -- we do not even want to consider them when
390+
// calculating consecutive ranges of added lines.
391+
continue;
392+
}
393+
if (diffLine.startsWith("+")) {
394+
if (additionRangeStartLine === undefined) {
395+
additionRangeStartLine = currentLine;
396+
}
397+
currentLine++;
398+
continue;
399+
}
400+
if (additionRangeStartLine !== undefined) {
401+
// Any line that does not start with a "+" or "-" terminates the current
402+
// range of added lines.
403+
diffRanges.push({
404+
path: filename,
405+
startLine: additionRangeStartLine,
406+
endLine: currentLine - 1,
407+
});
408+
additionRangeStartLine = undefined;
409+
}
410+
if (diffLine.startsWith("@@ ")) {
411+
// A new hunk header line resets the current line number.
412+
const match = diffLine.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
413+
if (match === null) {
414+
logger.warning(
415+
`Cannot parse diff hunk header for ${fileDiff.filename}: ${diffLine}`,
416+
);
417+
return undefined;
418+
}
419+
currentLine = parseInt(match[1], 10);
420+
continue;
421+
}
422+
if (diffLine.startsWith(" ")) {
423+
// An unchanged context line advances the current line number.
424+
currentLine++;
425+
continue;
426+
}
427+
}
428+
return diffRanges;
429+
}
430+
351431
/**
352432
* Create an extension pack in the temporary directory that contains the file
353433
* line ranges that were added or modified in the pull request.

0 commit comments

Comments
 (0)