forked from KCL-BMEIS/niftyreg
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
227 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
import os | ||
import argparse | ||
from github import Github | ||
|
||
# Input variables from Github action | ||
GITHUB_TOKEN = os.getenv('GITHUB_TOKEN') | ||
PR_NUM = int(os.getenv('PR_NUMBER')) | ||
WORK_DIR = os.getenv('GITHUB_WORKSPACE') | ||
REPO_NAME = os.getenv('GITHUB_REPOSITORY') | ||
SHA = os.getenv('GITHUB_SHA') | ||
COMMENT_TITLE = os.getenv('COMMENT_TITLE') | ||
ONLY_PR_CHANGES = os.getenv('REPORT_PR_CHANGES_ONLY') | ||
|
||
# Max characters per comment - 65536 | ||
# Make some room for HTML tags and error message | ||
MAX_CHAR_COUNT_REACHED = '!Maximum character count per GitHub comment has been reached! Not all warnings/errors has been parsed!' | ||
COMMENT_MAX_SIZE = 65000 | ||
current_comment_length = 0 | ||
|
||
def is_part_of_pr_changes(file_path, issue_file_line, files_changed_in_pr): | ||
if ONLY_PR_CHANGES == "false": | ||
return True | ||
|
||
file_name = file_path[file_path.rfind('/')+1:] | ||
print(f"Looking for issue found in file={file_name} ...") | ||
for file, (status, lines_changed_for_file) in files_changed_in_pr.items(): | ||
print(f"Changed file by this PR {file} with status {status} and changed lines {lines_changed_for_file}") | ||
if file == file_name: | ||
if status == "added": | ||
return True | ||
|
||
for (start, end) in lines_changed_for_file: | ||
if issue_file_line >= start and issue_file_line <= end: | ||
return True | ||
|
||
return False | ||
|
||
def get_lines_changed_from_patch(patch): | ||
lines_changed = [] | ||
lines = patch.split('\n') | ||
|
||
for line in lines: | ||
# Example line @@ -43,6 +48,8 @@ | ||
# ------------ ^ | ||
if line.startswith("@@"): | ||
# Example line @@ -43,6 +48,8 @@ | ||
# ----------------------^ | ||
idx_beg = line.index("+") | ||
|
||
# Example line @@ -43,6 +48,8 @@ | ||
# ^--^ | ||
idx_end = line[idx_beg:].index(",") | ||
line_begin = int(line[idx_beg + 1 : idx_beg + idx_end]) | ||
|
||
idx_beg = idx_beg + idx_end | ||
idx_end = line[idx_beg + 1 : ].index("@@") | ||
|
||
num_lines = int(line[idx_beg + 1 : idx_beg + idx_end]) | ||
|
||
lines_changed.append((line_begin, line_begin + num_lines)) | ||
|
||
return lines_changed | ||
|
||
def setup_changed_files(): | ||
files_changed = dict() | ||
|
||
g = Github(GITHUB_TOKEN) | ||
repo = g.get_repo(REPO_NAME) | ||
pull_request = repo.get_pull(PR_NUM) | ||
num_changed_files = pull_request.changed_files | ||
print(f"Changed files {num_changed_files}") | ||
files = pull_request.get_files() | ||
for file in files: | ||
# additions # blob_url # changes # contents_url # deletions # filename | ||
# patch # previous_filename # raw_url # sha # status | ||
# print(f"File: additions={file.additions} blob_url={file.blob_url} changes={file.changes} contents_url={file.contents_url}"\ | ||
# f"deletions={file.deletions} filename={file.filename} patch={file.patch} previous_filename={file.previous_filename}"\ | ||
# f"raw_url={file.raw_url} sha={file.sha} status={file.status} ") | ||
|
||
if file.patch is not None: | ||
lines_changed_for_file = get_lines_changed_from_patch(file.patch) | ||
files_changed[file.filename] = (file.status, lines_changed_for_file) | ||
|
||
return files_changed | ||
|
||
def check_for_char_limit(incoming_line): | ||
global current_comment_length | ||
return (current_comment_length + len(incoming_line)) <= COMMENT_MAX_SIZE | ||
|
||
def get_file_line_end(file, file_line_start): | ||
num_lines = sum(1 for line in open(WORK_DIR + file)) | ||
return min(file_line_start + 5, num_lines) | ||
|
||
def create_comment_for_output(tool_output, prefix, files_changed_in_pr): | ||
issues_found = 0 | ||
global current_comment_length | ||
output_string = '' | ||
for line in tool_output: | ||
if line.startswith(prefix): | ||
line = line.replace(prefix, "") | ||
file_path_end_idx = line.index(':') | ||
file_path = line[:file_path_end_idx] | ||
line = line[file_path_end_idx+1:] | ||
file_line_start = int(line[:line.index(':')]) | ||
file_line_end = get_file_line_end(file_path, file_line_start) | ||
description = f"\n```diff\n!Line: {file_line_start} - {line[line.index(' ')+1:]}``` \n" | ||
|
||
new_line = f'\n\nhttps://github.com/{REPO_NAME}/blob/{SHA}{file_path}#L{file_line_start}-L{file_line_end} {description} <br>\n' | ||
|
||
if is_part_of_pr_changes(file_path, file_line_start, files_changed_in_pr): | ||
if check_for_char_limit(new_line): | ||
output_string += new_line | ||
current_comment_length += len(new_line) | ||
issues_found += 1 | ||
else: | ||
current_comment_length = COMMENT_MAX_SIZE | ||
return output_string, issues_found | ||
|
||
return output_string, issues_found | ||
|
||
def read_files_and_parse_results(files_changed_in_pr): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('-cc', '--cppcheck', help='Output file name for cppcheck', required=True) | ||
cppcheck_file_name = parser.parse_args().cppcheck | ||
|
||
cppcheck_content = '' | ||
with open(cppcheck_file_name, 'r') as file: | ||
cppcheck_content = file.readlines() | ||
|
||
line_prefix = f'{WORK_DIR}' | ||
|
||
cppcheck_comment, cppcheck_issues_found = create_comment_for_output(cppcheck_content, line_prefix, files_changed_in_pr) | ||
|
||
return cppcheck_comment, cppcheck_issues_found | ||
|
||
def prepare_comment_body(cppcheck_comment, cppcheck_issues_found): | ||
|
||
if cppcheck_issues_found == 0: | ||
full_comment_body = f'## <p align="center"><b> :white_check_mark: {COMMENT_TITLE} - no issues found! :white_check_mark: </b></p>' | ||
else: | ||
full_comment_body = f'## <p align="center"><b> :zap: {COMMENT_TITLE} :zap: </b></p> \n\n' | ||
|
||
if len(cppcheck_comment) > 0: | ||
full_comment_body +=f'<details> <summary> <b> :red_circle: Cppcheck found'\ | ||
f' {cppcheck_issues_found} {"issues" if cppcheck_issues_found > 1 else "issue"}! Click here to see details. </b> </summary> <br>'\ | ||
f'{cppcheck_comment} </details><br>\n' | ||
|
||
if current_comment_length == COMMENT_MAX_SIZE: | ||
full_comment_body += f'\n```diff\n{MAX_CHAR_COUNT_REACHED}\n```' | ||
|
||
print(f'Repo={REPO_NAME} pr_num={PR_NUM} comment_title={COMMENT_TITLE}') | ||
|
||
return full_comment_body | ||
|
||
def create_or_edit_comment(comment_body): | ||
g = Github(GITHUB_TOKEN) | ||
repo = g.get_repo(REPO_NAME) | ||
pr = repo.get_pull(PR_NUM) | ||
|
||
comments = pr.get_issue_comments() | ||
found_id = -1 | ||
comment_to_edit = None | ||
for comment in comments: | ||
if (comment.user.login == 'github-actions[bot]') and (COMMENT_TITLE in comment.body): | ||
found_id = comment.id | ||
comment_to_edit = comment | ||
break | ||
|
||
if found_id != -1: | ||
comment_to_edit.edit(body = comment_body) | ||
else: | ||
pr.create_issue_comment(body = comment_body) | ||
|
||
|
||
if __name__ == "__main__": | ||
files_changed_in_pr = setup_changed_files() | ||
cppcheck_comment, cppcheck_issues_found = read_files_and_parse_results(files_changed_in_pr) | ||
comment_body = prepare_comment_body(cppcheck_comment, cppcheck_issues_found) | ||
create_or_edit_comment(comment_body) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
name: Code Analysis | ||
on: [pull_request] | ||
jobs: | ||
Code-Analysis: | ||
runs-on: ubuntu-20.04 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Install dependencies | ||
run: | | ||
sudo apt update && sudo apt install cppcheck -y | ||
pip3 install --upgrade setuptools | ||
pip3 install pygithub | ||
- name: Install CUDA Toolkit | ||
uses: Jimver/[email protected] | ||
with: | ||
method: network | ||
use-github-cache: false | ||
use-local-cache: false | ||
|
||
- name: Configure NiftyReg | ||
run: | | ||
mkdir build | ||
cd build | ||
cmake -DCMAKE_C_COMPILER=gcc \ | ||
-DCMAKE_CXX_COMPILER=g++ \ | ||
-DCMAKE_BUILD_TYPE=Debug \ | ||
-DBUILD_ALL_DEP=ON \ | ||
-DCHECK_GPU=OFF \ | ||
-DUSE_CUDA=ON \ | ||
-DUSE_OPENCL=ON \ | ||
-DUSE_SSE=ON \ | ||
-DUSE_OPENMP=ON \ | ||
-DBUILD_TESTING=OFF \ | ||
-DWITH_COVERAGE=OFF \ | ||
.. | ||
- name: Code Analysis | ||
env: | ||
COMMENT_TITLE: Code Analysis Results | ||
PR_NUMBER: ${{ github.event.pull_request.number }} | ||
REPORT_PR_CHANGES_ONLY: false | ||
GITHUB_TOKEN: ${{ github.token }} | ||
run: | | ||
cppcheck -j 4 --enable=warning,style,performance,portability --project=build/compile_commands.json --output-file=analysis.txt | ||
python3 ${{ github.workspace }}/.github/code_analysis.py -cc analysis.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
423 | ||
424 |