scripts: ci: check_compliance: Add check for disallowed Kconfigs

Adds a check for Kconfig settings that are disallowed from being
used in defconfig files (because it is the complete wrong place
for them), with the default entry being PINCTRL

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
Co-authored-by: Benjamin Cabé <benjamin@zephyrproject.org>
This commit is contained in:
Jamie McCrae 2024-09-18 08:53:31 +01:00 committed by Benjamin Cabé
parent ee07eba569
commit f8a5ebfd20

View File

@ -400,6 +400,7 @@ class KconfigCheck(ComplianceTest):
self.check_no_enable_in_boolean_prompt(kconf)
self.check_soc_name_sync(kconf)
self.check_no_undef_outside_kconfig(kconf)
self.check_disallowed_defconfigs(kconf)
def get_modules(self, modules_file, sysbuild_modules_file, settings_file):
"""
@ -674,6 +675,84 @@ class KconfigCheck(ComplianceTest):
return set(kconf_syms)
def check_disallowed_defconfigs(self, kconf):
"""
Checks that there are no disallowed Kconfigs used in board/SoC defconfig files
"""
# Grep for symbol references.
#
# Example output line for a reference to CONFIG_FOO at line 17 of
# foo/bar.c:
#
# foo/bar.c<null>17<null>#ifdef CONFIG_FOO
#
# 'git grep --only-matching' would get rid of the surrounding context
# ('#ifdef '), but it was added fairly recently (second half of 2018),
# so we extract the references from each line ourselves instead.
#
# The regex uses word boundaries (\b) to isolate the reference, and
# negative lookahead to automatically allowlist the following:
#
# - ##, for token pasting (CONFIG_FOO_##X)
#
# - $, e.g. for CMake variable expansion (CONFIG_FOO_${VAR})
#
# - @, e.g. for CMakes's configure_file() (CONFIG_FOO_@VAR@)
#
# - {, e.g. for Python scripts ("CONFIG_FOO_{}_BAR".format(...)")
#
# - *, meant for comments like '#endif /* CONFIG_FOO_* */
disallowed_symbols = {
"PINCTRL": "Drivers requiring PINCTRL must SELECT it instead.",
}
disallowed_regex = "(" + "|".join(disallowed_symbols.keys()) + ")$"
# Warning: Needs to work with both --perl-regexp and the 're' module
regex_boards = r"\bCONFIG_[A-Z0-9_]+\b(?!\s*##|[$@{(.*])"
regex_socs = r"\bconfig\s+[A-Z0-9_]+$"
grep_stdout_boards = git("grep", "--line-number", "-I", "--null",
"--perl-regexp", regex_boards, "--", ":boards",
cwd=Path(GIT_TOP))
grep_stdout_socs = git("grep", "--line-number", "-I", "--null",
"--perl-regexp", regex_socs, "--", ":soc",
cwd=Path(GIT_TOP))
# Board processing
# splitlines() supports various line terminators
for grep_line in grep_stdout_boards.splitlines():
path, lineno, line = grep_line.split("\0")
# Extract symbol references (might be more than one) within the line
for sym_name in re.findall(regex_boards, line):
sym_name = sym_name[len("CONFIG_"):]
# Only check in Kconfig fragment files, references might exist in documentation
if re.match(disallowed_regex, sym_name) and (path[-len("conf"):] == "conf" or
path[-len("defconfig"):] == "defconfig"):
reason = disallowed_symbols.get(sym_name)
self.fmtd_failure("error", "BoardDisallowedKconfigs", path, lineno, desc=f"""
Found disallowed Kconfig symbol in board Kconfig files: CONFIG_{sym_name:35}
{reason}
""")
# SoCs processing
# splitlines() supports various line terminators
for grep_line in grep_stdout_socs.splitlines():
path, lineno, line = grep_line.split("\0")
# Extract symbol references (might be more than one) within the line
for sym_name in re.findall(regex_socs, line):
sym_name = sym_name[len("config"):].strip()
# Only check in Kconfig defconfig files
if re.match(disallowed_regex, sym_name) and "defconfig" in path:
reason = disallowed_symbols.get(sym_name, "Unknown reason")
self.fmtd_failure("error", "SoCDisallowedKconfigs", path, lineno, desc=f"""
Found disallowed Kconfig symbol in SoC Kconfig files: {sym_name:35}
{reason}
""")
def get_defined_syms(self, kconf):
# Returns a set() with the names of all defined Kconfig symbols (with no
# 'CONFIG_' prefix). This is complicated by samples and tests defining