[PATCH 09/19] buildman: Split out Boards into its own file

Simon Glass sjg at chromium.org
Tue Jul 12 03:04:03 CEST 2022


Use a separate file for the Boards class so that its name matches the
module name.

Fix up the function names to match the pylint style and fix some other
warnings.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 tools/buildman/board.py     | 281 +---------------------------------
 tools/buildman/boards.py    | 290 ++++++++++++++++++++++++++++++++++++
 tools/buildman/control.py   |   4 +-
 tools/buildman/func_test.py |  11 +-
 tools/buildman/test.py      |   3 +-
 5 files changed, 301 insertions(+), 288 deletions(-)
 create mode 100644 tools/buildman/boards.py

diff --git a/tools/buildman/board.py b/tools/buildman/board.py
index ebb9d6f67dc..3268b39e356 100644
--- a/tools/buildman/board.py
+++ b/tools/buildman/board.py
@@ -1,74 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0+
 # Copyright (c) 2012 The Chromium OS Authors.
 
-from collections import OrderedDict
-import re
 
-class Expr:
-    """A single regular expression for matching boards to build"""
-
-    def __init__(self, expr):
-        """Set up a new Expr object.
-
-        Args:
-            expr: String cotaining regular expression to store
-        """
-        self._expr = expr
-        self._re = re.compile(expr)
-
-    def matches(self, props):
-        """Check if any of the properties match the regular expression.
-
-        Args:
-           props: List of properties to check
-        Returns:
-           True if any of the properties match the regular expression
-        """
-        for prop in props:
-            if self._re.match(prop):
-                return True
-        return False
-
-    def __str__(self):
-        return self._expr
-
-class Term:
-    """A list of expressions each of which must match with properties.
-
-    This provides a list of 'AND' expressions, meaning that each must
-    match the board properties for that board to be built.
-    """
-    def __init__(self):
-        self._expr_list = []
-        self._board_count = 0
-
-    def add_expr(self, expr):
-        """Add an Expr object to the list to check.
-
-        Args:
-            expr: New Expr object to add to the list of those that must
-                  match for a board to be built.
-        """
-        self._expr_list.append(Expr(expr))
-
-    def __str__(self):
-        """Return some sort of useful string describing the term"""
-        return '&'.join([str(expr) for expr in self._expr_list])
-
-    def matches(self, props):
-        """Check if any of the properties match this term
-
-        Each of the expressions in the term is checked. All must match.
-
-        Args:
-           props: List of properties to check
-        Returns:
-           True if all of the expressions in the Term match, else False
-        """
-        for expr in self._expr_list:
-            if not expr.matches(props):
-                return False
-        return True
+"""A single board which can be selected and built"""
 
 class Board:
     """A particular board that we can build"""
@@ -95,216 +29,3 @@ class Board:
         self.props = [self.target, self.arch, self.cpu, self.board_name,
                       self.vendor, self.soc, self.options]
         self.build_it = False
