@@ -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