diff options
Diffstat (limited to 'morphlib')
-rw-r--r-- | morphlib/morphloader.py | 8 | ||||
-rw-r--r-- | morphlib/sourceresolver.py | 88 |
2 files changed, 65 insertions, 31 deletions
diff --git a/morphlib/morphloader.py b/morphlib/morphloader.py index 8289b01e..e0f0952b 100644 --- a/morphlib/morphloader.py +++ b/morphlib/morphloader.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2014 Codethink Limited +# Copyright (C) 2013-2015 Codethink Limited # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -398,13 +398,17 @@ class MorphologyLoader(object): return morphlib.morphology.Morphology(obj) - def load_from_string(self, string, filename='string'): + def load_from_string(self, string, + filename='string'): # pragma: no cover '''Load a morphology from a string. Return the Morphology object. ''' + if string is None: + return None + m = self.parse_morphology_text(string, filename) m.filename = filename self.validate(m) diff --git a/morphlib/sourceresolver.py b/morphlib/sourceresolver.py index 22e643d2..387d2e0d 100644 --- a/morphlib/sourceresolver.py +++ b/morphlib/sourceresolver.py @@ -21,6 +21,7 @@ import os import pylru import shutil import tempfile +import yaml import cliapp @@ -31,6 +32,7 @@ tree_cache_filename = 'trees.cache.pickle' buildsystem_cache_size = 10000 buildsystem_cache_filename = 'detected-chunk-buildsystems.cache.pickle' +not_supported_versions = [] class PickleCacheManager(object): # pragma: no cover '''Cache manager for PyLRU that reads and writes to Pickle files. @@ -89,6 +91,11 @@ class MorphologyNotFoundError(SourceResolverError): # pragma: no cover SourceResolverError.__init__( self, "Couldn't find morphology: %s" % filename) +class UnknownVersionError(SourceResolverError): # pragma: no cover + def __init__(self, version): + SourceResolverError.__init__( + self, "Definitions format version %s is not supported" % version) + class SourceResolver(object): '''Provides a way of resolving the set of sources for a given system. @@ -212,14 +219,16 @@ class SourceResolver(object): return absref, tree - def _get_morphology_from_definitions(self, loader, - filename): # pragma: no cover + def _get_file_contents_from_definitions(self, + filename): # pragma: no cover if os.path.exists(filename): - return loader.load_from_file(filename) + with open(filename) as f: + return f.read() else: return None - def _get_morphology_from_repo(self, loader, reponame, sha1, filename): + def _get_file_contents_from_repo(self, reponame, + sha1, filename): # pragma: no cover if self.lrc.has_repo(reponame): self.status(msg="Looking for %(reponame)s:%(filename)s in the " "local repo cache.", @@ -227,37 +236,29 @@ class SourceResolver(object): try: repo = self.lrc.get_repo(reponame) text = repo.read_file(filename, sha1) - morph = loader.load_from_string(text) except IOError: - morph = None + text = None elif self.rrc is not None: self.status(msg="Looking for %(reponame)s:%(filename)s in the " "remote repo cache.", reponame=reponame, filename=filename, chatty=True) try: text = self.rrc.cat_file(reponame, sha1, filename) - morph = loader.load_from_string(text) except morphlib.remoterepocache.CatFileError: - morph = None + text = None else: # pragma: no cover repo = self.cache_repo_locally(reponame) text = repo.read_file(filename, sha1) - morph = loader.load_from_string(text) - return morph + return text - def _get_morphology(self, reponame, sha1, filename): - '''Read the morphology at the specified location. + def _get_file_contents(self, reponame, sha1, filename): # pragma: no cover + '''Read the file at the specified location. Returns None if the file does not exist in the specified commit. ''' - key = (reponame, sha1, filename) - if key in self._resolved_morphologies: - return self._resolved_morphologies[key] - - loader = morphlib.morphloader.MorphologyLoader() - morph = None + text = None if reponame == self._definitions_repo and \ sha1 == self._definitions_absref: # pragma: no cover @@ -265,20 +266,31 @@ class SourceResolver(object): # we can quickly read definitions files from. defs_filename = os.path.join(self._definitions_checkout_dir, filename) - morph = self._get_morphology_from_definitions(loader, - defs_filename) + text = self._get_file_contents_from_definitions(defs_filename) else: - morph = self._get_morphology_from_repo(loader, reponame, sha1, - filename) + text = self._get_file_contents_from_repo(reponame, sha1, filename) - if morph is None: - return None - else: - loader.validate(morph) - loader.set_commands(morph) - loader.set_defaults(morph) + return text + + def _get_morphology(self, reponame, sha1, filename): # pragma: no cover + '''Read the morphology at the specified location. + + Returns None if the file does not exist in the specified commit. + + ''' + key = (reponame, sha1, filename) + if key in self._resolved_morphologies: + return self._resolved_morphologies[key] + + loader = morphlib.morphloader.MorphologyLoader() + + text = self._get_file_contents(reponame, sha1, filename) + morph = loader.load_from_string(text) + + if morph is not None: self._resolved_morphologies[key] = morph - return morph + + return morph def _detect_build_system(self, reponame, sha1, expected_filename): '''Attempt to detect buildsystem of the given commit. @@ -333,6 +345,22 @@ class SourceResolver(object): loader.set_defaults(morph) return morph + def _check_version_file(self,definitions_repo, + definitions_absref): # pragma: no cover + version_file = self._get_file_contents( + definitions_repo, definitions_absref, 'VERSION') + + if version_file is None: + return + + try: + version = yaml.safe_load(version_file)['version'] + except (yaml.error.YAMLError, KeyError, TypeError): + version = 0 + + if version in not_supported_versions: + raise UnknownVersionError(version) + def _process_definitions_with_children(self, system_filenames, definitions_repo, definitions_ref, @@ -342,6 +370,8 @@ class SourceResolver(object): definitions_queue = collections.deque(system_filenames) chunk_queue = set() + self._check_version_file(definitions_repo, definitions_absref) + while definitions_queue: filename = definitions_queue.popleft() |