summaryrefslogtreecommitdiff
path: root/morphlib/repocache.py
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2016-03-03 14:41:15 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2016-03-14 17:50:56 +0000
commit23c021346571c24fa26eb348f573bab72fa257d9 (patch)
treefbc21c1e9c1804a56758e218566fb9497d29fc26 /morphlib/repocache.py
parent953a39140cf909f0130d76be587483b820dcd784 (diff)
downloadmorph-23c021346571c24fa26eb348f573bab72fa257d9.tar.gz
Almost complete the unification
Change-Id: Ifc29f9cd22f2d8cc609ee178bb22a4580386431c
Diffstat (limited to 'morphlib/repocache.py')
-rw-r--r--morphlib/repocache.py67
1 files changed, 40 insertions, 27 deletions
diff --git a/morphlib/repocache.py b/morphlib/repocache.py
index 86002f3b..58e05129 100644
--- a/morphlib/repocache.py
+++ b/morphlib/repocache.py
@@ -128,19 +128,25 @@ class RepoCache(object):
git_resolve_cache_url parameter enables this feature. Baserock 'Trove'
systems run 'morph-cache-server' by default.
+ The 'custom_fs' parameter takes a PyFilesystem instance, which you can use
+ to override where 'cachedir' is stored. This should probably only be used
+ for testing.
+
'''
def __init__(self, cachedir, resolver, tarball_base_url=None,
git_resolve_cache_url=None,
update_gits=True,
runcmd_cb=cliapp.runcmd, status_cb=lambda **kwargs: None,
- verbose=False, debug=False):
- morphlib.util.ensure_directory_exists(cachedir)
+ verbose=False, debug=False,
+ custom_fs=None):
+ self.fs = custom_fs or fs.osfs.OSFS('/')
+
+ self.fs.makedir(cachedir, recursive=True, allow_recreate=True)
- self.fs = fs.osfs.OSFS('/')
self.cachedir = cachedir
self._resolver = resolver
if tarball_base_url and not tarball_base_url.endswith('/'):
- tarball_base_url += '/' # pragma: no cover
+ tarball_base_url += '/'
self._tarball_base_url = tarball_base_url
self._cached_repo_objects = {}
@@ -152,7 +158,7 @@ class RepoCache(object):
self.verbose = verbose
self.debug = debug
- if git_resolve_cache_url:
+ if git_resolve_cache_url: # pragma: no cover
self.remote_cache = RemoteRepoCache(git_resolve_cache_url,
resolver)
else:
@@ -197,7 +203,7 @@ class RepoCache(object):
This method is meant to be overridden by unit tests.
'''
- return tempfile.mkdtemp(dir=dirname)
+ return tempfile.mkdtemp(dir=self.fs.getsyspath(dirname))
def _escape(self, url):
'''Escape a URL so it can be used as a basename in a file.'''
@@ -231,7 +237,7 @@ class RepoCache(object):
self._git(['config', 'remote.origin.mirror', 'true'], cwd=path)
self._git(['config', 'remote.origin.fetch', '+refs/*:refs/*'],
cwd=path)
- except BaseException as e: # pragma: no cover
+ except BaseException as e:
if self.fs.exists(path):
self.fs.removedir(path, force=True)
return False, 'Unable to extract tarball %s: %s' % (
@@ -268,7 +274,7 @@ class RepoCache(object):
errors.append('Unable to clone from %s to %s: %s' %
(repourl, target, e))
if self.fs.exists(target):
- self.fs.removedir(target, recursive=True, force=True)
+ self.fs.removedir(target, force=True)
raise NoRemote(reponame, errors)
self.fs.rename(target, path)
@@ -303,7 +309,7 @@ class RepoCache(object):
raise UpdateError(self)
def get_updated_repo(self, repo_name,
- ref=None, refs=None): # pragma: no cover
+ ref=None, refs=None):
'''Return object representing cached repository.
If all the specified refs in 'ref' or 'refs' point to SHA1s that are
@@ -322,13 +328,15 @@ class RepoCache(object):
if ref is not None and refs is None:
refs = (ref,)
+ else:
+ refs = list(refs)
if self.has_repo(repo_name):
repo = self._get_repo(repo_name)
if refs:
required_refs = set(refs)
missing_refs = set()
- for required_ref in required_refs:
+ for required_ref in required_refs: # pragma: no cover
if morphlib.git.is_valid_sha1(required_ref):
try:
repo.resolve_ref_to_commit(required_ref)
@@ -337,7 +345,7 @@ class RepoCache(object):
pass
missing_refs.add(required_ref)
- if not missing_refs:
+ if not missing_refs: # pragma: no cover
self.status_cb(
msg='Not updating git repository %(repo_name)s '
'because it already contains %(sha1s)s',
@@ -345,12 +353,17 @@ class RepoCache(object):
sha1s=_word_join_list(tuple(required_refs)))
return repo
- self.status_cb(msg='Updating %(repo_name)s', repo_name=repo_name)
+ if ref:
+ ref_str = 'ref %s' % ref
+ else:
+ ref_str = '%i refs' % len(refs)
+ self.status_cb(msg='Updating %(repo_name)s for %(ref_str)s',
+ repo_name=repo_name, ref_str=ref_str)
self._update_repo(repo)
return repo
else:
self.status_cb(msg='Cloning %(repo_name)s', repo_name=repo_name)
- return self._cache_repo(repo_name)
+ return self._get_repo(repo_name)
def ensure_submodules(self, toplevel_repo,
toplevel_ref): # pragma: no cover
@@ -378,7 +391,7 @@ class RepoCache(object):
if submod not in done:
subs_to_process.append(submod)
- def resolve_ref_to_commit_and_tree(self, repo_name, ref):
+ def resolve_ref_to_commit_and_tree(self, repo_name, ref): # pragma: no cover
absref = None
tree = None
@@ -400,38 +413,38 @@ class RepoCache(object):
if absref is None:
# As a last resort, clone the repo to resolve the ref.
- repo = self.get_updated_repo(reponame, ref)
+ repo = self.get_updated_repo(repo_name, ref)
absref = repo.resolve_ref_to_commit(ref)
tree = repo.resolve_ref_to_tree(absref)
return absref, ref
-class ResolveRefError(cliapp.AppException):
+class RemoteResolveRefError(cliapp.AppException):
def __init__(self, repo_name, ref):
cliapp.AppException.__init__(
- self, 'Failed to resolve ref %s for repo %s' %
+ self, 'Failed to resolve ref %s for repo %s from remote cache' %
(ref, repo_name))
-class CatFileError(cliapp.AppException):
+class RemoteCatFileError(cliapp.AppException): # pragma: no cover
def __init__(self, repo_name, ref, filename):
cliapp.AppException.__init__(
- self, 'Failed to cat file %s in ref %s of repo %s' %
- (filename, ref, repo_name))
+ self, 'Failed to cat file %s in ref %s of repo %s, from remote '
+ 'cache' % (filename, ref, repo_name))
-class LsTreeError(cliapp.AppException):
+class RemoteLsTreeError(cliapp.AppException): # pragma: no cover
def __init__(self, repo_name, ref):
cliapp.AppException.__init__(
- self, 'Failed to list tree in ref %s of repo %s' %
- (ref, repo_name))
+ self, 'Failed to list tree in ref %s of repo %s, from remote'
+ 'cache' % (ref, repo_name))
-class RemoteRepoCache(object):
+class RemoteRepoCache(object): # pragma: no cover
def __init__(self, server_url, resolver):
self.server_url = server_url
@@ -443,7 +456,7 @@ class RemoteRepoCache(object):
return self._resolve_ref_for_repo_url(repo_url, ref)
except BaseException as e:
logging.error('Caught exception: %s' % str(e))
- raise ResolveRefError(repo_name, ref)
+ raise RemoteResolveRefError(repo_name, ref)
def cat_file(self, repo_name, ref, filename):
repo_url = self._resolver.pull_url(repo_name)
@@ -452,7 +465,7 @@ class RemoteRepoCache(object):
except urllib2.HTTPError as e:
logging.error('Caught exception: %s' % str(e))
if e.code == 404:
- raise CatFileError(repo_name, ref, filename)
+ raise RemoteCatFileError(repo_name, ref, filename)
raise # pragma: no cover
def ls_tree(self, repo_name, ref):
@@ -462,7 +475,7 @@ class RemoteRepoCache(object):
return info['tree'].keys()
except BaseException as e:
logging.error('Caught exception: %s' % str(e))
- raise LsTreeError(repo_name, ref)
+ raise RemoteLsTreeError(repo_name, ref)
def _resolve_ref_for_repo_url(self, repo_url, ref): # pragma: no cover
data = self._make_request(