blob: 78d33bd1a91acaf44e2ee4612d6128c553e56c06 [file]
"""Build step class for validating XML files."""
from __future__ import absolute_import
import collections
import os
import re
import xml.etree
from helpers import git_utils
from slave import base_step
_XML_PARSE_ERROR_MSG = 'This XML file failed to parse: {}'
_XML_ERROR_POSITION_PATTERN = r'line (?P<linenum>\d+), column \d+'
class XmlCheckStep(base_step.BaseStep):
"""Build step class for validating XML files."""
def __init__(self, **kwargs):
"""Creates a XmlCheckStep instance.
Args:
**kwargs: Any additional args to pass to BaseStep.
"""
base_step.BaseStep.__init__(self, name='xml check', **kwargs)
def _parse_error_to_comment(self, err):
comment = {'message': _XML_PARSE_ERROR_MSG.format(str(err))}
match = re.search(_XML_ERROR_POSITION_PATTERN, str(err))
if match:
comment['line'] = match.group('linenum')
return comment
def run(self):
"""Attempts to parse all .xml files in the current commit.
Sets a build property "review" with the output if there are any errors.
Returns:
True iff there were no parsing errors.
"""
comments = collections.defaultdict(list)
for xml_filename in self.changed_files(file_extensions=['.xml']):
with open(os.path.join(self.directory, xml_filename)) as xml_file:
try:
xml.etree.ElementTree.parse(xml_file)
except xml.etree.ElementTree.ParseError as err:
comments[xml_filename].append(self._parse_error_to_comment(err))
if comments:
self.add_review({'comments': comments})
return False
# No Errors
return True