-
-
-class Boards:
-    """Manage a list of boards."""
-    def __init__(self):
-        # Use a simple list here, sinc OrderedDict requires Python 2.7
-        self._boards = []
-
-    def add_board(self, brd):
-        """Add a new board to the list.
-
-        The board's target member must not already exist in the board list.
-
-        Args:
-            brd: board to add
-        """
-        self._boards.append(brd)
-
-    def read_boards(self, fname):
-        """Read a list of boards from a board file.
-
-        Create a Board object for each and add it to our _boards list.
-
-        Args:
-            fname: Filename of boards.cfg file
-        """
-        with open(fname, 'r', encoding='utf-8') as fd:
-            for line in fd:
-                if line[0] == '#':
-                    continue
-                fields = line.split()
-                if not fields:
-                    continue
-                for upto in range(len(fields)):
-                    if fields[upto] == '-':
-                        fields[upto] = ''
-                while len(fields) < 8:
-                    fields.append('')
-                if len(fields) > 8:
-                    fields = fields[:8]
-
-                brd = Board(*fields)
-                self.add_board(brd)
-
-
-    def get_list(self):
-        """Return a list of available boards.
-
-        Returns:
-            List of Board objects
-        """
-        return self._boards
-
-    def get_dict(self):
-        """Build a dictionary containing all the boards.
-
-        Returns:
-            Dictionary:
-                key is board.target
-                value is board
-        """
-        board_dict = OrderedDict()
-        for brd in self._boards:
-            board_dict[brd.target] = brd
-        return board_dict
-
-    def get_selected_dict(self):
-        """Return a dictionary containing the selected boards
-
-        Returns:
-            List of Board objects that are marked selected
-        """
-        board_dict = OrderedDict()
-        for brd in self._boards:
-            if brd.build_it:
-                board_dict[brd.target] = brd
-        return board_dict
-
-    def get_selected(self):
-        """Return a list of selected boards
-
-        Returns:
-            List of Board objects that are marked selected
-        """
-        return [brd for brd in self._boards if brd.build_it]
-
-    def get_selected_names(self):
-        """Return a list of selected boards
-
-        Returns:
-            List of board names that are marked selected
-        """
-        return [brd.target for brd in self._boards if brd.build_it]
-
-    def _build_terms(self, args):
-        """Convert command line arguments to a list of terms.
-
-        This deals with parsing of the arguments. It handles the '&'
-        operator, which joins several expressions into a single Term.
-
-        For example:
-            ['arm & freescale sandbox', 'tegra']
-
-        will produce 3 Terms containing expressions as follows:
-            arm, freescale
-            sandbox
-            tegra
-
-        The first Term has two expressions, both of which must match for
-        a board to be selected.
-
-        Args:
-            args: List of command line arguments
-        Returns:
-            A list of Term objects
-        """
-        syms = []
-        for arg in args:
-            for word in arg.split():
-                sym_build = []
-                for term in word.split('&'):
-                    if term:
-                        sym_build.append(term)
-                    sym_build.append('&')
-                syms += sym_build[:-1]
-        terms = []
-        term = None
-        oper = None
-        for sym in syms:
-            if sym == '&':
-                oper = sym
-            elif oper:
-                term.add_expr(sym)
-                oper = None
-            else:
-                if term:
-                    terms.append(term)
-                term = Term()
-                term.add_expr(sym)
-        if term:
-            terms.append(term)
-        return terms
-
-    def select_boards(self, args, exclude=[], brds=None):
-        """Mark boards selected based on args
-
-        Normally either boards (an explicit list of boards) or args (a list of
-        terms to match against) is used. It is possible to specify both, in
-        which case they are additive.
-
-        If brds and args are both empty, all boards are selected.
-
-        Args:
-            args: List of strings specifying boards to include, either named,
-                  or by their target, architecture, cpu, vendor or soc. If
-                  empty, all boards are selected.
-            exclude: List of boards to exclude, regardless of 'args'
-            brds: List of boards to build
-
-        Returns:
-            Tuple
-                Dictionary which holds the list of boards which were selected
-                    due to each argument, arranged by argument.
-                List of errors found
-        """
-        result = OrderedDict()
-        warnings = []
-        terms = self._build_terms(args)
-
-        result['all'] = []
-        for term in terms:
-            result[str(term)] = []
-
-        exclude_list = []
-        for expr in exclude:
-            exclude_list.append(Expr(expr))
-
-        found = []
-        for brd in self._boards:
-            matching_term = None
-            build_it = False
-            if terms:
-                match = False
-                for term in terms:
-                    if term.matches(brd.props):
-                        matching_term = str(term)
-                        build_it = True
-                        break
-            elif brds:
-                if brd.target in brds:
-                    build_it = True
-                    found.append(brd.target)
-            else:
-                build_it = True
-
-            # Check that it is not specifically excluded
-            for expr in exclude_list:
-                if expr.matches(brd.props):
-                    build_it = False
-                    break
-
-            if build_it:
-                brd.build_it = True
-                if matching_term:
-                    result[matching_term].append(brd.target)
-                result['all'].append(brd.target)
-
-        if brds:
-            remaining = set(brds) - set(found)
-            if remaining:
-                warnings.append('Boards not found: %s\n' % ', '.join(remaining))
-
-        return result, warnings
diff --git a/tools/buildman/boards.py b/tools/buildman/boards.py
new file mode 100644
index 00000000000..ec143f9e0f5
--- /dev/null
+++ b/tools/buildman/boards.py
@@ -0,0 +1,290 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2012 The Chromium OS Authors.
+
+"""Maintains a list of boards and allows them to be selected"""
+
+from collections import OrderedDict
+import re
+
+from buildman import board
+
+
+class Expr:
+    """A single regular expression for matching boards to build"""
+
+    def __init__(self, expr):
+        """Set up a new Expr object.
+
+        Args:
+            expr: String cotaining regular expression to store
+        """
+        self._expr = expr
+        self._re = re.compile(expr)
+
+    def matches(self, props):
+        """Check if any of the properties match the regular expression.
+
+        Args:
+           props: List of properties to check
+        Returns:
+           True if any of the properties match the regular expression
+        """
+        for prop in props:
+            if self._re.match(prop):
+                return True
+        return False
+
+    def __str__(self):
+        return self._expr
+
+class Term:
+    """A list of expressions each of which must match with properties.
+
+    This provides a list of 'AND' expressions, meaning that each must
+    match the board properties for that board to be built.
+    """
+    def __init__(self):
+        self._expr_list = []
+        self._board_count = 0
+
+    def add_expr(self, expr):
+        """Add an Expr object to the list to check.
+
+        Args:
+            expr: New Expr object to add to the list of those that must
+                  match for a board to be built.
+        """
+        self._expr_list.append(Expr(expr))
+
+    def __str__(self):
+        """Return some sort of useful string describing the term"""
+        return '&'.join([str(expr) for expr in self._expr_list])
+
+    def matches(self, props):
+        """Check if any of the properties match this term
+
+        Each of the expressions in the term is checked. All must match.
+
+        Args:
+           props: List of properties to check
+        Returns:
+           True if all of the expressions in the Term match, else False
+        """
+        for expr in self._expr_list:
+            if not expr.matches(props):
+                return False
+        return True
+
+
+class Boards:
+    """Manage a list of boards."""
+    def __init__(self):
+        # Use a simple list here, sinc OrderedDict requires Python 2.7
+        self._boards = []
+
+    def add_board(self, brd):
+        """Add a new board to the list.
+
+        The board's target member must not already exist in the board list.
+
+        Args:
+            brd: board to add
+        """
+        self._boards.append(brd)
+
+    def read_boards(self, fname):
+        """Read a list of boards from a board file.
+
+        Create a Board object for each and add it to our _boards list.
+
+        Args:
+            fname: Filename of boards.cfg file
+        """
+        with open(fname, 'r', encoding='utf-8') as inf:
+            for line in inf:
+                if line[0] == '#':
+                    continue
+                fields = line.split()
+                if not fields:
+                    continue
+                for upto, field in enumerate(fields):
+                    if field == '-':
+                        fields[upto] = ''
+                while len(fields) < 8:
+                    fields.append('')
+                if len(fields) > 8:
+                    fields = fields[:8]
+
+                brd = board.Board(*fields)
+                self.add_board(brd)
+
+
+    def get_list(self):
+        """Return a list of available boards.
+
+        Returns:
+            List of Board objects
+        """
+        return self._boards
+
+    def get_dict(self):
+        """Build a dictionary containing all the boards.
+
+        Returns:
+            Dictionary:
+                key is board.target
+                value is board
+        """
+        board_dict = OrderedDict()
+        for brd in self._boards:
+            board_dict[brd.target] = brd
+        return board_dict
+
+    def get_selected_dict(self):
+        """Return a dictionary containing the selected boards
+
+        Returns:
+            List of Board objects that are marked selected
+        """
+        board_dict = OrderedDict()
+        for brd in self._boards:
+            if brd.build_it:
+                board_dict[brd.target] = brd
+        return board_dict
+
+    def get_selected(self):
+        """Return a list of selected boards
+
+        Returns:
+            List of Board objects that are marked selected
+        """
+        return [brd for brd in self._boards if brd.build_it]
+
+    def get_selected_names(self):
+        """Return a list of selected boards
+
+        Returns:
+            List of board names that are marked selected
+        """
+        return [brd.target for brd in self._boards if brd.build_it]
+
+    @classmethod
+    def _build_terms(cls, args):
+        """Convert command line arguments to a list of terms.
+
+        This deals with parsing of the arguments. It handles the '&'
+        operator, which joins several expressions into a single Term.
+
+        For example:
+            ['arm & freescale sandbox', 'tegra']
+
+        will produce 3 Terms containing expressions as follows:
+            arm, freescale
+            sandbox
+            tegra
+
+        The first Term has two expressions, both of which must match for
+        a board to be selected.
+
+        Args:
+            args: List of command line arguments
+        Returns:
+            A list of Term objects
+        """
+        syms = []
+        for arg in args:
+            for word in arg.split():
+                sym_build = []
+                for term in word.split('&'):
+                    if term:
+                        sym_build.append(term)
+                    sym_build.append('&')
+                syms += sym_build[:-1]
+        terms = []
+        term = None
+        oper = None
+        for sym in syms:
+            if sym == '&':
+                oper = sym
+            elif oper:
+                term.add_expr(sym)
+                oper = None
+            else:
+                if term:
+                    terms.append(term)
+                term = Term()
+                term.add_expr(sym)
+        if term:
+            terms.append(term)
+        return terms
+
+    def select_boards(self, args, exclude=None, brds=None):
+        """Mark boards selected based on args
+
+        Normally either boards (an explicit list of boards) or args (a list of
+        terms to match against) is used. It is possible to specify both, in
+        which case they are additive.
+
+        If brds and args are both empty, all boards are selected.
+
+        Args:
+            args: List of strings specifying boards to include, either named,
+                  or by their target, architecture, cpu, vendor or soc. If
+                  empty, all boards are selected.
+            exclude: List of boards to exclude, regardless of 'args'
+            brds: List of boards to build
+
+        Returns:
+            Tuple
+                Dictionary which holds the list of boards which were selected
+                    due to each argument, arranged by argument.
+                List of errors found
+        """
+        result = OrderedDict()
+        warnings = []
+        terms = self._build_terms(args)
+
+        result['all'] = []
+        for term in terms:
+            result[str(term)] = []
+
+        exclude_list = []
+        if exclude:
+            for expr in exclude:
+                exclude_list.append(Expr(expr))
+
+        found = []
+        for brd in self._boards:
+            matching_term = None
+            build_it = False
+            if terms:
+                for term in terms:
+                    if term.matches(brd.props):
+                        matching_term = str(term)
+                        build_it = True
+                        break
+            elif brds:
+                if brd.target in brds:
+                    build_it = True
+                    found.append(brd.target)
+            else:
+                build_it = True
+
+            # Check that it is not specifically excluded
+            for expr in exclude_list:
+                if expr.matches(brd.props):
+                    build_it = False
+                    break
+
+            if build_it:
+                brd.build_it = True
+                if matching_term:
+                    result[matching_term].append(brd.target)
+                result['all'].append(brd.target)
+
+        if brds:
+            remaining = set(brds) - set(found)
+            if remaining:
+                warnings.append(f"Boards not found: {', '.join(remaining)}\n")
+
+        return result, warnings
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index a5c1c2e51c6..8d3e781d51a 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -8,7 +8,7 @@ import shutil
 import subprocess
 import sys
 
