summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Coldrick <adam.coldrick@codethink.co.uk>2015-01-13 15:23:55 +0000
committerAdam Coldrick <adam.coldrick@codethink.co.uk>2015-01-15 09:03:50 +0000
commit451c7581e78205ae7295489a4f86ccade5528f9d (patch)
tree1d935099dcaa5cda35d0f53ade7d911bf310e4f7
parent38c1ce1a90b19a40540137efea044061759e4757 (diff)
downloadmorph-451c7581e78205ae7295489a4f86ccade5528f9d.tar.gz
Read files from a local clone of definitions where possiblebaserock/adamcoldrick/use-local-definitions
We normally store morphologies in definitions.git rather than in the chunk's source repository now. We currently read these using `git cat-file`, which is slow. Since our morphologies are mostly in a single repository, it will be quicker to check out all the files in one go into a temporary directory and then read them from there.
-rw-r--r--morphlib/sourceresolver.py129
1 files changed, 79 insertions, 50 deletions
diff --git a/morphlib/sourceresolver.py b/morphlib/sourceresolver.py
index 45e6937d..d129064e 100644
--- a/morphlib/sourceresolver.py
+++ b/morphlib/sourceresolver.py
@@ -19,6 +19,8 @@ import cliapp
import collections
import logging
import os
+import shutil
+import tempfile
import morphlib
@@ -75,6 +77,8 @@ class SourceResolver(object):
self._resolved_trees = {}
self._resolved_morphologies = {}
+ self._definitions_checkout_dir = None
+
def resolve_ref(self, reponame, ref):
'''Resolves commit and tree sha1s of the ref in a repo and returns it.
@@ -122,9 +126,22 @@ class SourceResolver(object):
if key in self._resolved_morphologies:
return self._resolved_morphologies[key]
+ if reponame == self._definitions_repo and \
+ sha1 == self._definitions_absref:
+ defs_filename = os.path.join(self._definitions_checkout_dir,
+ filename)
+ else:
+ defs_filename = None
+
morph_name = os.path.splitext(os.path.basename(filename))[0]
loader = morphlib.morphloader.MorphologyLoader()
- if self.lrc.has_repo(reponame):
+ if reponame == self._definitions_repo and \
+ sha1 == self._definitions_absref and \
+ os.path.exists(defs_filename):
+ self.status(msg="Reading %s from local definitions checkout"
+ % filename, chatty=True)
+ morph = loader.load_from_file(defs_filename)
+ elif self.lrc.has_repo(reponame):
self.status(msg="Looking for %s in local repo cache" % filename,
chatty=True)
try:
@@ -182,57 +199,69 @@ class SourceResolver(object):
if definitions_original_ref:
definitions_ref = definitions_original_ref
- while definitions_queue:
- filename = definitions_queue.popleft()
-
- morphology = self._get_morphology(
- definitions_repo, definitions_absref, filename)
-
- visit(definitions_repo, definitions_ref, filename,
- definitions_absref, definitions_tree, morphology)
- if morphology['kind'] == 'cluster':
- raise cliapp.AppException(
- "Cannot build a morphology of type 'cluster'.")
- elif morphology['kind'] == 'system':
- definitions_queue.extend(
- morphlib.util.sanitise_morphology_path(s['morph'])
- for s in morphology['strata'])
- elif morphology['kind'] == 'stratum':
- if morphology['build-depends']:
+ self._definitions_checkout_dir = tempfile.mkdtemp()
+
+ try:
+ self._definitions_repo = definitions_repo
+ self._definitions_absref = definitions_absref
+ definitions_cached_repo = self.lrc.get_repo(definitions_repo)
+ definitions_cached_repo.extract_commit(
+ definitions_absref, self._definitions_checkout_dir)
+
+ while definitions_queue:
+ filename = definitions_queue.popleft()
+
+ morphology = self._get_morphology(
+ definitions_repo, definitions_absref, filename)
+
+ visit(definitions_repo, definitions_ref, filename,
+ definitions_absref, definitions_tree, morphology)
+ if morphology['kind'] == 'cluster':
+ raise cliapp.AppException(
+ "Cannot build a morphology of type 'cluster'.")
+ elif morphology['kind'] == 'system':
definitions_queue.extend(
morphlib.util.sanitise_morphology_path(s['morph'])
- for s in morphology['build-depends'])
- for c in morphology['chunks']:
- if 'morph' not in c:
- path = morphlib.util.sanitise_morphology_path(
- c.get('morph', c['name']))
- chunk_in_source_repo_queue.append(
- (c['repo'], c['ref'], path))
- continue
- chunk_in_definitions_repo_queue.append(
- (c['repo'], c['ref'], c['morph']))
-
- for repo, ref, filename in chunk_in_definitions_repo_queue:
- if (repo, ref) not in resolved_trees:
- commit_sha1, tree_sha1 = self.resolve_ref(repo, ref)
- resolved_commits[repo, ref] = commit_sha1
- resolved_trees[repo, commit_sha1] = tree_sha1
- absref = resolved_commits[repo, ref]
- tree = resolved_trees[repo, absref]
- key = (definitions_repo, definitions_absref, filename)
- morphology = self._get_morphology(*key)
- visit(repo, ref, filename, absref, tree, morphology)
-
- for repo, ref, filename in chunk_in_source_repo_queue:
- if (repo, ref) not in resolved_trees:
- commit_sha1, tree_sha1 = self.resolve_ref(repo, ref)
- resolved_commits[repo, ref] = commit_sha1
- resolved_trees[repo, commit_sha1] = tree_sha1
- absref = resolved_commits[repo, ref]
- tree = resolved_trees[repo, absref]
- key = (repo, absref, filename)
- morphology = self._get_morphology(*key)
- visit(repo, ref, filename, absref, tree, morphology)
+ for s in morphology['strata'])
+ elif morphology['kind'] == 'stratum':
+ if morphology['build-depends']:
+ definitions_queue.extend(
+ morphlib.util.sanitise_morphology_path(s['morph'])
+ for s in morphology['build-depends'])
+ for c in morphology['chunks']:
+ if 'morph' not in c:
+ path = morphlib.util.sanitise_morphology_path(
+ c.get('morph', c['name']))
+ chunk_in_source_repo_queue.append(
+ (c['repo'], c['ref'], path))
+ continue
+ chunk_in_definitions_repo_queue.append(
+ (c['repo'], c['ref'], c['morph']))
+
+ for repo, ref, filename in chunk_in_definitions_repo_queue:
+ if (repo, ref) not in resolved_trees:
+ commit_sha1, tree_sha1 = self.resolve_ref(repo, ref)
+ resolved_commits[repo, ref] = commit_sha1
+ resolved_trees[repo, commit_sha1] = tree_sha1
+ absref = resolved_commits[repo, ref]
+ tree = resolved_trees[repo, absref]
+ key = (definitions_repo, definitions_absref, filename)
+ morphology = self._get_morphology(*key)
+ visit(repo, ref, filename, absref, tree, morphology)
+
+ for repo, ref, filename in chunk_in_source_repo_queue:
+ if (repo, ref) not in resolved_trees:
+ commit_sha1, tree_sha1 = self.resolve_ref(repo, ref)
+ resolved_commits[repo, ref] = commit_sha1
+ resolved_trees[repo, commit_sha1] = tree_sha1
+ absref = resolved_commits[repo, ref]
+ tree = resolved_trees[repo, absref]
+ key = (repo, absref, filename)
+ morphology = self._get_morphology(*key)
+ visit(repo, ref, filename, absref, tree, morphology)
+ finally:
+ shutil.rmtree(self._definitions_checkout_dir)
+ self._definitions_checkout_dir = None
def create_source_pool(lrc, rrc, repo, ref, filename,