Created
January 16, 2019 22:02
-
-
Save blakesanie/71de8b83c56fb314ddb9adefd401406b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import os | |
| import logging | |
| import xml.etree.ElementTree as et | |
| from xml.etree.ElementTree import ParseError | |
| from src.validators import PathValidator | |
| from src.report import FileReport | |
| from src.report.snap_report import SnapReport | |
| from src.utils import NotEnoughFilesError, Pair | |
| _logger = logging.getLogger('codediff') | |
| class FileParser: | |
| def __init__(self, path): | |
| # TODO Ensure path as been parsed | |
| self.path = path | |
| def parse(self): | |
| with open(self.path, 'r') as f: | |
| # We pass the whole files content in for now, but we really should | |
| # fragament it. | |
| report = FileReport(self.path, f.read(), | |
| os.path.getsize(self.path)) | |
| return report | |
| def parsefiles(parsed_paths): | |
| files = {} | |
| for i, path1 in enumerate(parsed_paths): | |
| parsed_file1 = FileParser(path1).parse() | |
| for path2 in parsed_paths[i+1:]: | |
| files[Pair(path1, path2)] = Pair(parsed_file1, FileParser(path2).parse()) | |
| return files | |
| def parsesnapfiles(parsed_paths): | |
| files = { | |
| 'succeeded': {}, | |
| 'failed': set() | |
| } | |
| for i, path1 in enumerate(parsed_paths): | |
| try: | |
| parsed_file1 = SnapParser(path1).parse() | |
| for path2 in parsed_paths[i+1:]: | |
| files['succeeded'][Pair(path1, path2)] = Pair(parsed_file1, SnapParser(path2).parse()) | |
| except ParseError as e: | |
| files['failed'] |= {e.filename} | |
| return files | |
| class SnapParser(FileParser): | |
| def __init__(self, path): | |
| super(SnapParser, self).__init__(path) | |
| def parse(self): | |
| try: | |
| project = et.parse(self.path).getroot() | |
| name = project.attrib['name'] | |
| stage = project.find('stage') | |
| blocks = project.find('blocks') | |
| custom_vars = project.find('variables') | |
| return SnapReport(self.path, project=project, | |
| name=name, stage=stage, blocks=blocks, | |
| vars=custom_vars) | |
| except ParseError as e: | |
| # overwrite the filename and re-raise the error | |
| e.filename = self.path | |
| raise e | |
| class PathParser: | |
| def __init__(self, paths, validator=None): | |
| if validator and not isinstance(validator, PathValidator): | |
| raise TypeError('Path validator must be an instance of `PathValidator`') | |
| self.paths = paths | |
| self.validator = validator | |
| def parse(self): | |
| _logger.debug('========== BEGIN `%s::%s::parse` ==========', __name__, self.__class__.__name__) | |
| _logger.debug('Parsing paths %s', self.paths) | |
| paths = [] | |
| for path in self.paths: | |
| if os.path.isfile(path): | |
| _logger.debug('%s is a file', path) | |
| if self.validator: | |
| self.validator.validate_file(path) | |
| paths.append(path) | |
| elif os.path.isdir(path): | |
| _logger.debug('%s is a directory', path) | |
| path = path.rstrip('/') # Will only work on unix, use os.path.normalpath for windows | |
| file_paths = [root + '/' + x for root, _, files_list in os.walk(path) for x in files_list] | |
| if self.validator: | |
| self.validator.validate_dir(file_paths) | |
| paths += file_paths | |
| else: | |
| raise FileNotFoundError('Could not find file {}. Aborting.'.format(path)) | |
| if len(paths) < 2: | |
| raise NotEnoughFilesError('Expecting at least two xml files but found less than two.') | |
| _logger.debug('========== END `%s::%s::parse` ==========', __name__, self.__class__.__name__) | |
| return paths | |
| def __iter__(self): | |
| parsed_paths = self.parse() | |
| yield parsed_paths |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment