# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2013 The Chromium OS Authors.
#
# Bloat-o-meter code used here Copyright 2004 Matt Mackall <mpm@selenic.com>
#

import collections
from datetime import datetime, timedelta
import glob
import os
import re
import queue
import shutil
import signal
import string
import sys
import threading
import time

from buildman import builderthread
from buildman import toolchain
from u_boot_pylib import command
from u_boot_pylib import gitutil
from u_boot_pylib import terminal
from u_boot_pylib import tools
from u_boot_pylib.terminal import tprint

# This indicates an new int or hex Kconfig property with no default
# It hangs the build since the 'conf' tool cannot proceed without valid input.
#
# We get a repeat sequence of something like this:
# >>
# Break things (BREAK_ME) [] (NEW)
# Error in reading or end of file.
# <<
# which indicates that BREAK_ME has an empty default
RE_NO_DEFAULT = re.compile(br'\((\w+)\) \[] \(NEW\)')

# Symbol types which appear in the bloat feature (-B). Others are silently
# dropped when reading in the 'nm' output
NM_SYMBOL_TYPES = 'tTdDbBr'

"""
Theory of Operation

Please see README for user documentation, and you should be familiar with
that before trying to make sense of this.

Buildman works by keeping the machine as busy as possible, building different
commits for different boards on multiple CPUs at once.

The source repo (self.git_dir) contains all the commits to be built. Each
thread works on a single board at a time. It checks out the first commit,
configures it for that board, then builds it. Then it checks out the next
commit and builds it (typically without re-configuring). When it runs out
of commits, it gets another job from the builder and starts again with that
board.

Clearly the builder threads could work either way - they could check out a
commit and then built it for all boards. Using separate directories for each
commit/board pair they could leave their build product around afterwards
also.

The intent behind building a single board for multiple commits, is to make
use of incremental builds. Since each commit is built incrementally from
the previous one, builds are faster. Reconfiguring for a different board
removes all intermediate object files.

Many threads can be working at once, but each has its own working directory.
When a thread finishes a build, it puts the output files into a result
directory.

The base directory used by buildman is normally '../<branch>', i.e.
a directory higher than the source repository and named after the branch
being built.

Within the base directory, we have one subdirectory for each commit. Within
that is one subdirectory for each board. Within that is the build output for
that commit/board combination.

Buildman also create working directories for each thread, in a .bm-work/
subdirectory in the base dir.

As an example, say we are building branch 'us-net' for boards 'sandbox' and
'seaboard', and say that us-net has two commits. We will have directories
like this:

us-net/             base directory
    01_g4ed4ebc_net--Add-tftp-speed-/
        sandbox/
            u-boot.bin
        seaboard/
            u-boot.bin
    02_g4ed4ebc_net--Check-tftp-comp/
        sandbox/
            u-boot.bin
        seaboard/
            u-boot.bin
    .bm-work/
        00/         working directory for thread 0 (contains source checkout)
            build/  build output
        01/         working directory for thread 1
            build/  build output
        ...
u-boot/             source directory
    .git/           repository
"""

"""Holds information about a particular error line we are outputing

   char: Character representation: '+': error, '-': fixed error, 'w+': warning,
       'w-' = fixed warning
   boards: List of Board objects which have line in the error/warning output
   errline: The text of the error line
"""
ErrLine = collections.namedtuple('ErrLine', 'char,brds,errline')

# Possible build outcomes
OUTCOME_OK, OUTCOME_WARNING, OUTCOME_ERROR, OUTCOME_UNKNOWN = list(range(4))

# Translate a commit subject into a valid filename (and handle unicode)
trans_valid_chars = str.maketrans('/: ', '---')

BASE_CONFIG_FILENAMES = [
    'u-boot.cfg', 'u-boot-spl.cfg', 'u-boot-tpl.cfg'
]

EXTRA_CONFIG_FILENAMES = [
    '.config', '.config-spl', '.config-tpl',
    'autoconf.mk', 'autoconf-spl.mk', 'autoconf-tpl.mk',
    'autoconf.h', 'autoconf-spl.h','autoconf-tpl.h',
]

class Config:
    """Holds information about configuration settings for a board."""
    def __init__(self, config_filename, target):
        self.target = target
        self.config = {}
        for fname in config_filename:
            self.config[fname] = {}

    def add(self, fname, key, value):
        self.config[fname][key] = value

    def __hash__(self):
        val = 0
        for fname in self.config:
            for key, value in self.config[fname].items():
                print(key, value)
                val = val ^ hash(key) & hash(value)
        return val

class Environment:
    """Holds information about environment variables for a board."""
    def __init__(self, target):
        self.target = target
        self.environment = {}

    def add(self, key, value):
        self.environment[key] = value

