ci: Apply coccinelle scripts in git diffs
This scripts receives the same parameter of what_changed.py. And run
coccinelle scripts for code guideline compliance in the given git
commits. e.g: ./guideline_check.py --commits origin/master..HEAD
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
diff --git a/scripts/ci/guideline_check.py b/scripts/ci/guideline_check.py
new file mode 100755
index 0000000..44752e3
--- /dev/null
+++ b/scripts/ci/guideline_check.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: Apache-2.0
+# Copyright (c) 2021 Intel Corporation
+
+import os
+import sh
+import argparse
+import re
+from unidiff import PatchSet
+
+if "ZEPHYR_BASE" not in os.environ:
+ exit("$ZEPHYR_BASE environment variable undefined.")
+
+repository_path = os.environ['ZEPHYR_BASE']
+
+sh_special_args = {
+ '_tty_out': False,
+ '_cwd': repository_path
+}
+
+coccinelle_scripts = ["/scripts/coccinelle/reserved_names.cocci",
+ "/scripts/coccinelle/same_identifier.cocci",
+ "/scripts/coccinelle/identifier_length.cocci",
+ ]
+
+
+def parse_coccinelle(contents: str, violations: dict):
+ reg = re.compile("([a-zA-Z0-9/]*\\.[ch]:[0-9]*)(:[0-9\\-]*: )(.*)")
+ for line in contents.split("\n"):
+ r = reg.match(line)
+ if r:
+ f = r.group(1)
+ if f in violations:
+ violations[f].append(r.group(3))
+ else:
+ violations[r.group(1)] = [r.group(3)]
+
+
+def parse_args():
+ parser = argparse.ArgumentParser(
+ description="Check if change requires full twister")
+ parser.add_argument('-c', '--commits', default=None,
+ help="Commit range in the form: a..b")
+ return parser.parse_args()
+
+
+def main():
+ args = parse_args()
+ if not args.commits:
+ exit("missing commit range")
+
+ commit = sh.git("diff", args.commits, **sh_special_args)
+ patch_set = PatchSet(commit)
+ zephyr_base = os.getenv("ZEPHYR_BASE")
+ violations = {}
+ numViolations = 0
+
+ for f in patch_set:
+ if not f.path.endswith(".c") and not f.path.endswith(".h") or not os.path.exists(zephyr_base + "/" + f.path):
+ continue
+
+ for script in coccinelle_scripts:
+ script_path = os.getenv("ZEPHYR_BASE") + "/" + script
+ cocci = sh.coccicheck(
+ "--mode=report",
+ "--cocci=" +
+ script_path,
+ f.path,
+ **sh_special_args)
+ parse_coccinelle(cocci, violations)
+
+ for hunk in f:
+ for line in hunk:
+ if line.is_added:
+ violation = "{}:{}".format(f.path, line.target_line_no)
+ if violation in violations:
+ numViolations += 1
+ print(
+ "{}:{}".format(
+ violation, "\t\n".join(
+ violations[violation])))
+
+ return numViolations
+
+
+if __name__ == "__main__":
+ ret = main()
+ exit(ret)