Skip to content

Commit f32cad7

Browse files
authored
feature: skip covered files in the report (#47)
* feature: skip covered files in the report * fix: percent covered decimal coversion * fix: additional fixes
1 parent 16a147a commit f32cad7

File tree

13 files changed

+115
-62
lines changed

13 files changed

+115
-62
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Note: Either `GITHUB_PR_NUMBER` or `GITHUB_REF` is required. `GITHUB_PR_NUMBER`
5151
- `ANNOTATE_MISSING_LINES`: Whether to annotate missing lines in the coverage report. Default is False.
5252
- `ANNOTATION_TYPE`: The type of annotation to use for missing lines. 'notice' or 'warning' or 'error'. Default is 'warning'.
5353
- `MAX_FILES_IN_COMMENT`: The maximum number of files to include in the coverage report comment. Default is 25.
54+
- `SKIP_COVERED_FILES_IN_REPORT`: Skip the files with coverage 100% from the report. Default is True.
5455
- `COMPLETE_PROJECT_REPORT`: Whether to include the complete project coverage report in the comment. Default is False.
5556
- `COVERAGE_REPORT_URL`: URL of the full coverage report to mention in the comment.
5657
- `DEBUG`: Whether to enable debug mode. Default is False.

codecov/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class Config:
5353
ANNOTATIONS_OUTPUT_PATH: pathlib.Path | None = None
5454
ANNOTATIONS_DATA_BRANCH: str | None = None
5555
MAX_FILES_IN_COMMENT: int = 25
56+
SKIP_COVERED_FILES_IN_REPORT: bool = True
5657
COMPLETE_PROJECT_REPORT: bool = False
5758
COVERAGE_REPORT_URL: str | None = None
5859
# Only for debugging, not exposed in the action
@@ -87,6 +88,10 @@ def clean_branch_coverage(cls, value: str) -> bool:
8788
def clean_complete_project_report(cls, value: str) -> bool:
8889
return str_to_bool(value)
8990

91+
@classmethod
92+
def clean_skip_covered_files_in_report(cls, value: str) -> bool:
93+
return str_to_bool(value)
94+
9095
@classmethod
9196
def clean_debug(cls, value: str) -> bool:
9297
return str_to_bool(value)

codecov/coverage/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def get_coverage_info(self, coverage_path: pathlib.Path) -> Coverage:
101101

102102
@abstractmethod
103103
def extract_info(self, data: dict) -> Coverage:
104-
raise NotImplementedError
104+
raise NotImplementedError # pragma: no cover
105105

106106
def get_diff_coverage_info( # pylint: disable=too-many-locals
107107
self,

codecov/coverage/pytest.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
from __future__ import annotations
22

33
import datetime
4+
import decimal
45
import pathlib
56

67
from codecov.coverage.base import BaseCoverage, Coverage, CoverageInfo, CoverageMetadata, FileCoverage
78

89

910
class PytestCoverage(BaseCoverage):
11+
def _convert_to_decimal(self, value: float, precision: int = 2) -> decimal.Decimal:
12+
return decimal.Decimal(str(float(value) / 100)).quantize(decimal.Decimal(10) ** -precision)
13+
1014
def extract_info(self, data: dict) -> Coverage:
1115
"""
1216
{
@@ -69,7 +73,7 @@ def extract_info(self, data: dict) -> Coverage:
6973
info=CoverageInfo(
7074
covered_lines=file_data['summary']['covered_lines'],
7175
num_statements=file_data['summary']['num_statements'],
72-
percent_covered=file_data['summary']['percent_covered'],
76+
percent_covered=self._convert_to_decimal(file_data['summary']['percent_covered']),
7377
percent_covered_display=file_data['summary']['percent_covered_display'],
7478
missing_lines=file_data['summary']['missing_lines'],
7579
excluded_lines=file_data['summary']['excluded_lines'],
@@ -84,7 +88,7 @@ def extract_info(self, data: dict) -> Coverage:
8488
info=CoverageInfo(
8589
covered_lines=data['totals']['covered_lines'],
8690
num_statements=data['totals']['num_statements'],
87-
percent_covered=data['totals']['percent_covered'],
91+
percent_covered=self._convert_to_decimal(data['totals']['percent_covered']),
8892
percent_covered_display=data['totals']['percent_covered_display'],
8993
missing_lines=data['totals']['missing_lines'],
9094
excluded_lines=data['totals']['excluded_lines'],

codecov/main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,16 @@ def _process_pr(self):
7171

7272
log.info('Generating comment for PR #%s', self.github.pr_number)
7373
marker = template.get_marker(marker_id=self.config.SUBPROJECT_ID)
74-
files_info, count_files, changed_files_info = template.select_changed_files(
74+
files_info, count_files = template.select_changed_files(
7575
coverage=self.coverage,
7676
diff_coverage=self.diff_coverage,
7777
max_files=self.config.MAX_FILES_IN_COMMENT,
78+
skip_covered_files_in_report=self.config.SKIP_COVERED_FILES_IN_REPORT,
7879
)
7980
coverage_files_info, count_coverage_files = template.select_files(
8081
coverage=self.coverage,
81-
changed_files_info=changed_files_info,
8282
max_files=self.config.MAX_FILES_IN_COMMENT - count_files, # Truncate the report to MAX_FILES_IN_COMMENT
83+
skip_covered_files_in_report=self.config.SKIP_COVERED_FILES_IN_REPORT,
8384
)
8485
try:
8586
comment = template.get_comment_markdown(

codecov/template.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,11 @@ def get_comment_markdown( # pylint: disable=too-many-arguments,too-many-locals
142142

143143

144144
def select_changed_files(
145-
*,
146145
coverage: Coverage,
147146
diff_coverage: DiffCoverage,
148147
max_files: int | None,
149-
) -> tuple[list[FileInfo], int, list[FileInfo]]:
148+
skip_covered_files_in_report: bool,
149+
) -> tuple[list[FileInfo], int]:
150150
"""
151151
Selects the MAX_FILES files with the most new missing lines sorted by path
152152
These are the files which have been modified in the PR
@@ -156,44 +156,42 @@ def select_changed_files(
156156
files = []
157157
for path, coverage_file in coverage.files.items():
158158
diff_coverage_file = diff_coverage.files.get(path)
159+
if not (diff_coverage_file and diff_coverage_file.added_statements):
160+
continue
161+
162+
if skip_covered_files_in_report and percentage_value(diff_coverage_file.percent_covered) == 100:
163+
continue
159164

160165
file_info = FileInfo(
161166
path=path,
162167
coverage=coverage_file,
163168
diff=diff_coverage_file,
164169
)
165-
has_diff = bool(diff_coverage_file and diff_coverage_file.added_statements)
166-
167-
if has_diff:
168-
files.append(file_info)
170+
files.append(file_info)
169171

170-
return sort_and_trucate_files(files=files, max_files=max_files), len(files), files
172+
return sort_and_trucate_files(files=files, max_files=max_files), len(files)
171173

172174

173175
def select_files(
174-
*,
175176
coverage: Coverage,
176-
changed_files_info: list[FileInfo],
177177
max_files: int | None,
178+
skip_covered_files_in_report: bool,
178179
) -> tuple[list[FileInfo], int]:
179180
"""
180181
Selects the no of `max_files` files from the whole project coverage
181-
Selects only files which are not in changed files report
182182
Select only files which have statements (not empty files)
183+
Select only files which have lines missing coverage if `skip_covered_files_in_report` is True
183184
"""
184185

185186
files = []
186-
changed_files_path = {file.path for file in changed_files_info}
187187
for path, coverage_file in coverage.files.items():
188-
# Don't show the report for files that have been modified in the PR
189-
# This is gonne be covered in the changed files report
190-
if path in changed_files_path:
191-
continue
192-
193188
# Don't show the report for files that have no statements
194189
if coverage_file.info.num_statements == 0:
195190
continue
196191

192+
if skip_covered_files_in_report and percentage_value(coverage_file.info.percent_covered) == 100:
193+
continue
194+
197195
file_info = FileInfo(path=path, coverage=coverage_file, diff=None)
198196
files.append(file_info)
199197

codecov/template_files/comment.md.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
{%- block coverage_evolution_badge -%}
66
{%- if coverage %}
77
{%- set text = "Coverage of the whole project for this PR is " ~ coverage.info.percent_covered_display ~ "%." -%}
8-
{%- set color = coverage.info.percent_covered | get_badge_color -%}
8+
{%- set color = coverage.info.percent_covered | x100 | get_badge_color -%}
99
<img title="{{ text }}" src="{{ 'Coverage' | generate_badge(message=coverage.info.percent_covered_display ~ '%', color=color) }}">
1010
{%- endif -%}
1111
{%- endblock coverage_evolution_badge -%}

codecov/template_files/macros.md.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
{%- set text = "The coverage rate of " ~ path ~ " is " ~ percent_covered_display ~ "% (" ~ covered_statements_count ~ "/" ~ statements_count ~ ")." -%}
3535
{%- set label = percent_covered_display ~ "%" -%}
3636
{%- set message = "(" ~ covered_statements_count ~ "/" ~ statements_count ~ ")" -%}
37-
{%- set color = percent_covered | get_badge_color -%}
37+
{%- set color = percent_covered | x100 | get_badge_color -%}
3838
<td align="center"><a href="{{ path | file_url(base=base) }}"><img title="{{ text }}" src="{{ label | generate_badge(message=message, color=color) }}"></a></td>
3939
{%- endmacro -%}
4040

codecov/template_files/pr.md.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{%- if not files %}
22

3-
_This PR does not seem to contain any modification to coverable code._
3+
_This PR does not include changes to coverable code or code with missing coverage._
44
{%- else -%}
55
<details><summary>Click to see coverage of changed files</summary>
66
<br>

tests/coverage/test_pytest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def test_extract_info(self, coverage_json):
2424
info=CoverageInfo(
2525
covered_lines=6,
2626
num_statements=10,
27-
percent_covered=60.0,
27+
percent_covered=PytestCoverage()._convert_to_decimal(60.0),
2828
percent_covered_display='60%',
2929
missing_lines=4,
3030
excluded_lines=0,
@@ -40,7 +40,7 @@ def test_extract_info(self, coverage_json):
4040
info=CoverageInfo(
4141
covered_lines=6,
4242
num_statements=10,
43-
percent_covered=60.0,
43+
percent_covered=PytestCoverage()._convert_to_decimal(60.0),
4444
percent_covered_display='60%',
4545
missing_lines=4,
4646
excluded_lines=0,

tests/test_config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ def test_config_clean_complete_project_report():
149149
assert value is True
150150

151151

152+
def test_config_clean_skip_covered_files_in_report():
153+
value = config.Config.clean_skip_covered_files_in_report('True')
154+
assert value is True
155+
156+
152157
def test_config_clean_debug():
153158
value = config.Config.clean_debug('False')
154159
assert value is False

tests/test_github.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,14 +361,19 @@ def test_post_comment_update(
361361
test_config,
362362
gh_client,
363363
):
364+
comment_with_no_marker = {
365+
'user': {'login': 'foo'},
366+
'body': 'Hey! Hi! How are you?',
367+
'id': 123,
368+
}
364369
comment = {
365370
'user': {'login': 'foo'},
366371
'body': 'Hey! Hi! How are you? marker',
367372
'id': 456,
368373
}
369374
session.register(
370375
'GET', f'/repos/{test_config.GITHUB_REPOSITORY}/issues/{test_config.GITHUB_PR_NUMBER}/comments'
371-
)(json=[comment])
376+
)(json=[comment_with_no_marker, comment])
372377
session.register(
373378
'PATCH',
374379
f'/repos/{test_config.GITHUB_REPOSITORY}/issues/comments/{comment["id"]}',

0 commit comments

Comments
 (0)