Anton Shestakov <av6@dwimlabs.net>, Sat, 02 Jul 2016 13:10:27 +0800
incoming: un-anchor "job failed" regex
Allows catching lines from bad_exit() (ed7f35f).
checker.py
Permissions: -rwxr-xr-x
from __future__ import print_function from argparse import ArgumentParser, FileType from datetime import datetime from shutil import rmtree from subprocess import check_call, check_output, CalledProcessError from tempfile import mkdtemp rel = lambda *x: os.path.abspath(os.path.join(os.path.dirname(__file__), *x)) def run_ignore_codes(fn, args, codes): except CalledProcessError as e: if e.returncode not in codes: def run(args, silent=False, get_output=False, ignore_codes=None): print('$ ' + ' '.join(args)) result = run_ignore_codes(fn, args, ignore_codes) print('# C&O error: {}'.format(e)) print('# C&O job failed') return datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S+00:00') def read_linter_config(name, path=rel('linters')): fd = open(os.path.join(path, '{}.yml'.format(name))) print("# C&O couldn't load linter config: {}".format(e)) return yaml.safe_load(fd) print("# C&O couldn't parse linter config: {}".format(e)) print('# C&O job started: {}'.format(now())) tmp = mkdtemp(prefix='candolint.') print('# C&O task: clone') print('# C&O project URL: {}'.format(config['url'])) if ok and not run(['hg', 'clone', config['url'], source]): print('$ cd {}'.format(source)) if ok and not run(['hg', 'sum']): template = (r'# C&O commit: {rev}:{node} {branch}\n' r'# C&O commit date: {date|isodatesec}\n' r'# C&O commit author: {author|person}\n' r'# C&O commit message: {desc|firstline}\n') if not run(['hg', 'log', '-r', '.', '-T', template], silent=True): print('# C&O task: setup') for linter in config['linters']: if name in linter_config: lc = read_linter_config(name) if lc is None or 'exec' not in lc: for item in lc.get('setup', []): if 'version' in lc and not run(lc['exec'] + lc['version']): print('# C&O task: checks') for linter in config['linters']: if 'name' not in linter or 'include' not in linter: if linter['name'] not in linter_config: for pat in linter['include']: for pat in linter.get('exclude', []): files = run(cmd, silent=True, get_output=True, ignore_codes=(1,)) lc = linter_config[linter['name']] for f in files.splitlines(): flags = lc.get('flags', []) + linter.get('flags', []) pf = lc.get('post_flags', []) + linter.get('post_flags', []) codes = lc.get('codes', (1,)) if not run(cmd + flags + [f] + pf, ignore_codes=codes): print('# C&O task: cleanup') print('# C&O job finished: {}'.format(now())) print('# C&O job failed (exception not caught)') print('# C&O job finished: {}'.format(now())) parser = ArgumentParser() parser.add_argument('config', help='configuration file (YAML)', type=FileType('r')) args = parser.parse_args() config = yaml.safe_load(args.config) if __name__ == '__main__':