[Concept,02/18] buildman: Move process_config() function to cfgutil

Message ID 20260110200828.168672-3-sjg@u-boot.org
State New
Headers
Series buildman: Split up the enormous Builder class |

Commit Message

Simon Glass Jan. 10, 2026, 8:08 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Move the _process_config() method from Builder class to a module-level
function process_config() in cfgutil.py

This function parses .config and autoconf.h files. It has no
dependencies on Builder state other than a single parameter
(squash_config_y).

Update the tests to call the function directly from cfgutil instead
of through a Builder instance.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 tools/buildman/builder.py | 41 ++-------------------------------------
 tools/buildman/cfgutil.py | 40 ++++++++++++++++++++++++++++++++++++++
 tools/buildman/test.py    | 26 +++++++++----------------
 3 files changed, 51 insertions(+), 56 deletions(-)
  

Patch

diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index 5531e496271..33ac9ab6e0a 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -20,7 +20,7 @@  import sys
 import threading
 
 from buildman import builderthread
-from buildman.cfgutil import Config
+from buildman.cfgutil import Config, process_config
 from u_boot_pylib import command
 from u_boot_pylib import gitutil
 from u_boot_pylib import terminal
@@ -828,43 +828,6 @@  class Builder:
                     sym[name] = sym.get(name, 0) + int(size, 16)
         return sym
 
-    def _process_config(self, fname):
-        """Read in a .config, autoconf.mk or autoconf.h file
-
-        This function handles all config file types. It ignores comments and
-        any #defines which don't start with CONFIG_.
-
-        Args:
-            fname: Filename to read
-
-        Returns:
-            Dictionary:
-                key: Config name (e.g. CONFIG_DM)
-                value: Config value (e.g. 1)
-        """
-        config = {}
-        if os.path.exists(fname):
-            with open(fname, encoding='utf-8') as fd:
-                for line in fd:
-                    line = line.strip()
-                    if line.startswith('#define'):
-                        values = line[8:].split(' ', 1)
-                        if len(values) > 1:
-                            key, value = values
-                        else:
-                            key = values[0]
-                            value = '1' if self.squash_config_y else ''
-                        if not key.startswith('CONFIG_'):
-                            continue
-                    elif not line or line[0] in ['#', '*', '/']:
-                        continue
-                    else:
-                        key, value = line.split('=', 1)
-                    if self.squash_config_y and value == 'y':
-                        value = '1'
-                    config[key] = value
-        return config
-
     def _process_environment(self, fname):
         """Read in a uboot.env file
 
@@ -981,7 +944,7 @@  class Builder:
                 output_dir = self.get_build_dir(commit_upto, target)
                 for name in self.config_filenames:
                     fname = os.path.join(output_dir, name)
-                    config[name] = self._process_config(fname)
+                    config[name] = process_config(fname, self.squash_config_y)
 
             if read_environment:
                 output_dir = self.get_build_dir(commit_upto, target)
diff --git a/tools/buildman/cfgutil.py b/tools/buildman/cfgutil.py
index ad6dee17829..2d4c6799b5c 100644
--- a/tools/buildman/cfgutil.py
+++ b/tools/buildman/cfgutil.py
@@ -5,6 +5,7 @@ 
 
 """Utility functions for dealing with Kconfig .config files"""
 
+import os
 import re
 
 from u_boot_pylib import tools
@@ -266,3 +267,42 @@  Failed adjustments:
 {content}
 '''
     return None
+
+
+def process_config(fname, squash_config_y):
+    """Read in a .config, autoconf.mk or autoconf.h file
+
+    This function handles all config file types. It ignores comments and
+    any #defines which don't start with CONFIG_.
+
+    Args:
+        fname (str): Filename to read
+        squash_config_y (bool): If True, replace 'y' values with '1'
+
+    Returns:
+        dict: Dictionary with:
+            key: Config name (e.g. CONFIG_DM)
+            value: Config value (e.g. '1')
+    """
+    config = {}
+    if os.path.exists(fname):
+        with open(fname, encoding='utf-8') as fd:
+            for line in fd:
+                line = line.strip()
+                if line.startswith('#define'):
+                    values = line[8:].split(' ', 1)
+                    if len(values) > 1:
+                        key, value = values
+                    else:
+                        key = values[0]
+                        value = '1' if squash_config_y else ''
+                    if not key.startswith('CONFIG_'):
+                        continue
+                elif not line or line[0] in ['#', '*', '/']:
+                    continue
+                else:
+                    key, value = line.split('=', 1)
+                if squash_config_y and value == 'y':
+                    value = '1'
+                config[key] = value
+    return config
diff --git a/tools/buildman/test.py b/tools/buildman/test.py
index 828d05781cc..bdf68ef841d 100644
--- a/tools/buildman/test.py
+++ b/tools/buildman/test.py
@@ -1323,9 +1323,7 @@  class TestBuilderFuncs(TestBuildBase):
             os.unlink(tmp_name)
 
     def test_process_config_defconfig(self):
-        """Test _process_config() with .config style file"""
-        build = builder.Builder(self.toolchains, self.base_dir, None, 0, 2)
-
+        """Test process_config() with .config style file"""
         config_data = '''# This is a comment
 CONFIG_OPTION_A=y
 CONFIG_OPTION_B="string"
@@ -1338,7 +1336,7 @@  CONFIG_OPTION_C=123
             tmp_name = tmp.name
 
         try:
-            config = build._process_config(tmp_name)
+            config = cfgutil.process_config(tmp_name, squash_config_y=False)
 
             self.assertEqual('y', config['CONFIG_OPTION_A'])
             self.assertEqual('"string"', config['CONFIG_OPTION_B'])
@@ -1349,9 +1347,7 @@  CONFIG_OPTION_C=123
             os.unlink(tmp_name)
 
     def test_process_config_autoconf_h(self):
-        """Test _process_config() with autoconf.h style file"""
-        build = builder.Builder(self.toolchains, self.base_dir, None, 0, 2)
-
+        """Test process_config() with autoconf.h style file"""
         config_data = '''/* Auto-generated header */
 #define CONFIG_OPTION_A 1
 #define CONFIG_OPTION_B "value"
@@ -1364,7 +1360,7 @@  CONFIG_OPTION_C=123
             tmp_name = tmp.name
 
         try:
-            config = build._process_config(tmp_name)
+            config = cfgutil.process_config(tmp_name, squash_config_y=False)
 
             self.assertEqual('1', config['CONFIG_OPTION_A'])
             self.assertEqual('"value"', config['CONFIG_OPTION_B'])
@@ -1376,17 +1372,13 @@  CONFIG_OPTION_C=123
             os.unlink(tmp_name)
 
     def test_process_config_nonexistent(self):
-        """Test _process_config() with non-existent file"""
-        build = builder.Builder(self.toolchains, self.base_dir, None, 0, 2)
-
-        config = build._process_config('/nonexistent/path/config')
+        """Test process_config() with non-existent file"""
+        config = cfgutil.process_config('/nonexistent/path/config',
+                                        squash_config_y=False)
         self.assertEqual({}, config)
 
     def test_process_config_squash_y(self):
-        """Test _process_config() with squash_config_y enabled"""
-        build = builder.Builder(self.toolchains, self.base_dir, None, 0, 2)
-        build.squash_config_y = True
-
+        """Test process_config() with squash_config_y enabled"""
         config_data = '''CONFIG_OPTION_A=y
 CONFIG_OPTION_B=n
 #define CONFIG_OPTION_C
@@ -1396,7 +1388,7 @@  CONFIG_OPTION_B=n
             tmp_name = tmp.name
 
         try:
-            config = build._process_config(tmp_name)
+            config = cfgutil.process_config(tmp_name, squash_config_y=True)
 
             # y should be squashed to 1
             self.assertEqual('1', config['CONFIG_OPTION_A'])