_narval/checkers/apycot/lgp.py
author David Douard <david.douard@logilab.fr>
Fri, 22 Jan 2016 17:14:04 +0100
changeset 1862 6063a2a6ee8c
parent 1841 f0c754604ae2
permissions -rw-r--r--
[checker] make lgp checker use hglib and add the node id as apycot package suffix in the context of checking draft changesets, the revision number is not guaranteed to be increasing, so let's build packages with a reasonably confident unique name.

import os
import logging
from glob import glob
import hglib

import apycotlib as apycot
from checkers.apycot import BaseChecker, AbstractFilteredFileChecker

from logilab.packaging.lgp import *

class FilePath(object):
    def __init__(self, path, host=None, **kwargs):
        self.path = path
        self.host = host
        self.__dict__.update(kwargs)

class LgpLogHandler(logging.Handler):
    def __init__(self, writer):
        logging.Handler.__init__(self)
        self.writer = writer
        self.path = None
        self.status = apycot.SUCCESS

    def emit(self, record):
        if record.levelno >= logging.CRITICAL:
            f = self.writer.fatal
            self.status = apycot.FAILURE
        elif record.levelno >= logging.ERROR:
            f = self.writer.error
            self.status = apycot.FAILURE
        elif record.levelno >= logging.WARNING:
            f = self.writer.warning
        elif record.levelno >= logging.INFO:
            f = self.writer.info
        else:
            f = self.writer.debug
        message = record.getMessage()
        f(message, path=self.path)
        self.writer.refresh_log()


class LgpCheckChecker(BaseChecker):
    """run tests on a project with lgp"""

    id = 'lgp.check'
    command = 'check'
    options_def = {
    }

    def do_check(self, test):
        status = apycot.SUCCESS
        cwd = os.getcwd()
        os.chdir(test.project_path())
        cmd = LGP.get_command(self.command)
        self.writer.debug(cmd)
        handler = LgpLogHandler(self.writer)
        cmd.logger.addHandler(handler)
        exit_status = cmd.main_run(['-vv'], LGP.rcfile)
        if exit_status:
            self.writer.fatal('lgp %s exited with status %s', self.command, exit_status)
            self.set_status(apycot.ERROR)
        os.chdir(cwd)
        return handler.status

apycot.register('checker', LgpCheckChecker)

class LgpBuildChecker(BaseChecker):
    """build debian packages with lgp"""

    id = 'lgp.build'
    command = 'build'
    options_def = {
        'lgp_build_distrib': {
            'type': 'csv',
            'help': ('comma-separated list of distributions to build against'),
        },
        'lgp_sign': {
            'help': ('whether to sign packages'),
            'default': 'no',
        },
        'lgp_suffix': {
            'help': ('append vcs revision to the package version'),
        },
    }

    def display_logs(self, build_folder):
        self.writer.info('begin scanning for log files ')
        for filename in glob(os.path.join(build_folder, '*', '*.log')):
            if os.path.isfile(filename):
                log_file = open(filename, 'r')
                self.writer.info('printing {0}: {1}'.format(filename,
                    '\n'.join(list(log_file))))

    def do_check(self, test):
        dist = self.options.get('lgp_build_distrib')
        sign = self.options.get('lgp_sign')
        suffix = self.options.get('lgp_suffix')
        build_folder = os.path.join(test.project_path(), '..')
        cwd = os.getcwd()
        os.chdir(test.project_path())
        try:
            handler = LgpLogHandler(self.writer)
            cmd = LGP.get_command(self.command)
            cmd.logger.addHandler(handler)
            args = ['-v', '-s', sign, '-r', build_folder]
            if dist:
                args += ['-d', ','.join(dist)]
            if suffix:
                revision = hglib.open('.').parents()[0].node[:12]
                args += ['--suffix', '~rev%s' % revision]
            exit_status = cmd.main_run(args, LGP.rcfile)
            self.debian_changes = [f for f in cmd.packages if f.endswith('.changes')]
            self.rpms = [f for f in cmd.packages if f.endswith('.rpm')]
            if exit_status:
                self.writer.fatal('lgp %s exited with status %s', self.command, exit_status)
                self.set_status(apycot.ERROR)
        finally:
            if handler.status is not apycot.SUCCESS:
                self.display_logs(build_folder)
            os.chdir(cwd)
        return handler.status

apycot.register('checker', LgpBuildChecker)