summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordejavudwh <[email protected]>2023-05-16 07:51:16 +0800
committerGitHub <[email protected]>2023-05-16 07:51:16 +0800
commitb1584e9fa9b66b250854b1836b79af9ba29400e6 (patch)
tree1c78f8d7adc92b37467c66b953beb0e48225f215
parent01d1bbe40d7932e042e9dfb1c9eb41b01abc1b3f (diff)
[CI] Added feature to filter out files to file_check.py that do not require cppcheck (#7499)
Co-authored-by: supperthomas <[email protected]>
-rw-r--r--.github/workflows/static_code_analysis.yml12
-rw-r--r--tools/ci/cpp_check.py63
-rw-r--r--tools/ci/format_ignore.py84
3 files changed, 150 insertions, 9 deletions
diff --git a/.github/workflows/static_code_analysis.yml b/.github/workflows/static_code_analysis.yml
index 37d9a7b2cb..397e04ef1d 100644
--- a/.github/workflows/static_code_analysis.yml
+++ b/.github/workflows/static_code_analysis.yml
@@ -1,6 +1,6 @@
name: Static code analysis
-on:
+on:
pull_request:
branches:
- master
@@ -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
diff --git a/tools/ci/cpp_check.py b/tools/ci/cpp_check.py
new file mode 100644
index 0000000000..10906a3b7f
--- /dev/null
+++ b/tools/ci/cpp_check.py
@@ -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
+
+def cli(ctx):
+ pass
+
+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()
diff --git a/tools/ci/format_ignore.py b/tools/ci/format_ignore.py
new file mode 100644
index 0000000000..a7f9be2cbf
--- /dev/null
+++ b/tools/ci/format_ignore.py
@@ -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 \ No newline at end of file