-from buildman import board
+from buildman import boards
 from buildman import bsettings
 from buildman import cfgutil
 from buildman import toolchain
@@ -197,7 +197,7 @@ def DoBuildman(options, args, toolchains=None, make_func=None, brds=None,
             if status != 0:
                 sys.exit("Failed to generate boards.cfg")
 
-        brds = board.Boards()
+        brds = boards.Boards()
         brds.read_boards(board_file)
 
     exclude = []
diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py
index 6806ea7fbe6..f12e9966349 100644
--- a/tools/buildman/func_test.py
+++ b/tools/buildman/func_test.py
@@ -9,6 +9,7 @@ import tempfile
 import unittest
 
 from buildman import board
+from buildman import boards
 from buildman import bsettings
 from buildman import cmdline
 from buildman import control
@@ -187,7 +188,7 @@ class TestFunctional(unittest.TestCase):
         self.setupToolchains()
         self._toolchains.Add('arm-gcc', test=False)
         self._toolchains.Add('powerpc-gcc', test=False)
-        self._boards = board.Boards()
+        self._boards = boards.Boards()
         for brd in BOARDS:
             self._boards.add_board(board.Board(*brd))
 
@@ -442,7 +443,7 @@ class TestFunctional(unittest.TestCase):
 
     def testNoBoards(self):
         """Test that buildman aborts when there are no boards"""
-        self._boards = board.Boards()
+        self._boards = boards.Boards()
         with self.assertRaises(SystemExit):
             self._RunControl()
 
@@ -580,7 +581,7 @@ class TestFunctional(unittest.TestCase):
 
     def testWorkInOutput(self):
         """Test the -w option which should write directly to the output dir"""
-        board_list = board.Boards()
+        board_list = boards.Boards()
         board_list.add_board(board.Board(*BOARDS[0]))
         self._RunControl('-o', self._output_dir, '-w', clean_dir=False,
                          brds=board_list)
@@ -599,14 +600,14 @@ class TestFunctional(unittest.TestCase):
         self.assertFalse(
             os.path.exists(os.path.join(self._output_dir, 'u-boot')))
 
-        board_list = board.Boards()
+        board_list = boards.Boards()
         board_list.add_board(board.Board(*BOARDS[0]))
         with self.assertRaises(SystemExit) as e:
             self._RunControl('-b', self._test_branch, '-o', self._output_dir,
                              '-w', clean_dir=False, brds=board_list)
         self.assertIn("single commit", str(e.exception))
 
-        board_list = board.Boards()
+        board_list = boards.Boards()
         board_list.add_board(board.Board(*BOARDS[0]))
         with self.assertRaises(SystemExit) as e:
             self._RunControl('-w', clean_dir=False)
diff --git a/tools/buildman/test.py b/tools/buildman/test.py
index d7306fb4dfa..daf5467503e 100644
--- a/tools/buildman/test.py
+++ b/tools/buildman/test.py
@@ -10,6 +10,7 @@ import time
 import unittest
 
 from buildman import board
+from buildman import boards
 from buildman import bsettings
 from buildman import builder
 from buildman import cfgutil
@@ -131,7 +132,7 @@ class TestBuild(unittest.TestCase):
             self.commits.append(comm)
 
         # Set up boards to build
-        self.brds = board.Boards()
+        self.brds = boards.Boards()
         for brd in BOARDS:
             self.brds.add_board(board.Board(*brd))
         self.brds.select_boards([])
-- 
2.37.0.144.g8ac04bfd2-goog



More information about the U-Boot mailing list