zephyr/scripts/ci/guideline_check.py
Jamie McCrae ec7044437e treewide: Disable automatic argparse argument shortening
Disables allowing the python argparse library from automatically
shortening command line arguments, this prevents issues whereby
a new command is added and code that wrongly uses the shortened
command of an existing argument which is the same as the new
command being added will silently change script behaviour.

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
2023-01-26 20:12:36 +09:00

103 lines
3.3 KiB
Python
Executable file

#!/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", allow_abbrev=False)
parser.add_argument('-c', '--commits', default=None,
help="Commit range in the form: a..b")
parser.add_argument("-o", "--output", required=False,
help="Print violation into a file")
return parser.parse_args()
def main():
args = parse_args()
if not args.commits:
exit("missing commit range")
# pylint does not like the 'sh' library
# pylint: disable=too-many-function-args,unexpected-keyword-arg
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
print(f"Running {script} on {f.path}")
try:
cocci = sh.coccicheck(
"--mode=report",
"--cocci=" +
script_path,
f.path,
_timeout=10,
**sh_special_args)
parse_coccinelle(cocci, violations)
except sh.TimeoutException:
print("we timed out waiting, skipping...")
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
if args.output:
with open(args.output, "a+") as fp:
fp.write("{}:{}\n".format(
violation, "\t\n".join(
violations[violation])))
else:
print(
"{}:{}".format(
violation, "\t\n".join(
violations[violation])))
return numViolations
if __name__ == "__main__":
ret = main()
exit(ret)