mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Ahmed S. Darwish" <darwi@linutronix.de>
To: Clark Williams <clrkwllms@kernel.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Ingo Molnar <mingo@redhat.com>,
	Nathan Chancellor <nathan@kernel.org>,
	Nicolas Schier <nsc@kernel.org>
Cc: "Sebastian Andrzej Siewior" <bigeasy@linutronix.de>,
	"Frederic Weisbecker" <frederic@kernel.org>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"John Ogness" <john.ogness@linutronix.de>,
	"Derek Barbosa" <debarbos@redhat.com>,
	"Zbigniew Jędrzejewski-Szmek" <zbyszek@amutable.com>,
	"Daan De Meyer" <daan.j.demeyer@gmail.com>,
	"Luca Boccassi" <luca.boccassi@gmail.com>,
	linux-rt-devel@lists.linux.dev, debian-kernel@lists.debian.org,
	linux-kbuild@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	"Ahmed S. Darwish" <darwi@linutronix.de>
Subject: [PATCH v1 08/10] kconfig-checker: Add support for rule overlays
Date: Fri,  6 Nov 2026 10:19:20 +0100	[thread overview]
Message-ID: <20261106091922.7560-9-darwi@linutronix.de> (raw)
In-Reply-To: <20261106091922.7560-1-darwi@linutronix.de>

An kconfig-checker overlay is a YAML file applied on top of an existing
rules file.

Overlays are intended for distribution kernel packaging scripts, CI
environments, and board support packages; where the base rules may need
local adjustments.  Overlays may override any rule's field.  They may
also update the documentation URL or introduce totally new rules.

Add support for such an overlay mechanism at the kconfig checker.

Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
---
 tools/kconfig-checker/check.py | 89 +++++++++++++++++++++++++++++++++-
 1 file changed, 88 insertions(+), 1 deletion(-)

diff --git a/tools/kconfig-checker/check.py b/tools/kconfig-checker/check.py
index 4f79ec487da7..38ae4ed32817 100755
--- a/tools/kconfig-checker/check.py
+++ b/tools/kconfig-checker/check.py
@@ -7,7 +7,7 @@
 # Main usage:
 #
 #     $ check.py list-rules
-#     $ check.py check -c path/to/linux/.config -r preempt_rt
+#     $ check.py check -c path/to/linux/.config -r preempt_rt [-o path/to/overlay.yml]
 #
 # Notes:
 #
@@ -225,6 +225,48 @@ class Rule:
         if self.docs_hint:
             self.docs_hint = '#' + self.docs_hint
 
+    def overlay(self, overlay: YamlDict) -> None:
+        """Overlay passed yaml structure over existing data"""
+        if 'expected' in overlay:
+            self.expected = ExpectedValue[overlay['expected']]
+
+        if 'severity' in overlay:
+            self.severity = Severity[overlay['severity']]
+
+        if 'rationale' in overlay:
+            self.rationale = overlay['rationale']
+
+        if 'docs_hint' in overlay:
+            self.docs_hint = overlay['docs_hint']
+            self._normalize_docs_hint()
+
+    @staticmethod
+    def _ensure_required_fields(rule: YamlDict, rule_id: str) -> None:
+        """Ensure that passed rule has all required fields"""
+
+        # Normal rule files require every rule to define both 'expected'
+        # and 'severity'.
+        #
+        # Overlay files are different: an overlay may update only selected
+        # fields of an existing rule, so the overlay schema permits these
+        # fields to be omitted.
+        #
+        # However, an overlay may also introduce a completely new rule,
+        # where such a rule has no existing base rule to inherit from.
+        # Manually check all required fields existence in that case.
+
+        if 'expected' not in rule:
+            error(
+                f'Required field `expected` is missing from {rule_id}',
+                os.EX_DATAERR
+            )
+
+        if 'severity' not in rule:
+            error(
+                f'Required field `severity` is missing from {rule_id}',
+                os.EX_DATAERR
+            )
+
 class SymbolRule(Rule):
     """Rule entry for one .config symbol"""
 
@@ -232,6 +274,8 @@ class SymbolRule(Rule):
 
     def __init__(self, rule: YamlDict):
         self.symbol = rule['name']
+
+        super()._ensure_required_fields(rule, f'symbol {self.symbol}')
         super().__init__(rule)
 
     def _normalize_docs_hint(self) -> None:
@@ -253,6 +297,7 @@ class PatternRule(Rule):
         except re.error as e:
             error(f'Invalid symbol regex {regex}: {e}', os.EX_DATAERR)
 
