Skip to content

Commit

Permalink
handle odd hunk headers
Browse files Browse the repository at this point in the history
  • Loading branch information
2bndy5 committed Jan 7, 2024
1 parent 9073eb2 commit 951226c
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 16 deletions.
22 changes: 19 additions & 3 deletions cpp_linter/common_fs.py
Expand Up @@ -2,6 +2,7 @@
from os.path import commonpath
from pathlib import PurePath, Path
from typing import List, Dict, Any, Union, Tuple, Optional
from pygit2 import DiffHunk # type: ignore
from .loggers import logger, start_log_group

#: A path to generated cache artifacts. (only used when verbosity is in debug mode)
Expand Down Expand Up @@ -98,13 +99,28 @@ def serialize(self) -> Dict[str, Any]:
},
}

def is_in_1_hunk(self, start: int, end: int) -> bool:
def is_hunk_contained(self, hunk: DiffHunk) -> Optional[Tuple[int, int]]:
"""Is a given ``start`` and ``end`` line numbers within a single diff hunk?"""
if hunk.old_lines > 0:
start = hunk.old_start
# span of old_lines is an inclusive range
end = hunk.old_start + hunk.old_lines - 1
else: # if number of old lines is 0
# start hunk at new line number
start = hunk.new_start
# make it span 1 line
end = start
for hunk in self.diff_chunks:
chunk_range = range(hunk[0], hunk[1])
if start in chunk_range and end in chunk_range:
return True
return False
return (start, end)
logger.warning(
"lines %d - %d are not within a single diff hunk for file %s.",
start,
end,
self.name,
)
return None


def is_file_in_list(paths: List[str], file_name: str, prompt: str) -> bool:
Expand Down
8 changes: 6 additions & 2 deletions cpp_linter/git/git_str.py
Expand Up @@ -11,7 +11,7 @@
DIFF_FILE_NAME = re.compile(r"^\+\+\+\sb?/(.*)$", re.MULTILINE)
DIFF_RENAMED_FILE = re.compile(r"^rename to (.*)$", re.MULTILINE)
DIFF_BINARY_FILE = re.compile(r"^Binary\sfiles\s", re.MULTILINE)
HUNK_INFO = re.compile(r"@@\s\-\d+,\d+\s\+(\d+,\d+)\s@@", re.MULTILINE)
HUNK_INFO = re.compile(r"^@@\s\-\d+,?\d*\s\+(\d+,?\d*)\s@@", re.MULTILINE)


def _get_filename_from_diff(front_matter: str) -> Optional[re.Match]:
Expand Down Expand Up @@ -94,7 +94,11 @@ def _parse_patch(full_patch: str) -> Tuple[List[List[int]], List[int]]:
for index, chunk in enumerate(chunks):
if index % 2 == 1:
# each odd element holds the starting line number and number of lines
start_line, hunk_length = [int(x) for x in chunk.split(",")]
if "," in chunk:
start_line, hunk_length = [int(x) for x in chunk.split(",")]
else:
start_line = int(chunk)
hunk_length = 1
ranges.append([start_line, hunk_length + start_line])
line_numb_in_diff = start_line
continue
Expand Down
14 changes: 3 additions & 11 deletions cpp_linter/rest_api/github_api.py
Expand Up @@ -427,18 +427,10 @@ def create_review_comments(
full_patch += patch.text
for hunk in patch.hunks:
total += 1
start_lines, end_lines = (
hunk.old_start,
hunk.old_start + hunk.old_lines,
)
if not file.is_in_1_hunk(start_lines, end_lines):
logger.warning(
"lines %d - %d are not within a single diff hunk for file %s.",
start_lines,
end_lines,
file.name,
)
new_hunk_range = file.is_hunk_contained(hunk)
if new_hunk_range is None:
continue
start_lines, end_lines = new_hunk_range
comment: Dict[str, Any] = {"path": file.name}
body = ""
if isinstance(advice, TidyAdvice):
Expand Down
27 changes: 27 additions & 0 deletions tests/test_git_str.py
Expand Up @@ -75,3 +75,30 @@ def test_ignored_diff():
files = parse_diff_str(TYPICAL_DIFF, ["hpp"], [], [], 0)
# binary files are ignored during parsing
assert not files


def test_terse_hunk_header():
"""For coverage completeness"""
diff_str = "\n".join(
[
"diff --git a/src/demo.cpp b/src/demo.cpp",
"--- a/src/demo.cpp",
"+++ b/src/demo.cpp",
"@@ -3 +3 @@",
"-#include <stdio.h>",
"+#include <cstdio>",
"@@ -4,0 +5,2 @@",
"+auto main() -> int",
"+{",
"@@ -18 +17,2 @@ int main(){",
"- return 0;}",
"+ return 0;",
"+}",
]
)
files = parse_diff_str(diff_str, ["cpp"], [], [], 0)
assert files
assert files[0].diff_chunks == [[3, 4], [5, 7], [17, 19]]
git_files = parse_diff(diff_str, ["cpp"], [], [], 0)
assert git_files
assert files[0].diff_chunks == git_files[0].diff_chunks

0 comments on commit 951226c

Please sign in to comment.