port-compare/port_stats/tasks.py
Ivan A. Melnikov 2e6ac86991 port_stats: Introducing config
Put all the args to config to easily support
several repositories.
2018-08-10 18:39:27 +04:00

128 lines
3.6 KiB
Python

import json
import logging
import os
import sys
from collections import defaultdict
from port_stats import utils
LOG = logging.getLogger(__name__)
def _task_dirs(prefix):
yield prefix
done_archive = os.path.join(prefix, 'archive', 'done')
for filename in os.listdir(done_archive):
if filename.startswith('_'):
yield os.path.join(done_archive, filename)
def task_pathes(prefix):
for task_dir in _task_dirs(prefix):
for name in os.listdir(task_dir):
if name.isdigit():
yield os.path.join(task_dir, name)
def load_task(path):
with open(os.path.join(path, 'info.json')) as f:
data = json.load(f)
data['task_path'] = path
data['task_time'] = utils.file_time_str(path)
data.setdefault('subtasks', {})
data.setdefault('try', 0)
return data
def load_tasks(prefixes, repo=None):
if isinstance(prefixes, basestring):
prefixes = [prefixes]
LOG.info("Loading tasks from %s%s", ' '.join(prefixes),
" for " + repo if repo else "")
tasks = (load_task(path)
for prefix in prefixes
for path in task_pathes(prefix))
if repo:
tasks = (t for t in tasks if t.get('repo') == repo)
return sorted(tasks, key=lambda t: t.get('taskid'))
_FORMAT_SUBTASK = {
'srpm': lambda st: 'srpm ' + st.get('srpm'),
'delete': lambda st: 'delete ' + st.get('package'),
'repo': lambda st: '%s %s' % (st.get('dir'),
st.get('tag') or st.get('tag_name'))
}
def format_subtask(subtask, extra_info=None):
stype = subtask.get('type')
result = _FORMAT_SUBTASK.get(stype, utils.format_dict)(subtask)
if extra_info:
pkg = subtask_package(subtask)
if pkg:
result = '%s %s' % (result, extra_info(pkg))
return result
def format_task(info, extra_info=None):
head = '%(taskid)s %(state)s try=%(try)s %(owner)s' % info
depends = sorted(utils.maybe_int(x) for x in info.get('depends', []))
if depends:
head += ' depends=' + ','.join(str(x) for x in depends)
subtasks = sorted((int(k), format_subtask(s, extra_info))
for k, s in info['subtasks'].iteritems())
tail = ''.join('\n%12d %s' % item for item in subtasks)
return head + tail
def format_tasks_short(tasks, separator=','):
return separator.join('%(taskid)s=%(state)s' % t
for t in (tasks or []))
def task_packages(info):
for subtask in info['subtasks'].values():
pkg = subtask_package(subtask)
if pkg:
yield pkg
def subtask_package(subtask):
if 'pkgname' in subtask:
return subtask['pkgname']
elif 'package' in subtask:
return subtask['package']
elif 'srpm' in subtask:
return subtask['srpm'].rsplit('-', 2)[0]
elif 'dir' in subtask:
name = os.path.basename(subtask['dir'])
if name.endswith('.git'):
name = name[:-4]
return name
elif list(subtask.keys()) == ['userid']:
return None
else:
LOG.error('Failed to parse subtask %s',
utils.format_dict(subtask))
return None
def tasks_by_package(task_list):
result = defaultdict(list)
for task in task_list:
try:
for p in task_packages(task):
result[p].append(task)
except Exception as ex:
LOG.error('Failed to parse task: %s',
utils.format_dict(task), exc_info=True)
return dict((p, sorted(l, key=lambda t: utils.maybe_int(t['taskid'])))
for p, l in result.iteritems())