class PrecommitClient: """Client for precommit analysis""" def __init__(self, teamscale_config, repository_path, analyzed_file=None, verify=True): """Constructor""" self.repository_path = repository_path self.teamscale_client = TeamscaleClient(teamscale_config.url, teamscale_config.username, teamscale_config.access_token, teamscale_config.project_id, verify) self.analyzed_file = analyzed_file def upload_precommit_data(self, changed_files, deleted_files): """Uploads the currently changed files for precommit analysis.""" current_branch = get_current_branch(self.repository_path) self.teamscale_client.branch = current_branch parent_commit_timestamp = get_current_timestamp(self.repository_path) print("Uploading changes on branch '%s' in '%s'..." % (current_branch, self.repository_path)) precommit_data = PreCommitUploadData( uniformPathToContentMap=changed_files, deletedUniformPaths=deleted_files) self.teamscale_client.upload_files_for_precommit_analysis( datetime.datetime.fromtimestamp(int(parent_commit_timestamp)), precommit_data) def wait_and_get_precommit_result(self): """Gets the current precommit results. Waits synchronously until server is ready. """ return self.teamscale_client.get_precommit_analysis_results() def print_precommit_results_as_error_string( self, include_findings_in_changed_code=True): """Print the current precommit results formatting them in a way, most text editors understand. Returns: `True`, if RED findings were among the new findings. `False`, otherwise. """ added_findings, removed_findings, findings_in_changed_code = self.wait_and_get_precommit_result( ) print('New findings:') for formatted_finding in self._format_findings(added_findings): print(formatted_finding) if include_findings_in_changed_code: print('') print('Findings in changed code:') for formatted_finding in self._format_findings( findings_in_changed_code): print(formatted_finding) red_added_findings = list( filter(lambda finding: finding.assessment == "RED", added_findings)) return len(red_added_findings) > 0 def print_other_findings_as_error_string(self, include_all_findings=True): """Print existing findings for the current file or the whole repo in a way, most text editors understand. """ uniform_path = os.path.relpath(self.analyzed_file, self.repository_path) if include_all_findings: uniform_path = '' existing_findings = self.teamscale_client.get_findings( uniform_path=uniform_path, timestamp=datetime.datetime.fromtimestamp( int(get_current_timestamp(self.repository_path)))) print('') print('Existing findings:') for formatted_finding in self._format_findings(existing_findings): print(formatted_finding) def _format_findings(self, findings): """Formats the given findings as error or warning strings.""" if len(findings) == 0: return ['> No findings.'] sorted_findings = sorted(findings) return [ os.path.join(self.repository_path, finding.uniformPath) + ':' + str(finding.startLine) + ':0: ' + self._severity_string(finding=finding) + ': ' + finding.message for finding in sorted_findings ] def _severity_string(self, finding): """Formats the given finding's assessment as severity.""" return 'error' if finding.assessment == 'RED' else 'warning'
class PrecommitClient: """Client for precommit analysis""" def __init__(self, teamscale_config, repository_path, analyzed_file=None, verify=True): """Constructor""" self.repository_path = repository_path self.teamscale_client = TeamscaleClient(teamscale_config.url, teamscale_config.username, teamscale_config.access_token, teamscale_config.project_id, verify) self.analyzed_file = analyzed_file def upload_precommit_data(self, changed_files, deleted_files): """Uploads the currently changed files for precommit analysis.""" current_branch = get_current_branch(self.repository_path) self.teamscale_client.branch = current_branch parent_commit_timestamp = get_current_timestamp(self.repository_path) print("Uploading changes on branch '%s' in '%s'..." % (current_branch, self.repository_path)) precommit_data = PreCommitUploadData(uniformPathToContentMap=changed_files, deletedUniformPaths=deleted_files) self.teamscale_client.upload_files_for_precommit_analysis( datetime.datetime.fromtimestamp(int(parent_commit_timestamp)), precommit_data) def wait_and_get_precommit_result(self): """Gets the current precommit results. Waits synchronously until server is ready. """ return self.teamscale_client.get_precommit_analysis_results() def print_precommit_results_as_error_string(self, include_findings_in_changed_code=True): """Print the current precommit results formatting them in a way, most text editors understand. Returns: `True`, if RED findings were among the new findings. `False`, otherwise. """ added_findings, removed_findings, findings_in_changed_code = self.wait_and_get_precommit_result() print('New findings:') for formatted_finding in self._format_findings(added_findings): print(formatted_finding) if include_findings_in_changed_code: print('') print('Findings in changed code:') for formatted_finding in self._format_findings(findings_in_changed_code): print(formatted_finding) red_added_findings = list(filter(lambda finding: finding.assessment == "RED", added_findings)) return len(red_added_findings) > 0 def print_other_findings_as_error_string(self, include_all_findings=True): """Print existing findings for the current file or the whole repo in a way, most text editors understand. """ uniform_path = os.path.relpath(self.analyzed_file, self.repository_path) if include_all_findings: uniform_path = '' existing_findings = self.teamscale_client.get_findings( uniform_path=uniform_path, timestamp=datetime.datetime.fromtimestamp(int(get_current_timestamp(self.repository_path)))) print('') print('Existing findings:') for formatted_finding in self._format_findings(existing_findings): print(formatted_finding) def _format_findings(self, findings): """Formats the given findings as error or warning strings.""" if len(findings) == 0: return ['> No findings.'] sorted_findings = sorted(findings) return [os.path.join(self.repository_path, finding.uniformPath) + ':' + str(finding.startLine) + ':0: ' + self._severity_string(finding=finding) + ': ' + finding.message for finding in sorted_findings] def _severity_string(self, finding): """Formats the given finding's assessment as severity.""" return 'error' if finding.assessment == 'RED' else 'warning'