+        super()._ensure_required_fields(rule, f'pattern {regex}')
         super().__init__(rule)
 
 @dataclass
@@ -333,6 +378,36 @@ class Issue:
     severity: Severity
     rationale: Optional[str]
 
+class OverlayFile:
+    """YAML overlay file access"""
+
+    overlays: YamlDict
+
+    def __init__(self, overlay_f: Path, schema: Schema):
+        self.overlays = Helpers.load_yaml(overlay_f)
+        Helpers.validate_yaml(self.overlays, schema.validator, overlay_f.name)
+
+    def apply(self, rules: Rules) -> Rules:
+        if 'docs_url' in self.overlays:
+            rules.docs_url = self.overlays['docs_url']
+
+        for overlay in self.overlays.get('rules', []):
+            if 'name' in overlay:
+                if rule := rules.get_symbol_rule(overlay['name']):
+                    rule.overlay(overlay)
+                else:
+                    rules.add_rule(SymbolRule(overlay))
+                continue
+
+            if 'name_pattern' in overlay:
+                if prule := rules.get_pattern_rule(overlay['name_pattern']):
+                    prule.overlay(overlay)
+                else:
+                    rules.add_rule(PatternRule(overlay))
+                continue
+
+        return rules
+
 @dataclass
 class SymbolIssue(Issue):
     """Checker issue concerning a single .config symbol"""
@@ -563,6 +638,14 @@ def parse_args(rules: list[str]) -> argparse.Namespace:
         help='rules file to check against',
     )
 
+    check_parser.add_argument(
+        '-o',
+        '--overlay',
+        metavar='OVERLAY_FILE',
+        type=Path,
+        help='file overlay over picked rules',
+    )
+
     return parser.parse_args()
 
 def main() -> None:
@@ -586,6 +669,10 @@ def main() -> None:
     rules_f = rules_dir / f'{args.rules}.yml'
     rules = RulesFile(rules_f, schema).parse()
 
+    if args.overlay:
+        schema = Schema(schema_dir / 'overlay.yml')
+        rules = OverlayFile(args.overlay, schema).apply(rules)
+
     checker = Checker(kconfig, rules)
     report = checker.find_issues()
 
-- 
2.56.0


  parent reply	other threads:[~2026-11-06  9:20 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-06  9:19 [PATCH v1 00/10] tools: Introduce a kernel configuration checker Ahmed S. Darwish
2026-11-06  9:19 ` [PATCH v1 01/10] kconfig-checker: Add schema for rule files Ahmed S. Darwish
2026-11-06  9:19 ` [PATCH v1 02/10] kconfig-checker: Introduce PREEMPT_RT configuration rules Ahmed S. Darwish
2026-11-06  9:19 ` [PATCH v1 03/10] kconfig-checker: Add the configuration checker code Ahmed S. Darwish
2026-11-06  9:19 ` [PATCH v1 04/10] kconfig: Introduce checkconfig target Ahmed S. Darwish
2026-11-06  9:19 ` [PATCH v1 05/10] Documentation: Describe kconfig-checker usage and design Ahmed S. Darwish
2026-11-06  9:19 ` [PATCH v1 06/10] kconfig-checker: Split schema to support component reuse Ahmed S. Darwish
2026-11-06  9:19 ` [PATCH v1 07/10] kconfig-checker: Introduce overlays schema Ahmed S. Darwish
2026-11-06  9:19 ` Ahmed S. Darwish [this message]
2026-11-06  9:19 ` [PATCH v1 09/10] Documentation: Describe kconfig-checker overlays Ahmed S. Darwish
2026-11-06  9:19 ` [PATCH v1 10/10] kconfig: Introduce OVERLAY= for make checkconfig Ahmed S. Darwish

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261106091922.7560-9-darwi@linutronix.de \
    --to=darwi@linutronix.de \
    --cc=bigeasy@linutronix.de \
    --cc=clrkwllms@kernel.org \
    --cc=corbet@lwn.net \
    --cc=daan.j.demeyer@gmail.com \
    --cc=debarbos@redhat.com \
    --cc=debian-kernel@lists.debian.org \
    --cc=frederic@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=john.ogness@linutronix.de \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-devel@lists.linux.dev \
    --cc=luca.boccassi@gmail.com \
    --cc=mingo@redhat.com \
    --cc=nathan@kernel.org \
    --cc=nsc@kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=zbyszek@amutable.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®