summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2015-02-20 10:23:11 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2015-02-20 13:48:33 +0000
commitafcb1146a2ed1a09244266f4e302ee78d8625b92 (patch)
tree6c0fb65b1632b3b11c4b393efea7c3a3e9c16446
parent9cdeacaea8528c1bc090046715374882e9be0e15 (diff)
downloadmorph-afcb1146a2ed1a09244266f4e302ee78d8625b92.tar.gz
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.
-rw-r--r--morphlib/sourceresolver.py69
1 files 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: