repo_checker: provide optional parsing of install check output and mapping to package.
This commit is contained in:
parent
4f64386366
commit
e1bf4522af
@ -3,12 +3,14 @@
|
||||
from collections import namedtuple
|
||||
import os
|
||||
import pipes
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from osclib.core import binary_list
|
||||
from osclib.core import depends_on
|
||||
from osclib.core import package_binary_list
|
||||
from osclib.core import request_staged
|
||||
from osclib.core import target_archs
|
||||
from osclib.cycle import CycleDetector
|
||||
@ -18,6 +20,8 @@ import ReviewBot
|
||||
|
||||
SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__))
|
||||
CheckResult = namedtuple('CheckResult', ('success', 'comment'))
|
||||
INSTALL_REGEX = r"^(?:can't install (.*?)|found conflict of (.*?) with (.*?)):$"
|
||||
InstallSection = namedtuple('InstallSection', ('binaries', 'text'))
|
||||
|
||||
class RepoChecker(ReviewBot.ReviewBot):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -59,6 +63,9 @@ class RepoChecker(ReviewBot.ReviewBot):
|
||||
self.group = None
|
||||
self.mirrored = set()
|
||||
|
||||
# Stores parsed install_check() results grouped by package.
|
||||
self.package_results = {}
|
||||
|
||||
# Look for requests of interest and group by staging.
|
||||
for request in self.requests:
|
||||
# Only interesting if request is staged.
|
||||
@ -208,7 +215,7 @@ class RepoChecker(ReviewBot.ReviewBot):
|
||||
whitelist.update(self.staging_config[project].get(key, '').split(' '))
|
||||
return whitelist
|
||||
|
||||
def install_check(self, directory_project, directory_group, arch, ignore, whitelist):
|
||||
def install_check(self, directory_project, directory_group, arch, ignore, whitelist, parse=False):
|
||||
self.logger.info('install check: start')
|
||||
|
||||
with tempfile.NamedTemporaryFile() as ignore_file:
|
||||
@ -233,6 +240,10 @@ class RepoChecker(ReviewBot.ReviewBot):
|
||||
if p.returncode == 126:
|
||||
self.logger.warn('mirror cache reset due to corruption')
|
||||
self.mirrored = set()
|
||||
elif parse:
|
||||
# Parse output for later consumption for posting comments.
|
||||
sections = self.install_check_parse(stdout)
|
||||
self.install_check_sections_group(parse, arch, sections)
|
||||
|
||||
# Format output as markdown comment.
|
||||
code = '```\n'
|
||||
@ -251,6 +262,42 @@ class RepoChecker(ReviewBot.ReviewBot):
|
||||
self.logger.info('install check: passed')
|
||||
return CheckResult(True, None)
|
||||
|
||||
def install_check_sections_group(self, project, arch, sections):
|
||||
_, binary_map = package_binary_list(self.apiurl, project, 'standard', arch)
|
||||
|
||||
for section in sections:
|
||||
# If switch to creating bugs likely makes sense to join packages to
|
||||
# form grouping key and create shared bugs for conflicts.
|
||||
packages = set([binary_map[b] for b in section.binaries])
|
||||
for package in packages:
|
||||
self.package_results.setdefault(package, [])
|
||||
self.package_results[package].append(section)
|
||||
|
||||
def install_check_parse(self, output):
|
||||
section = None
|
||||
text = None
|
||||
|
||||
# Loop over lines and parse into chunks assigned to binaries.
|
||||
for line in output.splitlines(True):
|
||||
if line.startswith(' '):
|
||||
if section:
|
||||
text += line
|
||||
else:
|
||||
if section:
|
||||
yield InstallSection(section, text)
|
||||
|
||||
match = re.match(INSTALL_REGEX, line)
|
||||
if match:
|
||||
# Remove empty groups since regex matches different patterns.
|
||||
binaries = [b for b in match.groups() if b is not None]
|
||||
section = binaries
|
||||
text = line
|
||||
else:
|
||||
section = None
|
||||
|
||||
if section:
|
||||
yield InstallSection(section, text)
|
||||
|
||||
def cycle_check(self, project, group, arch):
|
||||
if self.skip_cycle:
|
||||
self.logger.info('cycle check: skip due to --skip-cycle')
|
||||
|
Loading…
x
Reference in New Issue
Block a user