# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2014 Google, Inc
#

"""Implementation the bulider threads

This module provides the BuilderThread class, which handles calling the builder
based on the jobs provided.
"""

import errno
import glob
import io
import os
import shutil
import sys
import threading

from buildman import cfgutil
from patman import gitutil
from u_boot_pylib import command

RETURN_CODE_RETRY = -1
BASE_ELF_FILENAMES = ['u-boot', 'spl/u-boot-spl', 'tpl/u-boot-tpl']

# Common extensions for images
COMMON_EXTS = ['.bin', '.rom', '.itb', '.img']

def mkdir(dirname, parents=False):
    """Make a directory if it doesn't already exist.

    Args:
        dirname (str): Directory to create
        parents (bool): True to also make parent directories

    Raises:
        OSError: File already exists
    """
    try:
        if parents:
            os.makedirs(dirname)
        else:
            os.mkdir(dirname)
    except OSError as err:
        if err.errno == errno.EEXIST:
            if os.path.realpath('.') == os.path.realpath(dirname):
                print(f"Cannot create the current working directory '{dirname}'!")
                sys.exit(1)
        else:
            raise


def _remove_old_outputs(out_dir):
    """Remove any old output-target files

    Args:
        out_dir (str): Output directory for the build

    Since we use a build directory that was previously used by another
    board, it may have produced an SPL image. If we don't remove it (i.e.
    see do_config and self.mrproper below) then it will appear to be the
    output of this build, even if it does not produce SPL images.
    """
    for elf in BASE_ELF_FILENAMES:
        fname = os.path.join(out_dir, elf)
        if os.path.exists(fname):
            os.remove(fname)


def copy_files(out_dir, build_dir, dirname, patterns):
    """Copy files from the build directory to the output.

    Args:
        out_dir (str): Path to output directory containing the files
        build_dir (str): Place to copy the files
        dirname (str): Source directory, '' for normal U-Boot, 'spl' for SPL
        patterns (list of str): A list of filenames to copy, each relative
           to the build directory
    """
    for pattern in patterns:
        file_list = glob.glob(os.path.join(out_dir, dirname, pattern))
        for fname in file_list:
            target = os.path.basename(fname)
            if dirname:
                base, ext = os.path.splitext(target)
                if ext:
                    target = f'{base}-{dirname}{ext}'
            shutil.copy(fname, os.path.join(build_dir, target))


# pylint: disable=R0903
class BuilderJob:
    """Holds information about a job to be performed by a thread

    Members:
        brd: Board object to build
        commits: List of Commit objects to build
        keep_outputs: True to save build output files
        step: 1 to process every commit, n to process every nth commit
        work_in_output: Use the output directory as the work directory and
            don't write to a separate output directory.
    """
    def __init__(self):
        self.brd = None
        self.commits = []
        self.keep_outputs = False
        self.step = 1
        self.work_in_output = False


class ResultThread(threading.Thread):
    """This thread processes results from builder threads.

    It simply passes the results on to the builder. There is only one
    result thread, and this helps to serialise the build output.
    """
    def __init__(self, builder):
        """Set up a new result thread

        Args:
            builder: Builder which will be sent each result
        """
        threading.Thread.__init__(self)
        self.builder = builder

    def run(self):
        """Called to start up the result thread.

        We collect the next result job and pass it on to the build.
        """
        while True:
            result = self.builder.out_queue.get()
            self.builder.process_result(result)
            self.builder.out_queue.task_done()


