125:751f50b9b5fa
Anton Shestakov <av6@dwimlabs.net>, Thu, 07 Jul 2016 14:24:22 +0800
viewer: remove special case for cleanup task collapser Now that final "job finished" metadata line is not in any task, cleanup is empty and won't get the collapser naturally.

next change 139:8155ebf7d128
previous change 123:beb8f09f4bbb

incoming.py

Permissions: -rwxr-xr-x

Other formats: Feeds:
#!/usr/bin/env python
from __future__ import absolute_import
import fileinput
import logging
import os
import re
from datetime import datetime
from urlparse import urlparse
from tornado.escape import json_encode
from candolint.models import database, Project, Change, Check
rel = lambda *x: os.path.abspath(os.path.join(os.path.dirname(__file__), *x))
def parse_timestamp(value):
return datetime.strptime(value, '%Y-%m-%dT%H:%M:%S+00:00')
def parse_project_url(url):
parsed = urlparse(url)
domain = parsed.hostname
if domain is None:
domain = 'self'
parts = [part for part in parsed.path.split('/') if part]
if len(parts) > 1:
user = parts[0]
name = '/'.join(parts[1:])
else:
user = None
name = parts[0]
return domain, user, name
def match_linter_output(line):
errors = 0
warnings = 0
item = {}
m = re.match(r'^(?P<filename>.+):(?P<line_number>\d+):\d+: ', line)
if m is not None:
item['filename'] = m.group('filename')
item['line_number'] = int(m.group('line_number'))
item['link_start'] = m.start('filename')
item['link_end'] = m.end('line_number')
rest = line[m.end():]
patterns = (
# pep8-specific E9xx
# https://pep8.readthedocs.io/en/latest/intro.html#error-codes
(r'^E9\d{2}', 'error'),
(r'^[EWFCN]\d{3}', 'warning'),
(r'^\[error\]', 'error'),
(r'^\[warning\]', 'warning'),
# luacheck
(r'^\(E\d{3}\)', 'error'),
(r'^\(W\d{3}\)', 'warning'),
# jshint
(r'.* \(E\d{3}\)$', 'error'),
(r'.* \(W\d{3}\)$', 'warning'),
)
for regex, cls in patterns:
m = re.match(regex, rest)
if m is not None:
item['cls'] = cls
if cls == 'error':
errors += 1
elif cls == 'warning':
warnings += 1
break
else:
warnings += 1
item['cls'] = 'warning'
return errors, warnings, item
def insert_check(lines):
meta_prefix = '# C&O '
state = None
result = []
errors = 0
warnings = 0
url = None
rev = None
node = None
branch = None
date = None
author = None
message = None
success = True
started = None
finished = None
for line in lines:
line = line.rstrip('\r\n')
item = {'text': line}
if line.startswith(meta_prefix):
item['cls'] = 'meta'
rest = line[len(meta_prefix):]
m = re.match('^task: (\w+)$', rest)
if m is not None:
state = m.group(1)
item['cls'] = 'task'
m = re.match('^job failed', rest)
if m is not None:
success = False
item['cls'] = 'failure'
m = re.match('^job (started|finished): ([\dT:+-]+)$', rest)
if m is not None:
if m.group(1) == 'started':
started = parse_timestamp(m.group(2))
elif m.group(1) == 'finished':
finished = parse_timestamp(m.group(2))
state = None
m = re.match('^project URL: (\S+)$', rest)
if m is not None:
url = m.group(1)
m = re.match('^commit: (?:(\d+):)?(\w+)$', rest)
if m is not None:
rev = m.group(1)
node = m.group(2)
m = re.match('^commit branch: (.+)$', rest)
if m is not None:
branch = m.group(1)
m = re.match('^commit ref names:.* HEAD -> (\S+)(, |$)', rest)
if m is not None:
branch = m.group(1)
m = re.match('^commit date: (.+)$', rest)
if m is not None:
date = m.group(1)
m = re.match('^commit author: (.+)$', rest)
if m is not None:
author = m.group(1)
m = re.match('^commit message: (.+)$', rest)
if m is not None:
message = m.group(1)
elif state == 'checks':
de, dw, extra = match_linter_output(line)
errors += de
warnings += dw
item.update(extra)
if state is not None:
item['task'] = state
result.append(item)
if not url or not node or not branch:
return
domain, user, name = parse_project_url(url)
with database.transaction():
project, created = Project.manual_upsert(
url=url,
domain=domain,
user=user,
name=name)
change, created = Change.manual_upsert(
rev=rev,
node=node,
branch=branch,
date=date,
author=author,
message=message,
project=project)
Check.create(
ordinal=Check.get_next_ordinal(project),
errors=errors,
warnings=warnings,
lines=json_encode(result),
success=success,
started=started,
finished=finished,
project=project,
change=change)
def main():
database.init(rel('database.sqlite'))
database.connect()
database.create_tables([Project, Change, Check], safe=True)
logger = logging.getLogger('peewee')
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())
insert_check(list(fileinput.input()))
database.close()
if __name__ == '__main__':
main()