summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2012-04-10 16:51:37 +0100
committerRichard Maw <richard.maw@codethink.co.uk>2012-04-11 13:10:27 +0100
commit48671d75ae47cd133ecf58cc476cd18ea9afd469 (patch)
treee2a59253cd2571fc1ac4d5e37be385ca91f9711b
parentbb4c7432261aafc8682ffdcb49b76e44e9079501 (diff)
downloadmorph-48671d75ae47cd133ecf58cc476cd18ea9afd469.tar.gz
localrepocache: return error description
Also change _fetch to throw its exception as since it is more pythonic to throw exceptions than return exit status, other error handling needed to be caught, so it hsa been kept consistent. This required the tests to throw an exception as well
-rw-r--r--morphlib/localrepocache.py65
-rw-r--r--morphlib/localrepocache_tests.py5
2 files changed, 46 insertions, 24 deletions
diff --git a/morphlib/localrepocache.py b/morphlib/localrepocache.py
index 1be14555..f2fdc3e9 100644
--- a/morphlib/localrepocache.py
+++ b/morphlib/localrepocache.py
@@ -35,11 +35,13 @@ urlparse.uses_fragment.extend(gitscheme)
class NoRemote(Exception):
- def __init__(self, reponame):
+ def __init__(self, reponame, errors):
self.reponame = reponame
+ self.errors = errors
def __str__(self):
- return 'Cannot find remote git repository: %s' % self.reponame
+ return '\n\t'.join(['Cannot find remote git repository: %s' %
+ self.reponame] + self.errors)
class LocalRepoCache(object):
@@ -99,19 +101,16 @@ class LocalRepoCache(object):
'''
- try:
- source_handle = urllib2.urlopen(url)
- target_handle = open(filename, 'wb')
+ source_handle = urllib2.urlopen(url)
+ target_handle = open(filename, 'wb')
+ data = source_handle.read(4096)
+ while data:
+ target_handle.write(data)
data = source_handle.read(4096)
- while data:
- target_handle.write(data)
- data = source_handle.read(4096)
- source_handle.close()
- target_handle.close()
- except urllib2.URLError:
- return False
+ source_handle.close()
+ target_handle.close()
def _mkdir(self, dirname): # pragma: no cover
'''Create a directory.
@@ -131,6 +130,15 @@ class LocalRepoCache(object):
os.remove(filename)
+ def _rmtree(self, dirname): # pragma: no cover
+ '''Remove given directory tree.
+
+ This method is meant to be overridden by unit tests.
+
+ '''
+
+ shutil.rmtree(dirname)
+
def _escape(self, url):
'''Escape a URL so it can be used as a basename in a file.'''
@@ -166,12 +174,21 @@ class LocalRepoCache(object):
escaped = self._escape(repourl)
bundle_url = urlparse.urljoin(self._bundle_base_url, escaped)
bundle_path = path + '.bundle'
- success = self._fetch(bundle_url, bundle_path)
- if success:
+ try:
+ self._fetch(bundle_url, bundle_path)
+ except urllib2.URLError, e:
+ return False, 'Unable to fetch bundle %s: %s' % (bundle_url, e)
+ try:
self._git(['clone', bundle_path, path])
- if self._exists(bundle_path):
- self._remove(bundle_path)
- return success
+ except morphlib.execute.CommandFailure, e: # pragma: no cover
+ if self._exists(path):
+ shutil.rmtree(path)
+ return False, 'Unable to extract bundle %s: %s' % (bundle_path, e)
+ finally:
+ if self._exists(bundle_path):
+ self._remove(bundle_path)
+
+ return True, None
def cache_repo(self, reponame):
'''Clone the given repo into the cache.
@@ -179,7 +196,7 @@ class LocalRepoCache(object):
If the repo is already cloned, do nothing.
'''
-
+ errors = []
if not self._exists(self._cachedir):
self._mkdir(self._cachedir)
@@ -189,18 +206,22 @@ class LocalRepoCache(object):
if self._bundle_base_url:
for repourl, path in self._base_iterate(reponame):
- if self._clone_with_bundle(repourl, path):
+ ok, error = self._clone_with_bundle(repourl, path)
+ if ok:
return
+ else:
+ errors.append(error)
for repourl, path in self._base_iterate(reponame):
try:
self._git(['clone', repourl, path])
- except morphlib.execute.CommandFailure:
- pass
+ except morphlib.execute.CommandFailure, e:
+ errors.append('Unable to clone from %s to %s: %s' %
+ (repourl, path, e))
else:
break
else:
- raise NoRemote(reponame)
+ raise NoRemote(reponame, errors)
def get_repo(self, reponame):
'''Return an object representing a cached repository.'''
diff --git a/morphlib/localrepocache_tests.py b/morphlib/localrepocache_tests.py
index 72f000f9..49dc021f 100644
--- a/morphlib/localrepocache_tests.py
+++ b/morphlib/localrepocache_tests.py
@@ -15,6 +15,7 @@
import unittest
+import urllib2
import morphlib
@@ -65,7 +66,7 @@ class LocalRepoCacheTests(unittest.TestCase):
self.removed.append(filename)
def not_found(self, url, path):
- return False
+ raise urllib2.URLError('Not found')
def fake_fetch(self, url, path):
self.fetched.append(url)
@@ -135,6 +136,6 @@ class LocalRepoCacheTests(unittest.TestCase):
self.assertFalse('/' in escaped)
def test_noremote_error_message_contains_repo_name(self):
- e = morphlib.localrepocache.NoRemote(self.repourl)
+ e = morphlib.localrepocache.NoRemote(self.repourl, [])
self.assertTrue(self.repourl in str(e))