-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
171 lines (151 loc) · 7.07 KB
/
main.py
File metadata and controls
171 lines (151 loc) · 7.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import json
import os
from codecov import diff_grouper, groups, template
from codecov.config import Config
from codecov.coverage import PytestCoverage
from codecov.coverage.base import Coverage, DiffCoverage
from codecov.exceptions import ConfigurationException, CoreProcessingException, MissingMarker, TemplateException
from codecov.github import Github
from codecov.github_client import GitHubClient
from codecov.log import log, setup as log_setup
class Main:
def __init__(self):
self.config = self._init_config()
self._init_log()
self._init_required()
self.github = self._init_github()
self.coverage: Coverage
self.diff_coverage: DiffCoverage
# Default coverage module
self.coverage_module = PytestCoverage()
def _init_config(self):
return Config.from_environ(environ=os.environ)
def _init_log(self):
log_setup(debug=self.config.DEBUG)
def _init_required(self):
if self.config.SKIP_COVERAGE and not self.config.ANNOTATE_MISSING_LINES:
log.error('Nothing to do since both SKIP_COVERAGE and ANNOTATE_MISSING_LINES are set to False. Exiting.')
raise CoreProcessingException
def _init_github(self):
gh_client = GitHubClient(token=self.config.GITHUB_TOKEN)
github = Github(
client=gh_client,
repository=self.config.GITHUB_REPOSITORY,
pr_number=self.config.GITHUB_PR_NUMBER,
ref=self.config.GITHUB_REF,
annotations_data_branch=self.config.ANNOTATIONS_DATA_BRANCH,
)
return github
def run(self):
self._process_coverage()
self._process_pr()
self._generate_annotations()
def _process_coverage(self):
log.info('Processing coverage data')
try:
coverage = self.coverage_module.get_coverage_info(coverage_path=self.config.COVERAGE_PATH)
except ConfigurationException as e:
log.error('Error processing coverage data.')
raise CoreProcessingException from e
if self.config.BRANCH_COVERAGE:
coverage = diff_grouper.fill_branch_missing_groups(coverage=coverage)
added_lines = self.coverage_module.parse_diff_output(diff=self.github.pr_diff)
diff_coverage = self.coverage_module.get_diff_coverage_info(added_lines=added_lines, coverage=coverage)
self.coverage = coverage
self.diff_coverage = diff_coverage
def _process_pr(self):
if self.config.SKIP_COVERAGE:
log.info('Skipping coverage report generation.')
return
log.info('Generating comment for PR #%s', self.github.pr_number)
marker = template.get_marker(marker_id=self.config.SUBPROJECT_ID)
files_info, count_files = template.select_changed_files(
coverage=self.coverage,
diff_coverage=self.diff_coverage,
max_files=self.config.MAX_FILES_IN_COMMENT,
skip_covered_files_in_report=self.config.SKIP_COVERED_FILES_IN_REPORT,
)
coverage_files_info, count_coverage_files = template.select_files(
coverage=self.coverage,
max_files=self.config.MAX_FILES_IN_COMMENT - count_files, # Truncate the report to MAX_FILES_IN_COMMENT
skip_covered_files_in_report=self.config.SKIP_COVERED_FILES_IN_REPORT,
)
try:
comment = template.get_comment_markdown(
coverage=self.coverage,
diff_coverage=self.diff_coverage,
files=files_info,
count_files=count_files,
coverage_files=coverage_files_info,
count_coverage_files=count_coverage_files,
max_files=self.config.MAX_FILES_IN_COMMENT,
minimum_green=self.config.MINIMUM_GREEN,
minimum_orange=self.config.MINIMUM_ORANGE,
repo_name=self.config.GITHUB_REPOSITORY,
pr_number=self.github.pr_number,
base_ref=self.github.base_ref,
base_template=template.read_template_file('comment.md.j2'),
marker=marker,
subproject_id=self.config.SUBPROJECT_ID,
branch_coverage=self.config.BRANCH_COVERAGE,
complete_project_report=self.config.COMPLETE_PROJECT_REPORT,
coverage_report_url=self.config.COVERAGE_REPORT_URL,
)
except MissingMarker as e:
log.error(
'``{{ %s }}`` marker not found. The marker is necessary for this action to recognize '
"its own comment and avoid making new comments or overwriting someone else's comment.",
marker,
)
raise CoreProcessingException from e
except TemplateException as e:
log.error(
'There was a rendering error when computing the text of the comment to post '
'on the PR. Please see the traceback for more information.'
)
raise CoreProcessingException from e
self.github.post_comment(contents=comment, marker=marker)
log.info('Comment created on PR.')
def _generate_annotations(self):
if not self.config.ANNOTATE_MISSING_LINES:
log.info('Skipping annotations generation.')
return
log.info('Generating annotations for missing lines.')
annotations = diff_grouper.get_diff_missing_groups(coverage=self.coverage, diff_coverage=self.diff_coverage)
formatted_annotations = groups.create_missing_coverage_annotations(
annotation_type=self.config.ANNOTATION_TYPE.value,
annotations=annotations,
)
if self.config.BRANCH_COVERAGE:
branch_annotations = diff_grouper.get_diff_branch_missing_groups(
coverage=self.coverage,
diff_coverage=self.diff_coverage,
)
formatted_annotations.extend(
groups.create_missing_coverage_annotations(
annotation_type=self.config.ANNOTATION_TYPE.value,
annotations=branch_annotations,
branch=True,
)
)
if not formatted_annotations:
log.info('No annotations to generate. Exiting.')
return
# Print to console
log.info('Annotations:')
yellow = '\033[93m'
reset = '\033[0m'
print(yellow, end='')
print(*formatted_annotations, sep='\n')
print(reset, end='')
# Save to file
file_name = f'{self.github.pr_number}-annotations.json'
if self.config.ANNOTATIONS_OUTPUT_PATH:
log.info('Writing annotations to file %s', file_name)
with self.config.ANNOTATIONS_OUTPUT_PATH.joinpath(file_name).open('w+') as annotations_file:
json.dump(formatted_annotations, annotations_file, cls=groups.AnnotationEncoder)
# Write to branch
if self.config.ANNOTATIONS_DATA_BRANCH:
log.info('Writing annotations to branch.')
self.github.write_annotations_to_branch(annotations=formatted_annotations)
log.info('Annotations generated.')