Skip to content

Commit

Permalink
[nrf fromtree] scripts: ci: check_compliance: Update KconfigCheck sub…
Browse files Browse the repository at this point in the history
…classing

So far, the behavior of different Kconfig checks has been parametrized
using the `run()` method, and every new check has introduced with it a
new argument to that method.

It's possible to replace each `run()` argument by way of overriding
different class methods and making better use of inheritance:

    free=False          Stub check_no_undef_outside_kconfig()
    no_modules=True     Stub get_modules()
    filename            Introduce class member FILENAME
    hwm                 (unused)

This should establish a more scalable and straightforward pattern for
adding future Kconfig checks. It also favors composability, which will
come in handy when implementing checks for sysbuild Kconfig.

Additionally, avoid duplicating `doc` and `path_hint` in every subclass.

Signed-off-by: Grzegorz Swiderski <[email protected]>
(cherry picked from commit 50d9ed5)
  • Loading branch information
57300 committed Feb 26, 2025
1 parent b0213c8 commit 236b8ec
Showing 1 changed file with 19 additions and 28 deletions.
47 changes: 19 additions & 28 deletions scripts/ci/check_compliance.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,19 +371,19 @@ class KconfigCheck(ComplianceTest):
doc = "See https://docs.zephyrproject.org/latest/build/kconfig/tips.html for more details."
path_hint = "<zephyr-base>"

def run(self, full=True, no_modules=False, filename="Kconfig", hwm=None):
self.no_modules = no_modules
# Top-level Kconfig file. The path can be relative to srctree (ZEPHYR_BASE).
FILENAME = "Kconfig"

kconf = self.parse_kconfig(filename=filename, hwm=hwm)
def run(self):
kconf = self.parse_kconfig()

self.check_top_menu_not_too_long(kconf)
self.check_no_pointless_menuconfigs(kconf)
self.check_no_undef_within_kconfig(kconf)
self.check_no_redefined_in_defconfig(kconf)
self.check_no_enable_in_boolean_prompt(kconf)
self.check_soc_name_sync(kconf)
if full:
self.check_no_undef_outside_kconfig(kconf)
self.check_no_undef_outside_kconfig(kconf)

def get_modules(self, modules_file, settings_file):
"""
Expand All @@ -393,11 +393,6 @@ def get_modules(self, modules_file, settings_file):
This is needed to complete Kconfig sanity tests.
"""
if self.no_modules:
with open(modules_file, 'w') as fp_module_file:
fp_module_file.write("# Empty\n")
return

# Invoke the script directly using the Python executable since this is
# not a module nor a pip-installed Python utility
zephyr_module_path = os.path.join(ZEPHYR_BASE, "scripts",
Expand Down Expand Up @@ -594,7 +589,7 @@ def get_v2_model(self, kconfig_dir, settings_file):
for arch in v2_archs['archs']:
fp.write('source "' + (Path(arch['path']) / 'Kconfig').as_posix() + '"\n')

def parse_kconfig(self, filename="Kconfig", hwm=None):
def parse_kconfig(self):
"""
Returns a kconfiglib.Kconfig object for the Kconfig files. We reuse
this object for all tests to avoid having to reparse for each test.
Expand Down Expand Up @@ -654,7 +649,7 @@ def parse_kconfig(self, filename="Kconfig", hwm=None):
# them: so some warnings might get printed
# twice. "warn_to_stderr=False" could unfortunately cause
# some (other) warnings to never be printed.
return kconfiglib.Kconfig(filename=filename)
return kconfiglib.Kconfig(filename=self.FILENAME)
except kconfiglib.KconfigError as e:
self.failure(str(e))
raise EndTest
Expand Down Expand Up @@ -1069,40 +1064,36 @@ class KconfigBasicCheck(KconfigCheck):
references inside the Kconfig tree.
"""
name = "KconfigBasic"
doc = "See https://docs.zephyrproject.org/latest/build/kconfig/tips.html for more details."
path_hint = "<zephyr-base>"

def run(self):
super().run(full=False)
def check_no_undef_outside_kconfig(self, kconf):
pass


class KconfigBasicNoModulesCheck(KconfigCheck):
class KconfigBasicNoModulesCheck(KconfigBasicCheck):
"""
Checks if we are introducing any new warnings/errors with Kconfig when no
modules are available. Catches symbols used in the main repository but
defined only in a module.
"""
name = "KconfigBasicNoModules"
doc = "See https://docs.zephyrproject.org/latest/build/kconfig/tips.html for more details."
path_hint = "<zephyr-base>"
def run(self):
super().run(full=False, no_modules=True)

def get_modules(self, modules_file, settings_file):
with open(modules_file, 'w') as fp_module_file:
fp_module_file.write("# Empty\n")


class KconfigHWMv2Check(KconfigCheck, ComplianceTest):
class KconfigHWMv2Check(KconfigBasicCheck):
"""
This runs the Kconfig test for board and SoC v2 scheme.
This check ensures that all symbols inside the v2 scheme is also defined
within the same tree.
This ensures the board and SoC trees are fully self-contained and reusable.
"""
name = "KconfigHWMv2"
doc = "See https://docs.zephyrproject.org/latest/guides/kconfig/index.html for more details."

def run(self):
# Use dedicated Kconfig board / soc v2 scheme file.
# This file sources only v2 scheme tree.
kconfig_file = os.path.join(os.path.dirname(__file__), "Kconfig.board.v2")
super().run(full=False, hwm="v2", filename=kconfig_file)
# Use dedicated Kconfig board / soc v2 scheme file.
# This file sources only v2 scheme tree.
FILENAME = os.path.join(os.path.dirname(__file__), "Kconfig.board.v2")


class Nits(ComplianceTest):
Expand Down

0 comments on commit 236b8ec

Please sign in to comment.