Skip to content

Commit b9a60fa

Browse files
committed
getPullRequestEditedDiffRanges: compute diff ranges
1 parent 650fe60 commit b9a60fa

File tree

1 file changed

+80
-2
lines changed

1 file changed

+80
-2
lines changed

src/analyze.ts

Lines changed: 80 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
/**
@@ -345,6 +356,73 @@ async function getFileDiffsWithBasehead(
345356
}
346357
}
347358

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

0 commit comments

Comments
 (0)