class BuilderThread(threading.Thread):
    """This thread builds U-Boot for a particular board.

    An input queue provides each new job. We run 'make' to build U-Boot
    and then pass the results on to the output queue.

    Members:
        builder: The builder which contains information we might need
        thread_num: Our thread number (0-n-1), used to decide on a
            temporary directory. If this is -1 then there are no threads
            and we are the (only) main process
        mrproper: Use 'make mrproper' before each reconfigure
        per_board_out_dir: True to build in a separate persistent directory per
            board rather than a thread-specific directory
        test_exception: Used for testing; True to raise an exception instead of
            reporting the build result
    """
    def __init__(self, builder, thread_num, mrproper, per_board_out_dir,
                 test_exception=False):
        """Set up a new builder thread"""
        threading.Thread.__init__(self)
        self.builder = builder
        self.thread_num = thread_num
        self.mrproper = mrproper
        self.per_board_out_dir = per_board_out_dir
        self.test_exception = test_exception
        self.toolchain = None

    def make(self, commit, brd, stage, cwd, *args, **kwargs):
        """Run 'make' on a particular commit and board.

        The source code will already be checked out, so the 'commit'
        argument is only for information.

        Args:
            commit (Commit): Commit that is being built
            brd (Board): Board that is being built
            stage (str): Stage of the build. Valid stages are:
                        mrproper - can be called to clean source
                        config - called to configure for a board
                        build - the main make invocation - it does the build
            cwd (str): Working directory to set, or None to leave it alone
            *args (list of str): Arguments to pass to 'make'
            **kwargs (dict): A list of keyword arguments to pass to
                command.run_pipe()

        Returns:
            CommandResult object
        """
        return self.builder.do_make(commit, brd, stage, cwd, *args,
                **kwargs)

    def _build_args(self, brd, out_dir, out_rel_dir, work_dir, commit_upto):
        """Set up arguments to the args list based on the settings

        Args:
            brd (Board): Board to create arguments for
            out_dir (str): Path to output directory containing the files
            out_rel_dir (str): Output directory relative to the current dir
            work_dir (str): Directory to which the source will be checked out
            commit_upto (int): Commit number to build (0...n-1)

        Returns:
            tuple:
                list of str: Arguments to pass to make
                str: Current working directory, or None if no commit
                str: Source directory (typically the work directory)
        """
        args = []
        cwd = work_dir
        src_dir = os.path.realpath(work_dir)
        if not self.builder.in_tree:
            if commit_upto is None:
                # In this case we are building in the original source directory
                # (i.e. the current directory where buildman is invoked. The
                # output directory is set to this thread's selected work
                # directory.
                #
                # Symlinks can confuse U-Boot's Makefile since we may use '..'
                # in our path, so remove them.
                real_dir = os.path.realpath(out_dir)
                args.append(f'O={real_dir}')
                cwd = None
                src_dir = os.getcwd()
            else:
                args.append(f'O={out_rel_dir}')
        if self.builder.verbose_build:
            args.append('V=1')
        else:
            args.append('-s')
        if self.builder.num_jobs is not None:
            args.extend(['-j', str(self.builder.num_jobs)])
        if self.builder.warnings_as_errors:
            args.append('KCFLAGS=-Werror')
            args.append('HOSTCFLAGS=-Werror')
        if self.builder.allow_missing:
            args.append('BINMAN_ALLOW_MISSING=1')
        if self.builder.no_lto:
            args.append('NO_LTO=1')
        if self.builder.reproducible_builds:
            args.append('SOURCE_DATE_EPOCH=0')
        args.extend(self.builder.toolchains.GetMakeArguments(brd))
        args.extend(self.toolchain.MakeArgs())
        return args, cwd, src_dir

    def _reconfigure(self, commit, brd, cwd, args, env, config_args, config_out,
                     cmd_list, mrproper):
        """Reconfigure the build

        Args:
            commit (Commit): Commit only being built
            brd (Board): Board being built
            cwd (str): Current working directory
            args (list of str): Arguments to pass to make
            env (dict): Environment strings
            config_args (list of str): defconfig arg for this board
            cmd_list (list of str): List to add the commands to, for logging
            mrproper (bool): True to run mrproper first

        Returns:
            CommandResult object
        """
        if mrproper:
            result = self.make(commit, brd, 'mrproper', cwd, 'mrproper', *args,
                               env=env)
            config_out.write(result.combined)
            cmd_list.append([self.builder.gnu_make, 'mrproper', *args])
        result = self.make(commit, brd, 'config', cwd, *(args + config_args),
                           env=env)
        cmd_list.append([self.builder.gnu_make] + args + config_args)
        config_out.write(result.combined)
        return result

    def _build(self, commit, brd, cwd, args, env, cmd_list, config_only):
        """Perform the build

        Args:
            commit (Commit): Commit only being built
            brd (Board): Board being built
            cwd (str): Current working directory
            args (list of str): Arguments to pass to make
            env (dict): Environment strings
            cmd_list (list of str): List to add the commands to, for logging
            config_only (bool): True if this is a config-only build (using the
                'make cfg' target)

        Returns:
            CommandResult object
        """
        if config_only:
            args.append('cfg')
        result = self.make(commit, brd, 'build', cwd, *args, env=env)
        cmd_list.append([self.builder.gnu_make] + args)
        if (result.return_code == 2 and
            ('Some images are invalid' in result.stderr)):
            # This is handled later by the check for output in stderr
            result.return_code = 0
        return result

    def _read_done_file(self, commit_upto, brd, force_build,
                        force_build_failures):
        """Check the 'done' file and see if this commit should be built

        Args:
            commit (Commit): Commit only being built
            brd (Board): Board being built
            force_build (bool): Force a build even if one was previously done
            force_build_failures (bool): Force a bulid if the previous result
                showed failure

        Returns:
            tuple:
                bool: True if build should be built
                CommandResult: if there was a previous run:
                    - already_done set to True
                    - return_code set to return code
                    - result.stderr set to 'bad' if stderr output was recorded
        """
        result = command.CommandResult()
        done_file = self.builder.get_done_file(commit_upto, brd.target)
        result.already_done = os.path.exists(done_file)
        will_build = (force_build or force_build_failures or
            not result.already_done)
        if result.already_done:
            with open(done_file, 'r', encoding='utf-8') as outf:
                try:
                    result.return_code = int(outf.readline())
                except ValueError:
                    # The file may be empty due to running out of disk space.
                    # Try a rebuild
                    result.return_code = RETURN_CODE_RETRY

            # Check the signal that the build needs to be retried
            if result.return_code == RETURN_CODE_RETRY:
                will_build = True
            elif will_build:
                err_file = self.builder.get_err_file(commit_upto, brd.target)
                if os.path.exists(err_file) and os.stat(err_file).st_size:
                    result.stderr = 'bad'
                elif not force_build:
                    # The build passed, so no need to build it again
                    will_build = False
        return will_build, result

    def _decide_dirs(self, brd, work_dir, work_in_output):
        """Decide the output directory to use

        Args:
            work_dir (str): Directory to which the source will be checked out
            work_in_output (bool): Use the output directory as the work
                directory and don't write to a separate output directory.

        Returns:
            tuple:
                out_dir (str): Output directory for the build
                out_rel_dir (str): Output directory relatie to the current dir
        """
        if work_in_output or self.builder.in_tree:
            out_rel_dir = None
            out_dir = work_dir
        else:
            if self.per_board_out_dir:
                out_rel_dir = os.path.join('..', brd.target)
            else:
                out_rel_dir = 'build'
            out_dir = os.path.join(work_dir, out_rel_dir)
        return out_dir, out_rel_dir

    def _checkout(self, commit_upto, work_dir):
        """Checkout the right commit

        Args:
            commit_upto (int): Commit number to build (0...n-1)
            work_dir (str): Directory to which the source will be checked out

        Returns:
            Commit: Commit being built, or 'current' for current source
        """
        if self.builder.commits:
            commit = self.builder.commits[commit_upto]
            if self.builder.checkout:
                git_dir = os.path.join(work_dir, '.git')
                gitutil.checkout(commit.hash, git_dir, work_dir, force=True)
        else:
            commit = 'current'
        return commit

    def _config_and_build(self, commit_upto, brd, work_dir, do_config, mrproper,
                          config_only, adjust_cfg, commit, out_dir, out_rel_dir,
                          result):
        """Do the build, configuring first if necessary

        Args:
            commit_upto (int): Commit number to build (0...n-1)
            brd (Board): Board to create arguments for
            work_dir (str): Directory to which the source will be checked out
            do_config (bool): True to run a make <board>_defconfig on the source
            mrproper (bool): True to run mrproper first
            config_only (bool): Only configure the source, do not build it
            adjust_cfg (list of str): See the cfgutil module and run_commit()
            commit (Commit): Commit only being built
            out_dir (str): Output directory for the build
            out_rel_dir (str): Output directory relatie to the current dir
            result (CommandResult): Previous result

        Returns:
            tuple:
                result (CommandResult): Result of the build
                do_config (bool): indicates whether 'make config' is needed on
                    the next incremental build
        """
        # Set up the environment and command line
        env = self.toolchain.MakeEnvironment(self.builder.full_path)
        mkdir(out_dir)

        args, cwd, src_dir = self._build_args(brd, out_dir, out_rel_dir,
                                              work_dir, commit_upto)
        config_args = [f'{brd.target}_defconfig']
        config_out = io.StringIO()

        _remove_old_outputs(out_dir)

        # If we need to reconfigure, do that now
        cfg_file = os.path.join(out_dir, '.config')
        cmd_list = []
        if do_config or adjust_cfg:
            result = self._reconfigure(
                commit, brd, cwd, args, env, config_args, config_out, cmd_list,
                mrproper)
            do_config = False   # No need to configure next time
            if adjust_cfg:
                cfgutil.adjust_cfg_file(cfg_file, adjust_cfg)

        # Now do the build, if everything looks OK
        if result.return_code == 0:
            if adjust_cfg:
                oldc_args = list(args) + ['oldconfig']
                oldc_result = self.make(commit, brd, 'oldconfig', cwd,
                                        *oldc_args, env=env)
                if oldc_result.return_code:
                    return oldc_result
            result = self._build(commit, brd, cwd, args, env, cmd_list,
                                 config_only)
            if adjust_cfg:
                errs = cfgutil.check_cfg_file(cfg_file, adjust_cfg)
                if errs:
                    result.stderr += errs
                    result.return_code = 1
        result.stderr = result.stderr.replace(src_dir + '/', '')
        if self.builder.verbose_build:
            result.stdout = config_out.getvalue() + result.stdout
        result.cmd_list = cmd_list
        return result, do_config

    def run_commit(self, commit_upto, brd, work_dir, do_config, mrproper,
                   config_only, force_build, force_build_failures,
                   work_in_output, adjust_cfg):
        """Build a particular commit.

        If the build is already done, and we are not forcing a build, we skip
        the build and just return the previously-saved results.

        Args:
            commit_upto (int): Commit number to build (0...n-1)
            brd (Board): Board to build
            work_dir (str): Directory to which the source will be checked out
            do_config (bool): True to run a make <board>_defconfig on the source
            mrproper (bool): True to run mrproper first
            config_only (bool): Only configure the source, do not build it
            force_build (bool): Force a build even if one was previously done
            force_build_failures (bool): Force a bulid if the previous result
                showed failure
            work_in_output (bool) : Use the output directory as the work
                directory and don't write to a separate output directory.
            adjust_cfg (list of str): List of changes to make to .config file
                before building. Each is one of (where C is either CONFIG_xxx
                or just xxx):
                     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

        Returns:
            tuple containing:
                - CommandResult object containing the results of the build
                - boolean indicating whether 'make config' is still needed
        """
        # Create a default result - it will be overwritte by the call to
        # self.make() below, in the event that we do a build.
        out_dir, out_rel_dir = self._decide_dirs(brd, work_dir, work_in_output)

        # Check if the job was already completed last time
        will_build, result = self._read_done_file(commit_upto, brd, force_build,
                                                  force_build_failures)

        if will_build:
            # We are going to have to build it. First, get a toolchain
            if not self.toolchain:
                try:
                    self.toolchain = self.builder.toolchains.Select(brd.arch)
                except ValueError as err:
                    result.return_code = 10
                    result.stdout = ''
                    result.stderr = f'Tool chain error for {brd.arch}: {str(err)}'

            if self.toolchain:
                commit = self._checkout(commit_upto, work_dir)
                result, do_config = self._config_and_build(
                    commit_upto, brd, work_dir, do_config, mrproper,
                    config_only, adjust_cfg, commit, out_dir, out_rel_dir,
                    result)
            result.already_done = False

        result.toolchain = self.toolchain
        result.brd = brd
        result.commit_upto = commit_upto
        result.out_dir = out_dir
        return result, do_config

    def _write_result(self, result, keep_outputs, work_in_output):
        """Write a built result to the output directory.

        Args:
            result (CommandResult): result to write
            keep_outputs (bool): True to store the output binaries, False
                to delete them
            work_in_output (bool): Use the output directory as the work
                directory and don't write to a separate output directory.
        """
        # If we think this might have been aborted with Ctrl-C, record the
        # failure but not that we are 'done' with this board. A retry may fix
        # it.
        maybe_aborted = result.stderr and 'No child processes' in result.stderr

        if result.return_code >= 0 and result.already_done:
            return

        # Write the output and stderr
        output_dir = self.builder.get_output_dir(result.commit_upto)
        mkdir(output_dir)
        build_dir = self.builder.get_build_dir(result.commit_upto,
                result.brd.target)
        mkdir(build_dir)

        outfile = os.path.join(build_dir, 'log')
        with open(outfile, 'w', encoding='utf-8') as outf:
            if result.stdout:
                outf.write(result.stdout)

        errfile = self.builder.get_err_file(result.commit_upto,
                result.brd.target)
        if result.stderr:
            with open(errfile, 'w', encoding='utf-8') as outf:
                outf.write(result.stderr)
        elif os.path.exists(errfile):
            os.remove(errfile)

        # Fatal error
        if result.return_code < 0:
            return

        if result.toolchain:
            # Write the build result and toolchain information.
            done_file = self.builder.get_done_file(result.commit_upto,
                    result.brd.target)
            with open(done_file, 'w', encoding='utf-8') as outf:
                if maybe_aborted:
                    # Special code to indicate we need to retry
                    outf.write(f'{RETURN_CODE_RETRY}')
                else:
                    outf.write(f'{result.return_code}')
            with open(os.path.join(build_dir, 'toolchain'), 'w',
                      encoding='utf-8') as outf:
                print('gcc', result.toolchain.gcc, file=outf)
                print('path', result.toolchain.path, file=outf)
                print('cross', result.toolchain.cross, file=outf)
                print('arch', result.toolchain.arch, file=outf)
                outf.write(f'{result.return_code}')

            # Write out the image and function size information and an objdump
            env = result.toolchain.MakeEnvironment(self.builder.full_path)
            with open(os.path.join(build_dir, 'out-env'), 'wb') as outf:
                for var in sorted(env.keys()):
                    outf.write(b'%s="%s"' % (var, env[var]))

            with open(os.path.join(build_dir, 'out-cmd'), 'w',
                      encoding='utf-8') as outf:
                for cmd in result.cmd_list:
                    print(' '.join(cmd), file=outf)

            lines = []
            for fname in BASE_ELF_FILENAMES:
                cmd = [f'{self.toolchain.cross}nm', '--size-sort', fname]
                nm_result = command.run_pipe([cmd], capture=True,
                        capture_stderr=True, cwd=result.out_dir,
                        raise_on_error=False, env=env)
                if nm_result.stdout:
                    nm_fname = self.builder.get_func_sizes_file(
                        result.commit_upto, result.brd.target, fname)
                    with open(nm_fname, 'w', encoding='utf-8') as outf:
                        print(nm_result.stdout, end=' ', file=outf)

                cmd = [f'{self.toolchain.cross}objdump', '-h', fname]
                dump_result = command.run_pipe([cmd], capture=True,
                        capture_stderr=True, cwd=result.out_dir,
                        raise_on_error=False, env=env)
                rodata_size = ''
                if dump_result.stdout:
                    objdump = self.builder.get_objdump_file(result.commit_upto,
                                    result.brd.target, fname)
                    with open(objdump, 'w', encoding='utf-8') as outf:
                        print(dump_result.stdout, end=' ', file=outf)
                    for line in dump_result.stdout.splitlines():
                        fields = line.split()
                        if len(fields) > 5 and fields[1] == '.rodata':
                            rodata_size = fields[2]

                cmd = [f'{self.toolchain.cross}size', fname]
                size_result = command.run_pipe([cmd], capture=True,
                        capture_stderr=True, cwd=result.out_dir,
                        raise_on_error=False, env=env)
                if size_result.stdout:
                    lines.append(size_result.stdout.splitlines()[1] + ' ' +
                                 rodata_size)

            # Extract the environment from U-Boot and dump it out
            cmd = [f'{self.toolchain.cross}objcopy', '-O', 'binary',
                   '-j', '.rodata.default_environment',
                   'env/built-in.o', 'uboot.env']
            command.run_pipe([cmd], capture=True,
                            capture_stderr=True, cwd=result.out_dir,
                            raise_on_error=False, env=env)
            if not work_in_output:
                copy_files(result.out_dir, build_dir, '', ['uboot.env'])

            # Write out the image sizes file. This is similar to the output
            # of binutil's 'size' utility, but it omits the header line and
            # adds an additional hex value at the end of each line for the
            # rodata size
            if lines:
                sizes = self.builder.get_sizes_file(result.commit_upto,
                                result.brd.target)
                with open(sizes, 'w', encoding='utf-8') as outf:
                    print('\n'.join(lines), file=outf)

        if not work_in_output:
            # Write out the configuration files, with a special case for SPL
            for dirname in ['', 'spl', 'tpl']:
                copy_files(
                    result.out_dir, build_dir, dirname,
                    ['u-boot.cfg', 'spl/u-boot-spl.cfg', 'tpl/u-boot-tpl.cfg',
                     '.config', 'include/autoconf.mk',
                     'include/generated/autoconf.h'])

            # Now write the actual build output
            if keep_outputs:
                to_copy = ['u-boot*', '*.map', 'MLO', 'SPL',
                           'include/autoconf.mk', 'spl/u-boot-spl*',
                           'tpl/u-boot-tpl*', 'vpl/u-boot-vpl*']
                to_copy += [f'*{ext}' for ext in COMMON_EXTS]
                copy_files(result.out_dir, build_dir, '', to_copy)

    def _send_result(self, result):
        """Send a result to the builder for processing

        Args:
            result (CommandResult): results of the build

        Raises:
            ValueError: self.test_exception is true (for testing)
        """
        if self.test_exception:
            raise ValueError('test exception')
        if self.thread_num != -1:
            self.builder.out_queue.put(result)
        else:
            self.builder.process_result(result)

    def run_job(self, job):
        """Run a single job

        A job consists of a building a list of commits for a particular board.

        Args:
            job (Job): Job to build

        Raises:
            ValueError: Thread was interrupted
        """
        brd = job.brd
        work_dir = self.builder.get_thread_dir(self.thread_num)
        self.toolchain = None
        if job.commits:
            # Run 'make board_defconfig' on the first commit
            do_config = True
            commit_upto  = 0
            force_build = False
            for commit_upto in range(0, len(job.commits), job.step):
                result, request_config = self.run_commit(commit_upto, brd,
                        work_dir, do_config, self.mrproper,
                        self.builder.config_only,
                        force_build or self.builder.force_build,
                        self.builder.force_build_failures,
                        job.work_in_output, job.adjust_cfg)
                failed = result.return_code or result.stderr
                did_config = do_config
                if failed and not do_config and not self.mrproper:
                    # If our incremental build failed, try building again
                    # with a reconfig.
                    if self.builder.force_config_on_failure:
                        result, request_config = self.run_commit(commit_upto,
                            brd, work_dir, True,
                            self.mrproper or self.builder.fallback_mrproper,
                            False, True, False, job.work_in_output,
                            job.adjust_cfg)
                        did_config = True
                if not self.builder.force_reconfig:
                    do_config = request_config

                # If we built that commit, then config is done. But if we got
                # an warning, reconfig next time to force it to build the same
                # files that created warnings this time. Otherwise an
                # incremental build may not build the same file, and we will
                # think that the warning has gone away.
                # We could avoid this by using -Werror everywhere...
                # For errors, the problem doesn't happen, since presumably
                # the build stopped and didn't generate output, so will retry
                # that file next time. So we could detect warnings and deal
                # with them specially here. For now, we just reconfigure if
                # anything goes work.
                # Of course this is substantially slower if there are build
                # errors/warnings (e.g. 2-3x slower even if only 10% of builds
                # have problems).
                if (failed and not result.already_done and not did_config and
                        self.builder.force_config_on_failure):
                    # If this build failed, try the next one with a
                    # reconfigure.
                    # Sometimes if the board_config.h file changes it can mess
                    # with dependencies, and we get:
                    # make: *** No rule to make target `include/autoconf.mk',
                    #     needed by `depend'.
                    do_config = True
                    force_build = True
                else:
                    force_build = False
                    if self.builder.force_config_on_failure:
                        if failed:
                            do_config = True
                    result.commit_upto = commit_upto
                    if result.return_code < 0:
                        raise ValueError('Interrupt')

                # We have the build results, so output the result
                self._write_result(result, job.keep_outputs, job.work_in_output)
                self._send_result(result)
        else:
            # Just build the currently checked-out build
            result, request_config = self.run_commit(None, brd, work_dir, True,
                        self.mrproper, self.builder.config_only, True,
                        self.builder.force_build_failures, job.work_in_output,
                        job.adjust_cfg)
            result.commit_upto = 0
            self._write_result(result, job.keep_outputs, job.work_in_output)
            self._send_result(result)

    def run(self):
        """Our thread's run function

        This thread picks a job from the queue, runs it, and then goes to the
        next job.
        """
        while True:
            job = self.builder.queue.get()
            try:
                self.run_job(job)
            except Exception as exc:
                print('Thread exception (use -T0 to run without threads):',
                      exc)
                self.builder.thread_exceptions.append(exc)
            self.builder.queue.task_done()
