[CI] Added feature to filter out files to file_check.py that do not require cppcheck (#7499)

Co-authored-by: supperthomas <78900636@qq.com>
This commit is contained in:
dejavudwh 2023-05-16 07:51:16 +08:00 committed by GitHub
parent 01d1bbe40d
commit b1584e9fa9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 150 additions and 9 deletions

View File

@ -21,16 +21,10 @@ jobs:
run: |
sudo apt-get update
sudo apt-get -qq install cppcheck
pip install click PyYaml
git remote -v
git fetch origin
cppcheck --version
ls
git branch -a
changed_files=$(git diff --name-only HEAD origin/master | grep -E '\.(c|cpp|cc|cxx)$' || true)
if [ -n "$changed_files" ];then
cppcheck --enable=warning,performance,portability --inline-suppr --error-exitcode=1 --force $changed_files
err=$?
if [ $err -ne 0 ]; then
echo "CPPCHECK REPORT, PLEASE CHECK THE WARNING !!!!!!!!!"
fi
fi
python tools/ci/cpp_check.py check

63
tools/ci/cpp_check.py Normal file
View File

@ -0,0 +1,63 @@
#
# Copyright (c) 2006-2023, RT-Thread Development Team
#
# SPDX-License-Identifier: Apache-2.0
#
# Change Logs:
# Date Author Notes
# 2023-05-16 dejavudwh the first version
#
import click
import logging
import subprocess
import sys
import format_ignore
class CPPCheck:
def __init__(self, file_list):
self.file_list = file_list
def check(self):
file_list_filtered = [file for file in self.file_list if file.endswith(('.c', '.cpp', '.cc', '.cxx'))]
logging.info("Start to static code analysis.")
check_result = True
for file in file_list_filtered:
result = subprocess.run(['cppcheck', '--enable=warning', 'performance', 'portability', '--inline-suppr', '--error-exitcode=1', '--force', file], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
logging.info(result.stdout.decode())
logging.info(result.stderr.decode())
if result.stderr:
check_result = False
return check_result
@click.group()
@click.pass_context
def cli(ctx):
pass
@cli.command()
def check():
"""
static code analysis(cppcheck).
"""
format_ignore.init_logger()
# get modified files list
checkout = format_ignore.CheckOut()
file_list = checkout.get_new_file()
if file_list is None:
logging.error("checkout files fail")
sys.exit(1)
# use cppcheck
cpp_check = CPPCheck(file_list)
cpp_check_result = cpp_check.check()
if not cpp_check_result:
logging.error("static code analysis(cppcheck) fail.")
sys.exit(1)
logging.info("check success.")
sys.exit(0)
if __name__ == '__main__':
cli()

84
tools/ci/format_ignore.py Normal file
View File

@ -0,0 +1,84 @@
#
# Copyright (c) 2006-2023, RT-Thread Development Team
#
# SPDX-License-Identifier: Apache-2.0
#
# Change Logs:
# Date Author Notes
# 2023-05-16 dejavudwh the first version
#
import yaml
import logging
import os
import subprocess
def init_logger():
log_format = "[%(filename)s %(lineno)d %(levelname)s] %(message)s "
date_format = '%Y-%m-%d %H:%M:%S %a '
logging.basicConfig(level=logging.INFO,
format=log_format,
datefmt=date_format,
)
class CheckOut:
def __init__(self):
pass
def __exclude_file(self, file_path):
dir_number = file_path.split('/')
ignore_path = file_path
# gets the file path depth.
for i in dir_number:
# current directory.
dir_name = os.path.dirname(ignore_path)
ignore_path = dir_name
# judge the ignore file exists in the current directory.
ignore_file_path = os.path.join(dir_name, ".ignore_format.yml")
if not os.path.exists(ignore_file_path):
continue
try:
with open(ignore_file_path) as f:
ignore_config = yaml.safe_load(f.read())
file_ignore = ignore_config.get("file_path", [])
dir_ignore = ignore_config.get("dir_path", [])
except Exception as e:
logging.error(e)
continue
logging.debug("ignore file path: {}".format(ignore_file_path))
logging.debug("file_ignore: {}".format(file_ignore))
logging.debug("dir_ignore: {}".format(dir_ignore))
try:
# judge file_path in the ignore file.
for file in file_ignore:
if file is not None:
file_real_path = os.path.join(dir_name, file)
if file_real_path == file_path:
logging.info("ignore file path: {}".format(file_real_path))
return 0
file_dir_path = os.path.dirname(file_path)
for _dir in dir_ignore:
if _dir is not None:
dir_real_path = os.path.join(dir_name, _dir)
if file_dir_path.startswith(dir_real_path):
logging.info("ignore dir path: {}".format(dir_real_path))
return 0
except Exception as e:
logging.error(e)
continue
return 1
def get_new_file(self):
result = subprocess.run(['git', 'diff', '--name-only', 'HEAD', 'origin/master', '--diff-filter=ACMR', '--no-renames', '--full-index'], stdout = subprocess.PIPE)
file_list = result.stdout.decode().strip().split('\n')
new_files = []
for line in file_list:
logging.info("modified file -> {}".format(line))
result = self.__exclude_file(line)
if result != 0:
new_files.append(line)
return new_files