From afcb1146a2ed1a09244266f4e302ee78d8625b92 Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Fri, 20 Feb 2015 10:23:11 +0000 Subject: sourceresolver: Always try to read chunk morph files from definitions This fixes the 'Morph ignores the chunk morph file I added to definitions' regression introduced in the recent build-graph speedups branch. The new 'detected-chunk-buildsystems' cache associates a (chunk repo, chunk ref) pair with the auto-detected build system. When calculating the build graph, if the is an auto-detected build system known already, that will be used instead of looking for a chunk morphology. There's a flaw here: if the user added or changed the chunk morphology in the definitions repo, the *chunk* ref won't necessarily have changed -- so Morph will ignore the user's changes, if it had already cached an autodetected buildsystem for that repo/ref pair. This doesn't cost much in terms of speed because we're just reading a file from disk. We can still avoid looking in the chunk repo for a chunk morph, because the chunk ref would be different if something had changed in the chunk repo. --- morphlib/sourceresolver.py | 69 +++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/morphlib/sourceresolver.py b/morphlib/sourceresolver.py index 0c2d1a0a..832266dd 100644 --- a/morphlib/sourceresolver.py +++ b/morphlib/sourceresolver.py @@ -214,29 +214,12 @@ class SourceResolver(object): return absref, tree - def _get_morphology(self, reponame, sha1, filename): - '''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] + def _get_morphology_from_definitions(self, loader, filename): + return loader.load_from_file(filename) - if reponame == self._definitions_repo and \ - sha1 == self._definitions_absref: # pragma: no cover - defs_filename = os.path.join(self._definitions_checkout_dir, - filename) - else: - defs_filename = None - - - loader = morphlib.morphloader.MorphologyLoader() - morph = None - if defs_filename and os.path.exists(defs_filename): # pragma: no cover - morph = loader.load_from_file(defs_filename) - elif self.lrc.has_repo(reponame): + def _get_morphology_from_chunk_repo(self, loader, reponame, sha1, + filename): + if self.lrc.has_repo(reponame): self.status(msg="Looking for %(reponame)s:%(filename)s in the " "local repo cache.", reponame=reponame, filename=filename, chatty=True) @@ -261,6 +244,34 @@ class SourceResolver(object): # if it had been possible. raise NotcachedError(reponame) + return morph + + def _get_morphology(self, reponame, sha1, filename, + look_in_chunk_repo=True): + '''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] + + if reponame == self._definitions_repo and \ + sha1 == self._definitions_absref: # pragma: no cover + defs_filename = os.path.join(self._definitions_checkout_dir, + filename) + else: + defs_filename = None + + + loader = morphlib.morphloader.MorphologyLoader() + morph = None + if defs_filename and os.path.exists(defs_filename): # pragma: no cover + morph = self._get_morphology_from_definitions(loader, defs_filename) + elif look_in_chunk_repo: + morph = self._get_morphology_from_chunk_repo(loader, reponame, sha1, filename) + if morph is None: return None else: @@ -378,18 +389,18 @@ class SourceResolver(object): morph_name = os.path.splitext(os.path.basename(filename))[0] - morphology = None + morphology = self._get_morphology( + *definition_key, look_in_chunk_repo=False) buildsystem = None if chunk_key in self._resolved_buildsystems: buildsystem = self._resolved_buildsystems[chunk_key] - if buildsystem is None: - # The morphologies aren't locally cached, so a morphology - # for a chunk kept in the chunk repo will be read every time. - # So, always keep your chunk morphs in your definitions repo, - # not in the chunk repo! - morphology = self._get_morphology(*definition_key) + if morphology is None and buildsystem is None: + # This is a slow operation (looking for a file in Git repo may + # potentially require cloning the whole thing). + morphology = self._get_morphology( + *definition_key, look_in_chunk_repo=True) if morphology is None: if buildsystem is None: -- cgit v1.2.1