class Builder:
    """Class for building U-Boot for a particular commit.

    Public members: (many should ->private)
        already_done: Number of builds already completed
        base_dir: Base directory to use for builder
        checkout: True to check out source, False to skip that step.
            This is used for testing.
        col: terminal.Color() object
        count: Total number of commits to build, which is the number of commits
            multiplied by the number of boards
        do_make: Method to call to invoke Make
        fail: Number of builds that failed due to error
        force_build: Force building even if a build already exists
        force_config_on_failure: If a commit fails for a board, disable
            incremental building for the next commit we build for that
            board, so that we will see all warnings/errors again.
        force_build_failures: If a previously-built build (i.e. built on
            a previous run of buildman) is marked as failed, rebuild it.
        git_dir: Git directory containing source repository
        num_jobs: Number of jobs to run at once (passed to make as -j)
        num_threads: Number of builder threads to run
        out_queue: Queue of results to process
        re_make_err: Compiled regular expression for ignore_lines
        queue: Queue of jobs to run
        threads: List of active threads
        toolchains: Toolchains object to use for building
        upto: Current commit number we are building (0.count-1)
        warned: Number of builds that produced at least one warning
        force_reconfig: Reconfigure U-Boot on each comiit. This disables
            incremental building, where buildman reconfigures on the first
            commit for a baord, and then just does an incremental build for
            the following commits. In fact buildman will reconfigure and
            retry for any failing commits, so generally the only effect of
            this option is to slow things down.
        in_tree: Build U-Boot in-tree instead of specifying an output
            directory separate from the source code. This option is really
            only useful for testing in-tree builds.
        work_in_output: Use the output directory as the work directory and
            don't write to a separate output directory.
        thread_exceptions: List of exceptions raised by thread jobs
        no_lto (bool): True to set the NO_LTO flag when building
        reproducible_builds (bool): True to set SOURCE_DATE_EPOCH=0 for builds

    Private members:
        _base_board_dict: Last-summarised Dict of boards
        _base_err_lines: Last-summarised list of errors
        _base_warn_lines: Last-summarised list of warnings
        _build_period_us: Time taken for a single build (float object).
        _complete_delay: Expected delay until completion (timedelta)
        _next_delay_update: Next time we plan to display a progress update
                (datatime)
        _show_unknown: Show unknown boards (those not built) in summary
        _start_time: Start time for the build
        _timestamps: List of timestamps for the completion of the last
            last _timestamp_count builds. Each is a datetime object.
        _timestamp_count: Number of timestamps to keep in our list.
        _working_dir: Base working directory containing all threads
        _single_builder: BuilderThread object for the singer builder, if
            threading is not being used
        _terminated: Thread was terminated due to an error
        _restarting_config: True if 'Restart config' is detected in output
        _ide: Produce output suitable for an Integrated Development Environment,
            i.e. dont emit progress information and put errors/warnings on stderr
    """
    class Outcome:
        """Records a build outcome for a single make invocation

        Public Members:
            rc: Outcome value (OUTCOME_...)
            err_lines: List of error lines or [] if none
            sizes: Dictionary of image size information, keyed by filename
                - Each value is itself a dictionary containing
                    values for 'text', 'data' and 'bss', being the integer
                    size in bytes of each section.
            func_sizes: Dictionary keyed by filename - e.g. 'u-boot'. Each
                    value is itself a dictionary:
                        key: function name
                        value: Size of function in bytes
            config: Dictionary keyed by filename - e.g. '.config'. Each
                    value is itself a dictionary:
                        key: config name
                        value: config value
            environment: Dictionary keyed by environment variable, Each
                     value is the value of environment variable.
        """
        def __init__(self, rc, err_lines, sizes, func_sizes, config,
                     environment):
            self.rc = rc
            self.err_lines = err_lines
            self.sizes = sizes
            self.func_sizes = func_sizes
            self.config = config
            self.environment = environment

    def __init__(self, toolchains, base_dir, git_dir, num_threads, num_jobs,
                 gnu_make='make', checkout=True, show_unknown=True, step=1,
                 no_subdirs=False, full_path=False, verbose_build=False,
                 mrproper=False, fallback_mrproper=False,
                 per_board_out_dir=False, config_only=False,
                 squash_config_y=False, warnings_as_errors=False,
                 work_in_output=False, test_thread_exceptions=False,
                 adjust_cfg=None, allow_missing=False, no_lto=False,
                 reproducible_builds=False, force_build=False,
                 force_build_failures=False, force_reconfig=False,
                 in_tree=False, force_config_on_failure=False, make_func=None,
                 dtc_skip=False):
        """Create a new Builder object

        Args:
            toolchains: Toolchains object to use for building
            base_dir: Base directory to use for builder
            git_dir: Git directory containing source repository
            num_threads: Number of builder threads to run
            num_jobs: Number of jobs to run at once (passed to make as -j)
            gnu_make: the command name of GNU Make.
            checkout: True to check out source, False to skip that step.
                This is used for testing.
            show_unknown: Show unknown boards (those not built) in summary
            step: 1 to process every commit, n to process every nth commit
            no_subdirs: Don't create subdirectories when building current
                source for a single board
            full_path: Return the full path in CROSS_COMPILE and don't set
                PATH
            verbose_build: Run build with V=1 and don't use 'make -s'
            mrproper: Always run 'make mrproper' when configuring
            fallback_mrproper: Run 'make mrproper' and retry on build failure
            per_board_out_dir: Build in a separate persistent directory per
                board rather than a thread-specific directory
            config_only: Only configure each build, don't build it
            squash_config_y: Convert CONFIG options with the value 'y' to '1'
            warnings_as_errors: Treat all compiler warnings as errors
            work_in_output: Use the output directory as the work directory and
                don't write to a separate output directory.
            test_thread_exceptions: Uses for tests only, True to make the
                threads raise an exception instead of reporting their result.
                This simulates a failure in the code somewhere
            adjust_cfg_list (list of str): List of changes to make to .config
                file before building. Each is one of (where C is the config
                option with or without the CONFIG_ prefix)

                    C to enable C
                    ~C to disable C
                    C=val to set the value of C (val must have quotes if C is
                        a string Kconfig
            allow_missing: Run build with BINMAN_ALLOW_MISSING=1
            no_lto (bool): True to set the NO_LTO flag when building
            force_build (bool): Rebuild even commits that are already built
            force_build_failures (bool): Rebuild commits that have not been
                built, or failed to build
            force_reconfig (bool): Reconfigure on each commit
            in_tree (bool): Bulid in tree instead of out-of-tree
            force_config_on_failure (bool): Reconfigure the build before
                retrying a failed build
            make_func (function): Function to call to run 'make'
            dtc_skip (bool): True to skip building dtc and use the system one
        """
        self.toolchains = toolchains
        self.base_dir = base_dir
        if work_in_output:
            self._working_dir = base_dir
        else:
            self._working_dir = os.path.join(base_dir, '.bm-work')
        self.threads = []
        self.do_make = make_func or self.make
        self.gnu_make = gnu_make
        self.checkout = checkout
        self.num_threads = num_threads
        self.num_jobs = num_jobs
        self.already_done = 0
        self.force_build = False
        self.git_dir = git_dir
        self._show_unknown = show_unknown
        self._timestamp_count = 10
        self._build_period_us = None
        self._complete_delay = None
        self._next_delay_update = datetime.now()
        self._start_time = None
        self._step = step
        self._error_lines = 0
        self.no_subdirs = no_subdirs
        self.full_path = full_path
        self.verbose_build = verbose_build
        self.config_only = config_only
        self.squash_config_y = squash_config_y
        self.config_filenames = BASE_CONFIG_FILENAMES
        self.work_in_output = work_in_output
        self.adjust_cfg = adjust_cfg
        self.allow_missing = allow_missing
        self._ide = False
        self.no_lto = no_lto
        self.reproducible_builds = reproducible_builds
        self.force_build = force_build
        self.force_build_failures = force_build_failures
        self.force_reconfig = force_reconfig
        self.in_tree = in_tree
        self.force_config_on_failure = force_config_on_failure
        self.fallback_mrproper = fallback_mrproper
        if dtc_skip:
            self.dtc = shutil.which('dtc')
            if not self.dtc:
                raise ValueError('Cannot find dtc')
        else:
            self.dtc = None

        if not self.squash_config_y:
            self.config_filenames += EXTRA_CONFIG_FILENAMES
        self._terminated = False
        self._restarting_config = False

        self.warnings_as_errors = warnings_as_errors
        self.col = terminal.Color()

        self._re_function = re.compile('(.*): In function.*')
        self._re_files = re.compile('In file included from.*')
        self._re_warning = re.compile(r'(.*):(\d*):(\d*): warning: .*')
        self._re_dtb_warning = re.compile('(.*): Warning .*')
        self._re_note = re.compile(r'(.*):(\d*):(\d*): note: this is the location of the previous.*')
        self._re_migration_warning = re.compile(r'^={21} WARNING ={22}\n.*\n=+\n',
                                                re.MULTILINE | re.DOTALL)

        self.thread_exceptions = []
        self.test_thread_exceptions = test_thread_exceptions
        if self.num_threads:
            self._single_builder = None
            self.queue = queue.Queue()
            self.out_queue = queue.Queue()
            for i in range(self.num_threads):
                t = builderthread.BuilderThread(
                        self, i, mrproper, per_board_out_dir,
                        test_exception=test_thread_exceptions)
                t.setDaemon(True)
                t.start()
                self.threads.append(t)

            t = builderthread.ResultThread(self)
            t.setDaemon(True)
            t.start()
            self.threads.append(t)
        else:
            self._single_builder = builderthread.BuilderThread(
                self, -1, mrproper, per_board_out_dir)

        ignore_lines = ['(make.*Waiting for unfinished)', '(Segmentation fault)']
        self.re_make_err = re.compile('|'.join(ignore_lines))

        # Handle existing graceful with SIGINT / Ctrl-C
        signal.signal(signal.SIGINT, self.signal_handler)

    def __del__(self):
        """Get rid of all threads created by the builder"""
        for t in self.threads:
            del t

    def signal_handler(self, signal, frame):
        sys.exit(1)

    def make_environment(self, toolchain):
        """Create the environment to use for building

        Args:
            toolchain (Toolchain): Toolchain to use for building

        Returns:
            dict:
                key (str): Variable name
                value (str): Variable value
        """
        env = toolchain.MakeEnvironment(self.full_path)
        if self.dtc:
            env[b'DTC'] = tools.to_bytes(self.dtc)
        return env

    def set_display_options(self, show_errors=False, show_sizes=False,
                          show_detail=False, show_bloat=False,
                          list_error_boards=False, show_config=False,
                          show_environment=False, filter_dtb_warnings=False,
                          filter_migration_warnings=False, ide=False):
        """Setup display options for the builder.

        Args:
            show_errors: True to show summarised error/warning info
            show_sizes: Show size deltas
            show_detail: Show size delta detail for each board if show_sizes
            show_bloat: Show detail for each function
            list_error_boards: Show the boards which caused each error/warning
            show_config: Show config deltas
            show_environment: Show environment deltas
            filter_dtb_warnings: Filter out any warnings from the device-tree
                compiler
            filter_migration_warnings: Filter out any warnings about migrating
                a board to driver model
            ide: Create output that can be parsed by an IDE. There is no '+' prefix on
                error lines and output on stderr stays on stderr.
        """
        self._show_errors = show_errors
        self._show_sizes = show_sizes
        self._show_detail = show_detail
        self._show_bloat = show_bloat
        self._list_error_boards = list_error_boards
        self._show_config = show_config
        self._show_environment = show_environment
        self._filter_dtb_warnings = filter_dtb_warnings
        self._filter_migration_warnings = filter_migration_warnings
        self._ide = ide

    def _add_timestamp(self):
        """Add a new timestamp to the list and record the build period.

        The build period is the length of time taken to perform a single
        build (one board, one commit).
        """
        now = datetime.now()
        self._timestamps.append(now)
        count = len(self._timestamps)
        delta = self._timestamps[-1] - self._timestamps[0]
        seconds = delta.total_seconds()

        # If we have enough data, estimate build period (time taken for a
        # single build) and therefore completion time.
        if count > 1 and self._next_delay_update < now:
            self._next_delay_update = now + timedelta(seconds=2)
            if seconds > 0:
                self._build_period = float(seconds) / count
                todo = self.count - self.upto
                self._complete_delay = timedelta(microseconds=
                        self._build_period * todo * 1000000)
                # Round it
                self._complete_delay -= timedelta(
                        microseconds=self._complete_delay.microseconds)

        if seconds > 60:
            self._timestamps.popleft()
            count -= 1

    def select_commit(self, commit, checkout=True):
        """Checkout the selected commit for this build
        """
        self.commit = commit
        if checkout and self.checkout:
            gitutil.checkout(commit.hash)

    def make(self, commit, brd, stage, cwd, *args, **kwargs):
        """Run make

        Args:
            commit: Commit object that is being built
            brd: Board object that is being built
            stage: Stage that we are at (mrproper, config, oldconfig, build)
            cwd: Directory where make should be run
            args: Arguments to pass to make
            kwargs: Arguments to pass to command.run_one()
        """

        def check_output(stream, data):
            if b'Restart config' in data:
                self._restarting_config = True

            # If we see 'Restart config' following by multiple errors
            if self._restarting_config:
                m = RE_NO_DEFAULT.findall(data)

                # Number of occurences of each Kconfig item
                multiple = [m.count(val) for val in set(m)]

                # If any of them occur more than once, we have a loop
                if [val for val in multiple if val > 1]:
                    self._terminated = True
                    return True
            return False

        self._restarting_config = False
        self._terminated = False
        cmd = [self.gnu_make] + list(args)
        result = command.run_one(*cmd, capture=True, capture_stderr=True,
                                 cwd=cwd, raise_on_error=False,
                                 infile='/dev/null', output_func=check_output,
                                 **kwargs)

        if self._terminated:
            # Try to be helpful
            result.stderr += '(** did you define an int/hex Kconfig with no default? **)'

        if self.verbose_build:
            result.stdout = '%s\n' % (' '.join(cmd)) + result.stdout
            result.combined = '%s\n' % (' '.join(cmd)) + result.combined
        return result

    def process_result(self, result):
        """Process the result of a build, showing progress information

        Args:
            result: A CommandResult object, which indicates the result for
                    a single build
        """
        col = terminal.Color()
        if result:
            target = result.brd.target

            self.upto += 1
            if result.return_code != 0:
                self.fail += 1
            elif result.stderr:
                self.warned += 1
            if result.already_done:
                self.already_done += 1
            if self._verbose:
                terminal.print_clear()
                boards_selected = {target : result.brd}
                self.reset_result_summary(boards_selected)
                self.produce_result_summary(result.commit_upto, self.commits,
                                          boards_selected)
        else:
            target = '(starting)'

        # Display separate counts for ok, warned and fail
        ok = self.upto - self.warned - self.fail
        line = '\r' + self.col.build(self.col.GREEN, '%5d' % ok)
        line += self.col.build(self.col.YELLOW, '%5d' % self.warned)
        line += self.col.build(self.col.RED, '%5d' % self.fail)

        line += ' /%-5d  ' % self.count
        remaining = self.count - self.upto
        if remaining:
            line += self.col.build(self.col.MAGENTA, ' -%-5d  ' % remaining)
        else:
            line += ' ' * 8

        # Add our current completion time estimate
        self._add_timestamp()
        if self._complete_delay:
            line += '%s  : ' % self._complete_delay

        line += target
        if not self._ide:
            terminal.print_clear()
            tprint(line, newline=False, limit_to_line=True)

    def get_output_dir(self, commit_upto):
        """Get the name of the output directory for a commit number

        The output directory is typically .../<branch>/<commit>.

        Args:
            commit_upto: Commit number to use (0..self.count-1)
        """
        if self.work_in_output:
            return self._working_dir

        commit_dir = None
        if self.commits:
            commit = self.commits[commit_upto]
            subject = commit.subject.translate(trans_valid_chars)
            # See _get_output_space_removals() which parses this name
            commit_dir = ('%02d_g%s_%s' % (commit_upto + 1,
                    commit.hash, subject[:20]))
        elif not self.no_subdirs:
            commit_dir = 'current'
        if not commit_dir:
            return self.base_dir
        return os.path.join(self.base_dir, commit_dir)

    def get_build_dir(self, commit_upto, target):
        """Get the name of the build directory for a commit number

        The build directory is typically .../<branch>/<commit>/<target>.

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
        """
        output_dir = self.get_output_dir(commit_upto)
        if self.work_in_output:
            return output_dir
        return os.path.join(output_dir, target)

    def get_done_file(self, commit_upto, target):
        """Get the name of the done file for a commit number

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
        """
        return os.path.join(self.get_build_dir(commit_upto, target), 'done')

    def get_sizes_file(self, commit_upto, target):
        """Get the name of the sizes file for a commit number

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
        """
        return os.path.join(self.get_build_dir(commit_upto, target), 'sizes')

    def get_func_sizes_file(self, commit_upto, target, elf_fname):
        """Get the name of the funcsizes file for a commit number and ELF file

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
            elf_fname: Filename of elf image
        """
        return os.path.join(self.get_build_dir(commit_upto, target),
                            '%s.sizes' % elf_fname.replace('/', '-'))

    def get_objdump_file(self, commit_upto, target, elf_fname):
        """Get the name of the objdump file for a commit number and ELF file

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
            elf_fname: Filename of elf image
        """
        return os.path.join(self.get_build_dir(commit_upto, target),
                            '%s.objdump' % elf_fname.replace('/', '-'))

    def get_err_file(self, commit_upto, target):
        """Get the name of the err file for a commit number

        Args:
            commit_upto: Commit number to use (0..self.count-1)
            target: Target name
        """
        output_dir = self.get_build_dir(commit_upto, target)
        return os.path.join(output_dir, 'err')

    def filter_errors(self, lines):
        """Filter out errors in which we have no interest

        We should probably use map().

        Args:
            lines: List of error lines, each a string
        Returns:
            New list with only interesting lines included
        """
        out_lines = []
        if self._filter_migration_warnings:
            text = '\n'.join(lines)
            text = self._re_migration_warning.sub('', text)
            lines = text.splitlines()
        for line in lines:
            if self.re_make_err.search(line):
                continue
            if self._filter_dtb_warnings and self._re_dtb_warning.search(line):
                continue
            out_lines.append(line)
        return out_lines

    def read_func_sizes(self, fname, fd):
        """Read function sizes from the output of 'nm'

        Args:
            fd: File containing data to read
            fname: Filename we are reading from (just for errors)

        Returns:
            Dictionary containing size of each function in bytes, indexed by
            function name.
        """
        sym = {}
        for line in fd.readlines():
            line = line.strip()
            parts = line.split()
            if line and len(parts) == 3:
                    size, type, name = line.split()
                    if type in NM_SYMBOL_TYPES:
                        # function names begin with '.' on 64-bit powerpc
                        if '.' in name[1:]:
                            name = 'static.' + name.split('.')[0]
                        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) 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

        This function reads in environment variables from a file.

        Args:
            fname: Filename to read

        Returns:
            Dictionary:
                key: environment variable (e.g. bootlimit)
                value: value of environment variable (e.g. 1)
        """
        environment = {}
        if os.path.exists(fname):
            with open(fname) as fd:
                for line in fd.read().split('\0'):
                    try:
                        key, value = line.split('=', 1)
                        environment[key] = value
                    except ValueError:
                        # ignore lines we can't parse
                        pass
        return environment

    def get_build_outcome(self, commit_upto, target, read_func_sizes,
                        read_config, read_environment):
        """Work out the outcome of a build.

        Args:
            commit_upto: Commit number to check (0..n-1)
            target: Target board to check
            read_func_sizes: True to read function size information
            read_config: True to read .config and autoconf.h files
            read_environment: True to read uboot.env files

        Returns:
            Outcome object
        """
        done_file = self.get_done_file(commit_upto, target)
        sizes_file = self.get_sizes_file(commit_upto, target)
        sizes = {}
        func_sizes = {}
        config = {}
        environment = {}
        if os.path.exists(done_file):
            with open(done_file, 'r') as fd:
                try:
                    return_code = int(fd.readline())
                except ValueError:
                    # The file may be empty due to running out of disk space.
                    # Try a rebuild
                    return_code = 1
                err_lines = []
                err_file = self.get_err_file(commit_upto, target)
                if os.path.exists(err_file):
                    with open(err_file, 'r') as fd:
                        err_lines = self.filter_errors(fd.readlines())

                # Decide whether the build was ok, failed or created warnings
                if return_code:
                    rc = OUTCOME_ERROR
                elif len(err_lines):
                    rc = OUTCOME_WARNING
                else:
                    rc = OUTCOME_OK

                # Convert size information to our simple format
                if os.path.exists(sizes_file):
                    with open(sizes_file, 'r') as fd:
                        for line in fd.readlines():
                            values = line.split()
                            rodata = 0
                            if len(values) > 6:
                                rodata = int(values[6], 16)
                            size_dict = {
                                'all' : int(values[0]) + int(values[1]) +
                                        int(values[2]),
                                'text' : int(values[0]) - rodata,
                                'data' : int(values[1]),
                                'bss' : int(values[2]),
                                'rodata' : rodata,
                            }
                            sizes[values[5]] = size_dict

            if read_func_sizes:
                pattern = self.get_func_sizes_file(commit_upto, target, '*')
                for fname in glob.glob(pattern):
                    with open(fname, 'r') as fd:
                        dict_name = os.path.basename(fname).replace('.sizes',
                                                                    '')
                        func_sizes[dict_name] = self.read_func_sizes(fname, fd)

            if read_config:
                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)

            if read_environment:
                output_dir = self.get_build_dir(commit_upto, target)
                fname = os.path.join(output_dir, 'uboot.env')
                environment = self._process_environment(fname)

            return Builder.Outcome(rc, err_lines, sizes, func_sizes, config,
                                   environment)

        return Builder.Outcome(OUTCOME_UNKNOWN, [], {}, {}, {}, {})

    def get_result_summary(self, boards_selected, commit_upto, read_func_sizes,
                         read_config, read_environment):
        """Calculate a summary of the results of building a commit.

        Args:
            board_selected: Dict containing boards to summarise
            commit_upto: Commit number to summarize (0..self.count-1)
            read_func_sizes: True to read function size information
            read_config: True to read .config and autoconf.h files
            read_environment: True to read uboot.env files

        Returns:
            Tuple:
                Dict containing boards which built this commit:
                    key: board.target
                    value: Builder.Outcome object
                List containing a summary of error lines
                Dict keyed by error line, containing a list of the Board
                    objects with that error
                List containing a summary of warning lines
                Dict keyed by error line, containing a list of the Board
                    objects with that warning
                Dictionary keyed by board.target. Each value is a dictionary:
                    key: filename - e.g. '.config'
                    value is itself a dictionary:
                        key: config name
                        value: config value
                Dictionary keyed by board.target. Each value is a dictionary:
                    key: environment variable
                    value: value of environment variable
        """
        def add_line(lines_summary, lines_boards, line, board):
            line = line.rstrip()
            if line in lines_boards:
                lines_boards[line].append(board)
            else:
                lines_boards[line] = [board]
                lines_summary.append(line)

        board_dict = {}
        err_lines_summary = []
        err_lines_boards = {}
        warn_lines_summary = []
        warn_lines_boards = {}
        config = {}
        environment = {}

        for brd in boards_selected.values():
            outcome = self.get_build_outcome(commit_upto, brd.target,
                                           read_func_sizes, read_config,
                                           read_environment)
            board_dict[brd.target] = outcome
            last_func = None
            last_was_warning = False
            for line in outcome.err_lines:
                if line:
                    if (self._re_function.match(line) or
                            self._re_files.match(line)):
                        last_func = line
                    else:
                        is_warning = (self._re_warning.match(line) or
                                      self._re_dtb_warning.match(line))
                        is_note = self._re_note.match(line)
                        if is_warning or (last_was_warning and is_note):
                            if last_func:
                                add_line(warn_lines_summary, warn_lines_boards,
                                        last_func, brd)
                            add_line(warn_lines_summary, warn_lines_boards,
                                    line, brd)
                        else:
                            if last_func:
                                add_line(err_lines_summary, err_lines_boards,
                                        last_func, brd)
                            add_line(err_lines_summary, err_lines_boards,
                                    line, brd)
                        last_was_warning = is_warning
                        last_func = None
            tconfig = Config(self.config_filenames, brd.target)
            for fname in self.config_filenames:
                if outcome.config:
                    for key, value in outcome.config[fname].items():
                        tconfig.add(fname, key, value)
            config[brd.target] = tconfig

            tenvironment = Environment(brd.target)
            if outcome.environment:
                for key, value in outcome.environment.items():
                    tenvironment.add(key, value)
            environment[brd.target] = tenvironment

        return (board_dict, err_lines_summary, err_lines_boards,
                warn_lines_summary, warn_lines_boards, config, environment)

    def add_outcome(self, board_dict, arch_list, changes, char, color):
        """Add an output to our list of outcomes for each architecture

        This simple function adds failing boards (changes) to the
        relevant architecture string, so we can print the results out
        sorted by architecture.

        Args:
             board_dict: Dict containing all boards
             arch_list: Dict keyed by arch name. Value is a string containing
                    a list of board names which failed for that arch.
             changes: List of boards to add to arch_list
             color: terminal.Colour object
        """
        done_arch = {}
        for target in changes:
            if target in board_dict:
                arch = board_dict[target].arch
            else:
                arch = 'unknown'
            str = self.col.build(color, ' ' + target)
            if not arch in done_arch:
                str = ' %s  %s' % (self.col.build(color, char), str)
                done_arch[arch] = True
            if not arch in arch_list:
                arch_list[arch] = str
            else:
                arch_list[arch] += str


    def colour_num(self, num):
        color = self.col.RED if num > 0 else self.col.GREEN
        if num == 0:
            return '0'
        return self.col.build(color, str(num))

    def reset_result_summary(self, board_selected):
        """Reset the results summary ready for use.

        Set up the base board list to be all those selected, and set the
        error lines to empty.

        Following this, calls to print_result_summary() will use this
        information to work out what has changed.

        Args:
            board_selected: Dict containing boards to summarise, keyed by
                board.target
        """
        self._base_board_dict = {}
        for brd in board_selected:
            self._base_board_dict[brd] = Builder.Outcome(0, [], [], {}, {}, {})
        self._base_err_lines = []
        self._base_warn_lines = []
        self._base_err_line_boards = {}
        self._base_warn_line_boards = {}
        self._base_config = None
        self._base_environment = None

    def print_func_size_detail(self, fname, old, new):
        grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
        delta, common = [], {}

        for a in old:
            if a in new:
                common[a] = 1

        for name in old:
            if name not in common:
                remove += 1
                down += old[name]
                delta.append([-old[name], name])

        for name in new:
            if name not in common:
                add += 1
                up += new[name]
                delta.append([new[name], name])

        for name in common:
                diff = new.get(name, 0) - old.get(name, 0)
                if diff > 0:
                    grow, up = grow + 1, up + diff
                elif diff < 0:
                    shrink, down = shrink + 1, down - diff
                delta.append([diff, name])

        delta.sort()
        delta.reverse()

        args = [add, -remove, grow, -shrink, up, -down, up - down]
        if max(args) == 0 and min(args) == 0:
            return
        args = [self.colour_num(x) for x in args]
        indent = ' ' * 15
        tprint('%s%s: add: %s/%s, grow: %s/%s bytes: %s/%s (%s)' %
              tuple([indent, self.col.build(self.col.YELLOW, fname)] + args))
        tprint('%s  %-38s %7s %7s %+7s' % (indent, 'function', 'old', 'new',
                                         'delta'))
        for diff, name in delta:
            if diff:
                color = self.col.RED if diff > 0 else self.col.GREEN
                msg = '%s  %-38s %7s %7s %+7d' % (indent, name,
                        old.get(name, '-'), new.get(name,'-'), diff)
                tprint(msg, colour=color)


    def print_size_detail(self, target_list, show_bloat):
        """Show details size information for each board

        Args:
            target_list: List of targets, each a dict containing:
                    'target': Target name
                    'total_diff': Total difference in bytes across all areas
                    <part_name>: Difference for that part
            show_bloat: Show detail for each function
        """
        targets_by_diff = sorted(target_list, reverse=True,
        key=lambda x: x['_total_diff'])
        for result in targets_by_diff:
            printed_target = False
            for name in sorted(result):
                diff = result[name]
                if name.startswith('_'):
                    continue
                colour = self.col.RED if diff > 0 else self.col.GREEN
                msg = ' %s %+d' % (name, diff)
                if not printed_target:
                    tprint('%10s  %-15s:' % ('', result['_target']),
                          newline=False)
                    printed_target = True
                tprint(msg, colour=colour, newline=False)
            if printed_target:
                tprint()
                if show_bloat:
                    target = result['_target']
                    outcome = result['_outcome']
                    base_outcome = self._base_board_dict[target]
                    for fname in outcome.func_sizes:
                        self.print_func_size_detail(fname,
                                                 base_outcome.func_sizes[fname],
                                                 outcome.func_sizes[fname])


    def print_size_summary(self, board_selected, board_dict, show_detail,
                         show_bloat):
        """Print a summary of image sizes broken down by section.

        The summary takes the form of one line per architecture. The
        line contains deltas for each of the sections (+ means the section
        got bigger, - means smaller). The numbers are the average number
        of bytes that a board in this section increased by.

        For example:
           powerpc: (622 boards)   text -0.0
          arm: (285 boards)   text -0.0

        Args:
            board_selected: Dict containing boards to summarise, keyed by
                board.target
            board_dict: Dict containing boards for which we built this
                commit, keyed by board.target. The value is an Outcome object.
            show_detail: Show size delta detail for each board
            show_bloat: Show detail for each function
        """
        arch_list = {}
        arch_count = {}

        # Calculate changes in size for different image parts
        # The previous sizes are in Board.sizes, for each board
        for target in board_dict:
            if target not in board_selected:
                continue
            base_sizes = self._base_board_dict[target].sizes
            outcome = board_dict[target]
            sizes = outcome.sizes

            # Loop through the list of images, creating a dict of size
            # changes for each image/part. We end up with something like
            # {'target' : 'snapper9g45, 'data' : 5, 'u-boot-spl:text' : -4}
            # which means that U-Boot data increased by 5 bytes and SPL
            # text decreased by 4.
            err = {'_target' : target}
            for image in sizes:
                if image in base_sizes:
                    base_image = base_sizes[image]
                    # Loop through the text, data, bss parts
                    for part in sorted(sizes[image]):
                        diff = sizes[image][part] - base_image[part]
                        col = None
                        if diff:
                            if image == 'u-boot':
                                name = part
                            else:
                                name = image + ':' + part
                            err[name] = diff
            arch = board_selected[target].arch
            if not arch in arch_count:
                arch_count[arch] = 1
            else:
                arch_count[arch] += 1
            if not sizes:
                pass    # Only add to our list when we have some stats
            elif not arch in arch_list:
                arch_list[arch] = [err]
            else:
                arch_list[arch].append(err)

        # We now have a list of image size changes sorted by arch
        # Print out a summary of these
        for arch, target_list in arch_list.items():
            # Get total difference for each type
            totals = {}
            for result in target_list:
                total = 0
                for name, diff in result.items():
                    if name.startswith('_'):
                        continue
                    total += diff
                    if name in totals:
                        totals[name] += diff
                    else:
                        totals[name] = diff
                result['_total_diff'] = total
                result['_outcome'] = board_dict[result['_target']]

            count = len(target_list)
            printed_arch = False
            for name in sorted(totals):
                diff = totals[name]
                if diff:
                    # Display the average difference in this name for this
                    # architecture
                    avg_diff = float(diff) / count
                    color = self.col.RED if avg_diff > 0 else self.col.GREEN
                    msg = ' %s %+1.1f' % (name, avg_diff)
                    if not printed_arch:
                        tprint('%10s: (for %d/%d boards)' % (arch, count,
                              arch_count[arch]), newline=False)
                        printed_arch = True
                    tprint(msg, colour=color, newline=False)

            if printed_arch:
                tprint()
                if show_detail:
                    self.print_size_detail(target_list, show_bloat)


    def print_result_summary(self, board_selected, board_dict, err_lines,
                           err_line_boards, warn_lines, warn_line_boards,
                           config, environment, show_sizes, show_detail,
                           show_bloat, show_config, show_environment):
        """Compare results with the base results and display delta.

        Only boards mentioned in board_selected will be considered. This
        function is intended to be called repeatedly with the results of
        each commit. It therefore shows a 'diff' between what it saw in
        the last call and what it sees now.

        Args:
            board_selected: Dict containing boards to summarise, keyed by
                board.target
            board_dict: Dict containing boards for which we built this
                commit, keyed by board.target. The value is an Outcome object.
            err_lines: A list of errors for this commit, or [] if there is
                none, or we don't want to print errors
            err_line_boards: Dict keyed by error line, containing a list of
                the Board objects with that error
            warn_lines: A list of warnings for this commit, or [] if there is
                none, or we don't want to print errors
            warn_line_boards: Dict keyed by warning line, containing a list of
                the Board objects with that warning
            config: Dictionary keyed by filename - e.g. '.config'. Each
                    value is itself a dictionary:
                        key: config name
                        value: config value
            environment: Dictionary keyed by environment variable, Each
                     value is the value of environment variable.
            show_sizes: Show image size deltas
            show_detail: Show size delta detail for each board if show_sizes
            show_bloat: Show detail for each function
            show_config: Show config changes
            show_environment: Show environment changes
        """
        def _board_list(line, line_boards):
            """Helper function to get a line of boards containing a line

            Args:
                line: Error line to search for
                line_boards: boards to search, each a Board
            Return:
                List of boards with that error line, or [] if the user has not
                    requested such a list
            """
            brds = []
            board_set = set()
            if self._list_error_boards:
                for brd in line_boards[line]:
                    if not brd in board_set:
                        brds.append(brd)
                        board_set.add(brd)
            return brds

        def _calc_error_delta(base_lines, base_line_boards, lines, line_boards,
                            char):
            """Calculate the required output based on changes in errors

            Args:
                base_lines: List of errors/warnings for previous commit
                base_line_boards: Dict keyed by error line, containing a list
                    of the Board objects with that error in the previous commit
                lines: List of errors/warning for this commit, each a str
                line_boards: Dict keyed by error line, containing a list
                    of the Board objects with that error in this commit
                char: Character representing error ('') or warning ('w'). The
                    broken ('+') or fixed ('-') characters are added in this
                    function

            Returns:
                Tuple
                    List of ErrLine objects for 'better' lines
                    List of ErrLine objects for 'worse' lines
            """
            better_lines = []
            worse_lines = []
            for line in lines:
                if line not in base_lines:
                    errline = ErrLine(char + '+', _board_list(line, line_boards),
                                      line)
                    worse_lines.append(errline)
            for line in base_lines:
                if line not in lines:
                    errline = ErrLine(char + '-',
                                      _board_list(line, base_line_boards), line)
                    better_lines.append(errline)
            return better_lines, worse_lines

        def _calc_config(delta, name, config):
            """Calculate configuration changes

            Args:
                delta: Type of the delta, e.g. '+'
                name: name of the file which changed (e.g. .config)
                config: configuration change dictionary
                    key: config name
                    value: config value
            Returns:
                String containing the configuration changes which can be
                    printed
            """
            out = ''
            for key in sorted(config.keys()):
                out += '%s=%s ' % (key, config[key])
            return '%s %s: %s' % (delta, name, out)

        def _add_config(lines, name, config_plus, config_minus, config_change):
            """Add changes in configuration to a list

            Args:
                lines: list to add to
                name: config file name
                config_plus: configurations added, dictionary
                    key: config name
                    value: config value
                config_minus: configurations removed, dictionary
                    key: config name
                    value: config value
                config_change: configurations changed, dictionary
                    key: config name
                    value: config value
            """
            if config_plus:
                lines.append(_calc_config('+', name, config_plus))
            if config_minus:
                lines.append(_calc_config('-', name, config_minus))
            if config_change:
                lines.append(_calc_config('c', name, config_change))

        def _output_config_info(lines):
            for line in lines:
                if not line:
                    continue
                col = None
                if line[0] == '+':
                    col = self.col.GREEN
                elif line[0] == '-':
                    col = self.col.RED
                elif line[0] == 'c':
                    col = self.col.YELLOW
                tprint('   ' + line, newline=True, colour=col)

        def _output_err_lines(err_lines, colour):
            """Output the line of error/warning lines, if not empty

            Also increments self._error_lines if err_lines not empty

            Args:
                err_lines: List of ErrLine objects, each an error or warning
                    line, possibly including a list of boards with that
                    error/warning
                colour: Colour to use for output
            """
            if err_lines:
                out_list = []
                for line in err_lines:
                    names = [brd.target for brd in line.brds]
                    board_str = ' '.join(names) if names else ''
                    if board_str:
                        out = self.col.build(colour, line.char + '(')
                        out += self.col.build(self.col.MAGENTA, board_str,
                                              bright=False)
                        out += self.col.build(colour, ') %s' % line.errline)
                    else:
                        out = self.col.build(colour, line.char + line.errline)
                    out_list.append(out)
                tprint('\n'.join(out_list))
                self._error_lines += 1


        ok_boards = []      # List of boards fixed since last commit
        warn_boards = []    # List of boards with warnings since last commit
        err_boards = []     # List of new broken boards since last commit
        new_boards = []     # List of boards that didn't exist last time
        unknown_boards = [] # List of boards that were not built

        for target in board_dict:
            if target not in board_selected:
                continue

            # If the board was built last time, add its outcome to a list
            if target in self._base_board_dict:
                base_outcome = self._base_board_dict[target].rc
                outcome = board_dict[target]
                if outcome.rc == OUTCOME_UNKNOWN:
                    unknown_boards.append(target)
                elif outcome.rc < base_outcome:
                    if outcome.rc == OUTCOME_WARNING:
                        warn_boards.append(target)
                    else:
                        ok_boards.append(target)
                elif outcome.rc > base_outcome:
                    if outcome.rc == OUTCOME_WARNING:
                        warn_boards.append(target)
                    else:
                        err_boards.append(target)
            else:
                new_boards.append(target)

        # Get a list of errors and warnings that have appeared, and disappeared
        better_err, worse_err = _calc_error_delta(self._base_err_lines,
                self._base_err_line_boards, err_lines, err_line_boards, '')
        better_warn, worse_warn = _calc_error_delta(self._base_warn_lines,
                self._base_warn_line_boards, warn_lines, warn_line_boards, 'w')

        # For the IDE mode, print out all the output
        if self._ide:
            outcome = board_dict[target]
            for line in outcome.err_lines:
                sys.stderr.write(line)

        # Display results by arch
        elif any((ok_boards, warn_boards, err_boards, unknown_boards, new_boards,
                worse_err, better_err, worse_warn, better_warn)):
            arch_list = {}
            self.add_outcome(board_selected, arch_list, ok_boards, '',
                    self.col.GREEN)
            self.add_outcome(board_selected, arch_list, warn_boards, 'w+',
                    self.col.YELLOW)
            self.add_outcome(board_selected, arch_list, err_boards, '+',
                    self.col.RED)
            self.add_outcome(board_selected, arch_list, new_boards, '*', self.col.BLUE)
            if self._show_unknown:
                self.add_outcome(board_selected, arch_list, unknown_boards, '?',
                        self.col.MAGENTA)
            for arch, target_list in arch_list.items():
                tprint('%10s: %s' % (arch, target_list))
                self._error_lines += 1
            _output_err_lines(better_err, colour=self.col.GREEN)
            _output_err_lines(worse_err, colour=self.col.RED)
            _output_err_lines(better_warn, colour=self.col.CYAN)
            _output_err_lines(worse_warn, colour=self.col.YELLOW)

        if show_sizes:
            self.print_size_summary(board_selected, board_dict, show_detail,
                                  show_bloat)

        if show_environment and self._base_environment:
            lines = []

            for target in board_dict:
                if target not in board_selected:
                    continue

                tbase = self._base_environment[target]
                tenvironment = environment[target]
                environment_plus = {}
                environment_minus = {}
                environment_change = {}
                base = tbase.environment
                for key, value in tenvironment.environment.items():
                    if key not in base:
                        environment_plus[key] = value
                for key, value in base.items():
                    if key not in tenvironment.environment:
                        environment_minus[key] = value
                for key, value in base.items():
                    new_value = tenvironment.environment.get(key)
                    if new_value and value != new_value:
                        desc = '%s -> %s' % (value, new_value)
                        environment_change[key] = desc

                _add_config(lines, target, environment_plus, environment_minus,
                           environment_change)

            _output_config_info(lines)

        if show_config and self._base_config:
            summary = {}
            arch_config_plus = {}
            arch_config_minus = {}
            arch_config_change = {}
            arch_list = []

            for target in board_dict:
                if target not in board_selected:
                    continue
                arch = board_selected[target].arch
                if arch not in arch_list:
                    arch_list.append(arch)

            for arch in arch_list:
                arch_config_plus[arch] = {}
                arch_config_minus[arch] = {}
                arch_config_change[arch] = {}
                for name in self.config_filenames:
                    arch_config_plus[arch][name] = {}
                    arch_config_minus[arch][name] = {}
                    arch_config_change[arch][name] = {}

            for target in board_dict:
                if target not in board_selected:
                    continue

                arch = board_selected[target].arch

                all_config_plus = {}
                all_config_minus = {}
                all_config_change = {}
                tbase = self._base_config[target]
                tconfig = config[target]
                lines = []
                for name in self.config_filenames:
                    if not tconfig.config[name]:
                        continue
                    config_plus = {}
                    config_minus = {}
                    config_change = {}
                    base = tbase.config[name]
                    for key, value in tconfig.config[name].items():
                        if key not in base:
                            config_plus[key] = value
                            all_config_plus[key] = value
                    for key, value in base.items():
                        if key not in tconfig.config[name]:
                            config_minus[key] = value
                            all_config_minus[key] = value
                    for key, value in base.items():
                        new_value = tconfig.config.get(key)
                        if new_value and value != new_value:
                            desc = '%s -> %s' % (value, new_value)
                            config_change[key] = desc
                            all_config_change[key] = desc

                    arch_config_plus[arch][name].update(config_plus)
                    arch_config_minus[arch][name].update(config_minus)
                    arch_config_change[arch][name].update(config_change)

                    _add_config(lines, name, config_plus, config_minus,
                               config_change)
                _add_config(lines, 'all', all_config_plus, all_config_minus,
                           all_config_change)
                summary[target] = '\n'.join(lines)

            lines_by_target = {}
            for target, lines in summary.items():
                if lines in lines_by_target:
                    lines_by_target[lines].append(target)
                else:
                    lines_by_target[lines] = [target]

            for arch in arch_list:
                lines = []
                all_plus = {}
                all_minus = {}
                all_change = {}
                for name in self.config_filenames:
                    all_plus.update(arch_config_plus[arch][name])
                    all_minus.update(arch_config_minus[arch][name])
                    all_change.update(arch_config_change[arch][name])
                    _add_config(lines, name, arch_config_plus[arch][name],
                               arch_config_minus[arch][name],
                               arch_config_change[arch][name])
                _add_config(lines, 'all', all_plus, all_minus, all_change)
                #arch_summary[target] = '\n'.join(lines)
                if lines:
                    tprint('%s:' % arch)
                    _output_config_info(lines)

            for lines, targets in lines_by_target.items():
                if not lines:
                    continue
                tprint('%s :' % ' '.join(sorted(targets)))
                _output_config_info(lines.split('\n'))


        # Save our updated information for the next call to this function
        self._base_board_dict = board_dict
        self._base_err_lines = err_lines
        self._base_warn_lines = warn_lines
        self._base_err_line_boards = err_line_boards
        self._base_warn_line_boards = warn_line_boards
        self._base_config = config
        self._base_environment = environment

        # Get a list of boards that did not get built, if needed
        not_built = []
        for brd in board_selected:
            if not brd in board_dict:
                not_built.append(brd)
        if not_built:
            tprint("Boards not built (%d): %s" % (len(not_built),
                  ', '.join(not_built)))

    def produce_result_summary(self, commit_upto, commits, board_selected):
            (board_dict, err_lines, err_line_boards, warn_lines,
             warn_line_boards, config, environment) = self.get_result_summary(
                    board_selected, commit_upto,
                    read_func_sizes=self._show_bloat,
                    read_config=self._show_config,
                    read_environment=self._show_environment)
            if commits:
                msg = '%02d: %s' % (commit_upto + 1,
                        commits[commit_upto].subject)
                tprint(msg, colour=self.col.BLUE)
            self.print_result_summary(board_selected, board_dict,
                    err_lines if self._show_errors else [], err_line_boards,
                    warn_lines if self._show_errors else [], warn_line_boards,
                    config, environment, self._show_sizes, self._show_detail,
                    self._show_bloat, self._show_config, self._show_environment)

    def show_summary(self, commits, board_selected):
        """Show a build summary for U-Boot for a given board list.

        Reset the result summary, then repeatedly call GetResultSummary on
        each commit's results, then display the differences we see.

        Args:
            commit: Commit objects to summarise
            board_selected: Dict containing boards to summarise
        """
        self.commit_count = len(commits) if commits else 1
        self.commits = commits
        self.reset_result_summary(board_selected)
        self._error_lines = 0

        for commit_upto in range(0, self.commit_count, self._step):
            self.produce_result_summary(commit_upto, commits, board_selected)
        if not self._error_lines:
            tprint('(no errors to report)', colour=self.col.GREEN)


    def setup_build(self, board_selected, commits):
        """Set up ready to start a build.

        Args:
            board_selected: Selected boards to build
            commits: Selected commits to build
        """
        # First work out how many commits we will build
        count = (self.commit_count + self._step - 1) // self._step
        self.count = len(board_selected) * count
        self.upto = self.warned = self.fail = 0
        self._timestamps = collections.deque()

    def get_thread_dir(self, thread_num):
        """Get the directory path to the working dir for a thread.

        Args:
            thread_num: Number of thread to check (-1 for main process, which
                is treated as 0)
        """
        if self.work_in_output:
            return self._working_dir
        return os.path.join(self._working_dir, '%02d' % max(thread_num, 0))

    def _prepare_thread(self, thread_num, setup_git):
        """Prepare the working directory for a thread.

        This clones or fetches the repo into the thread's work directory.
        Optionally, it can create a linked working tree of the repo in the
        thread's work directory instead.

        Args:
            thread_num: Thread number (0, 1, ...)
            setup_git:
               'clone' to set up a git clone
               'worktree' to set up a git worktree
        """
        thread_dir = self.get_thread_dir(thread_num)
        builderthread.mkdir(thread_dir)
        git_dir = os.path.join(thread_dir, '.git')

        # Create a worktree or a git repo clone for this thread if it
        # doesn't already exist
        if setup_git and self.git_dir:
            src_dir = os.path.abspath(self.git_dir)
            if os.path.isdir(git_dir):
                # This is a clone of the src_dir repo, we can keep using
                # it but need to fetch from src_dir.
                tprint('\rFetching repo for thread %d' % thread_num,
                      newline=False)
                gitutil.fetch(git_dir, thread_dir)
                terminal.print_clear()
            elif os.path.isfile(git_dir):
                # This is a worktree of the src_dir repo, we don't need to
                # create it again or update it in any way.
                pass
            elif os.path.exists(git_dir):
                # Don't know what could trigger this, but we probably
                # can't create a git worktree/clone here.
                raise ValueError('Git dir %s exists, but is not a file '
                                 'or a directory.' % git_dir)
            elif setup_git == 'worktree':
                tprint('\rChecking out worktree for thread %d' % thread_num,
                      newline=False)
                gitutil.add_worktree(src_dir, thread_dir)
                terminal.print_clear()
            elif setup_git == 'clone' or setup_git == True:
                tprint('\rCloning repo for thread %d' % thread_num,
                      newline=False)
                gitutil.clone(src_dir, thread_dir)
                terminal.print_clear()
            else:
                raise ValueError("Can't setup git repo with %s." % setup_git)

    def _prepare_working_space(self, max_threads, setup_git):
        """Prepare the working directory for use.

        Set up the git repo for each thread. Creates a linked working tree
        if git-worktree is available, or clones the repo if it isn't.

        Args:
            max_threads: Maximum number of threads we expect to need. If 0 then
                1 is set up, since the main process still needs somewhere to
                work
            setup_git: True to set up a git worktree or a git clone
        """
        builderthread.mkdir(self._working_dir)
        if setup_git and self.git_dir:
            src_dir = os.path.abspath(self.git_dir)
            if gitutil.check_worktree_is_available(src_dir):
                setup_git = 'worktree'
                # If we previously added a worktree but the directory for it
                # got deleted, we need to prune its files from the repo so
                # that we can check out another in its place.
                gitutil.prune_worktrees(src_dir)
            else:
                setup_git = 'clone'

        # Always do at least one thread
        for thread in range(max(max_threads, 1)):
            self._prepare_thread(thread, setup_git)

    def _get_output_space_removals(self):
        """Get the output directories ready to receive files.

        Figure out what needs to be deleted in the output directory before it
        can be used. We only delete old buildman directories which have the
        expected name pattern. See get_output_dir().

        Returns:
            List of full paths of directories to remove
        """
        if not self.commits:
            return
        dir_list = []
        for commit_upto in range(self.commit_count):
            dir_list.append(self.get_output_dir(commit_upto))

        to_remove = []
        for dirname in glob.glob(os.path.join(self.base_dir, '*')):
            if dirname not in dir_list:
                leaf = dirname[len(self.base_dir) + 1:]
                m =  re.match('[0-9]+_g[0-9a-f]+_.*', leaf)
                if m:
                    to_remove.append(dirname)
        return to_remove

    def _prepare_output_space(self):
        """Get the output directories ready to receive files.

        We delete any output directories which look like ones we need to
        create. Having left over directories is confusing when the user wants
        to check the output manually.
        """
        to_remove = self._get_output_space_removals()
        if to_remove:
            tprint('Removing %d old build directories...' % len(to_remove),
                  newline=False)
            for dirname in to_remove:
                shutil.rmtree(dirname)
            terminal.print_clear()

    def build_boards(self, commits, board_selected, keep_outputs, verbose):
        """Build all commits for a list of boards

        Args:
            commits: List of commits to be build, each a Commit object
            boards_selected: Dict of selected boards, key is target name,
                    value is Board object
            keep_outputs: True to save build output files
            verbose: Display build results as they are completed
        Returns:
            Tuple containing:
                - number of boards that failed to build
                - number of boards that issued warnings
                - list of thread exceptions raised
        """
        self.commit_count = len(commits) if commits else 1
        self.commits = commits
        self._verbose = verbose

        self.reset_result_summary(board_selected)
        builderthread.mkdir(self.base_dir, parents = True)
        self._prepare_working_space(min(self.num_threads, len(board_selected)),
                commits is not None)
        self._prepare_output_space()
        if not self._ide:
            tprint('\rStarting build...', newline=False)
        self._start_time = datetime.now()
        self.setup_build(board_selected, commits)
        self.process_result(None)
        self.thread_exceptions = []
        # Create jobs to build all commits for each board
        for brd in board_selected.values():
            job = builderthread.BuilderJob()
            job.brd = brd
            job.commits = commits
            job.keep_outputs = keep_outputs
            job.work_in_output = self.work_in_output
            job.adjust_cfg = self.adjust_cfg
            job.step = self._step
            if self.num_threads:
                self.queue.put(job)
            else:
                self._single_builder.run_job(job)

        if self.num_threads:
            term = threading.Thread(target=self.queue.join)
            term.setDaemon(True)
            term.start()
            while term.is_alive():
                term.join(100)

            # Wait until we have processed all output
            self.out_queue.join()
        if not self._ide:
            tprint()

            msg = 'Completed: %d total built' % self.count
            if self.already_done:
                msg += ' (%d previously' % self.already_done
            if self.already_done != self.count:
                msg += ', %d newly' % (self.count - self.already_done)
            msg += ')'
            duration = datetime.now() - self._start_time
            if duration > timedelta(microseconds=1000000):
                if duration.microseconds >= 500000:
                    duration = duration + timedelta(seconds=1)
                duration = duration - timedelta(microseconds=duration.microseconds)
                rate = float(self.count) / duration.total_seconds()
                msg += ', duration %s, rate %1.2f' % (duration, rate)
            tprint(msg)
            if self.thread_exceptions:
                tprint('Failed: %d thread exceptions' % len(self.thread_exceptions),
                    colour=self.col.RED)

        return (self.fail, self.warned, self.thread_exceptions)
