Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 33 additions & 53 deletions codecov/coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def get_diff_coverage_info(added_lines: dict[pathlib.Path, list[int]], coverage:
)


def parse_diff_output(diff: str, coverage: Coverage) -> dict[pathlib.Path, list[int]]:
def parse_diff_output(diff: str) -> dict[pathlib.Path, list[int]]:
current_file: pathlib.Path | None = None
added_filename_prefix = '+++ b/'
result: dict[pathlib.Path, list[int]] = {}
Expand All @@ -260,58 +260,38 @@ def parse_line_number_diff_line(diff_line: str) -> Sequence[int]:

Github API returns default context lines 3 at start and end, we need to remove them.
"""
start, length = (int(i) for i in (diff_line.split()[2][1:] + ',1').split(',')[:2])
current_file_coverage = current_file and coverage.files.get(current_file)

# TODO: sometimes the file might not be in the coverage report
# Then we might as well just return the whole range since they are also not covered
# But this will make the new statements in report in github comment inaccurate

# Alternatively, we can get the number of statements in the file from github API
# But it can be not good performance-wise since we need to make a request for each file
if not (current_file_coverage and current_file_coverage.executed_lines):
return range(start if start == 1 else start + 3, start + length)

current_file_num_statements = current_file_coverage.executed_lines[-1] + 1
end = start + length

# For the first 4 lines of the file, the start is always 1
# So we need to check the next lines to get the context lines and remove them
if start == 1:
while diff_lines:
next_line = diff_lines.popleft()
if next_line.startswith(' '):
start += 1
continue
diff_lines.appendleft(next_line)
break
else:
start += 3

# If the end is less then number of statements in the file
# Then the last 3 lines could be context lines and we need to remove them
if end < current_file_num_statements:
end -= 3
else:
# If the end is same as the number of statements in the file
# Then the last 3 lines could be context lines and we need to remove them
last_3_lines: deque[str] = deque(maxlen=3)
while diff_lines:
next_line = diff_lines.popleft()
if next_line.startswith(' ') or next_line.startswith('+') or next_line.startswith('-'):
last_3_lines.append(next_line)
continue
diff_lines.appendleft(next_line)
break

while last_3_lines:
last_line = last_3_lines.pop()
if last_line.startswith(' '):
end -= 1
else:
break

return range(start, end)
start, _ = (int(i) for i in (diff_line.split()[2][1:] + ',1').split(',')[:2])

line_start = line_end = start
while diff_lines:
next_line = diff_lines.popleft()
if next_line.startswith(' '):
line_start += 1
line_end += 1
continue

if next_line.startswith('-'):
continue

diff_lines.appendleft(next_line)
break

last_added_line = line_end
while diff_lines:
next_line = diff_lines.popleft()
if next_line.startswith(' ') or next_line.startswith('+'):
line_end += 1
if next_line.startswith('+'):
last_added_line = line_end
continue

if next_line.startswith('-'):
continue

diff_lines.appendleft(next_line)
break

return range(line_start, last_added_line)

lines = parse_line_number_diff_line(diff_line=line)
if len(lines) > 0:
Expand Down
2 changes: 1 addition & 1 deletion codecov/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def process_pr( # pylint: disable=too-many-locals
_, coverage = coverage_module.get_coverage_info(coverage_path=config.COVERAGE_PATH)
base_ref = config.GITHUB_BASE_REF or repo_info.default_branch
pr_diff = github.get_pr_diff(github=gh, repository=config.GITHUB_REPOSITORY, pr_number=pr_number)
added_lines = coverage_module.parse_diff_output(diff=pr_diff, coverage=coverage)
added_lines = coverage_module.parse_diff_output(diff=pr_diff)
diff_coverage = coverage_module.get_diff_coverage_info(coverage=coverage, added_lines=added_lines)
marker = template.get_marker(marker_id=config.SUBPROJECT_ID)

Expand Down