Skip to content

Commit

Permalink
Adding tool for parsing build.log
Browse files Browse the repository at this point in the history
Fixes: #279
  • Loading branch information
schlupov authored and xsuchy committed Jul 17, 2019
1 parent c6fe975 commit 628124a
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 2 deletions.
8 changes: 6 additions & 2 deletions mock/mock.spec
Expand Up @@ -129,12 +129,12 @@ of the buildroot.

%prep
%setup -q
for file in py/mock.py py/mockchain.py; do
for file in py/mock.py py/mockchain.py py/mock-parse-buildlog.py; do
sed -i 1"s|#!/usr/bin/python3 |#!%{__python} |" $file
done

%build
for i in py/mock.py py/mockchain.py; do
for i in py/mock.py py/mockchain.py py/mock-parse-buildlog.py; do
perl -p -i -e 's|^__VERSION__\s*=.*|__VERSION__="%{version}"|' $i
perl -p -i -e 's|^SYSCONFDIR\s*=.*|SYSCONFDIR="%{_sysconfdir}"|' $i
perl -p -i -e 's|^PYTHONDIR\s*=.*|PYTHONDIR="%{python_sitelib}"|' $i
Expand All @@ -148,6 +148,7 @@ done
install -d %{buildroot}%{_bindir}
install -d %{buildroot}%{_libexecdir}/mock
install py/mockchain.py %{buildroot}%{_bindir}/mockchain
install py/mock-parse-buildlog.py %{buildroot}%{_bindir}/mock-parse-buildlog
install py/mock.py %{buildroot}%{_libexecdir}/mock/mock
ln -s consolehelper %{buildroot}%{_bindir}/mock
install create_default_route_in_container.sh %{buildroot}%{_libexecdir}/mock/
Expand All @@ -164,6 +165,7 @@ cp -a etc/consolehelper/mock %{buildroot}%{_sysconfdir}/security/console.apps/%{
install -d %{buildroot}%{_datadir}/bash-completion/completions/
cp -a etc/bash_completion.d/* %{buildroot}%{_datadir}/bash-completion/completions/
ln -s mock %{buildroot}%{_datadir}/bash-completion/completions/mockchain
ln -s mock %{buildroot}%{_datadir}/bash-completion/completions/mock-parse-buildlog

install -d %{buildroot}%{_sysconfdir}/pki/mock
cp -a etc/pki/* %{buildroot}%{_sysconfdir}/pki/mock/
Expand All @@ -188,12 +190,14 @@ pylint-3 py/mockbuild/ py/*.py py/mockbuild/plugins/* || :
%config(noreplace) %{_sysconfdir}/mock/site-defaults.cfg
%{_datadir}/bash-completion/completions/mock
%{_datadir}/bash-completion/completions/mockchain
%{_datadir}/bash-completion/completions/mock-parse-buildlog

%defattr(-, root, root)

# executables
%{_bindir}/mock
%{_bindir}/mockchain
%{_bindir}/mock-parse-buildlog
%{_libexecdir}/mock

# python stuff
Expand Down
95 changes: 95 additions & 0 deletions mock/py/mock-parse-buildlog.py
@@ -0,0 +1,95 @@
#!/usr/bin/python3 -tt
# -*- coding: utf-8 -*-
# vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=python:textwidth=0:

import argparse
import logging
import re

FORMAT = "%(levelname)s: %(message)s"
logging.basicConfig(format=FORMAT, level=logging.WARNING)
log = logging.getLogger()


def argumentParser():
parser = argparse.ArgumentParser(
description="Parses the build.log and return an error why build failed.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument("-p", "--path", required=True, help="Path to build.log")
arguments = parser.parse_args()
return arguments


def parseBuildLog(log_path):
"""Parses the build log.
Args:
log_path (str): Path to the RPM build log.
Returns:
tuple: The first element is the type of error that was found
in the log (missing or deleted). The second element is
a list of problematic files.
"""
try:
with open(log_path, "r") as build_log:
lines = build_log.read().splitlines()
except IOError as error:
log.error("There was an error opening %s, %s", log_path, str(error))
return

error_re = re.compile(
r"""
^
(BUILDSTDERR:)?
\s*
(
(?P<missing>File\s+not\s+found:\s*)|
(?P<unpackaged>Installed\s+\(but\s+unpackaged\)\s+file\(s\)\s+found:)
)?
(?P<path>/.*)?
$
""", re.VERBOSE,
)

error_type = None
files = set()

for line in lines:
match = error_re.match(line)
if match:
if match.group("missing"):
error_type = "deleted"
files.add(match.group("path"))
elif match.group("unpackaged"):
error_type = "missing"
elif error_type == "missing" and match.group("path"):
files.add(match.group("path"))
elif error_type and not match.group("path"):
break

return error_type, list(files)


def main(log_path):
error = parseBuildLog(log_path)
if error[0] is not None:
if error[0] == "missing":
print(
"Error type: {0}".format("Build failed because problematic files are in %buildroot but not in %files")
)
elif error[0] == "deleted":
print(
"Error type: {0}".format("Build failed because problematic files are in %files but not in %buildroot")
)
print("Problematic files: ")
for files in error[1]:
print(files)
else:
log.error("Couldn't recognize the error that caused the build failure.")


if __name__ == "__main__":
programArguments = argumentParser()
main(programArguments.path)

0 comments on commit 628124a

Please sign in to comment.