summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <daniel.silverstone@codethink.co.uk>2012-09-04 10:49:35 +0100
committerDaniel Silverstone <daniel.silverstone@codethink.co.uk>2012-09-07 13:34:26 +0100
commitcd00de30a0f4d2d422053692948ea9986960c43f (patch)
tree9878ddc7d13bb82321aa46adcbc04bdd5150f442
parentb53860b0aa27e5c004adc45552e7fead71de09e7 (diff)
downloadmorph-cache-server-cd00de30a0f4d2d422053692948ea9986960c43f.tar.gz
A direct-mode for git cache access
Direct-mode, when enabled, causes morph-cache-server to assume a more Trove-like structure for the repositories, rather than the morph-cache structure which it was originally written for. This means that for the workers, we can use the original code and for Trove, the direct mode.
-rwxr-xr-xmorph-cache-server5
-rw-r--r--morphcacheserver/repocache.py34
2 files changed, 30 insertions, 9 deletions
diff --git a/morph-cache-server b/morph-cache-server
index 3f72c18..bb84915 100755
--- a/morph-cache-server
+++ b/morph-cache-server
@@ -48,13 +48,16 @@ class MorphCacheServer(cliapp.Application):
'path to the artifact cache directory',
metavar='PATH',
default=defaults['artifact-dir'])
+ self.settings.boolean(['direct-mode'],
+ 'cache directories are directly managed')
def process_args(self, args):
app = Bottle()
repo_cache = RepoCache(self,
self.settings['repo-dir'],
- self.settings['bundle-dir'])
+ self.settings['bundle-dir'],
+ self.settings['direct-mode'])
@app.get('/sha1s')
def sha1():
diff --git a/morphcacheserver/repocache.py b/morphcacheserver/repocache.py
index 7061508..c226ef4 100644
--- a/morphcacheserver/repocache.py
+++ b/morphcacheserver/repocache.py
@@ -17,6 +17,7 @@
import cliapp
import os
import string
+import urlparse
class RepositoryNotFoundError(cliapp.AppException):
@@ -44,19 +45,25 @@ class UnresolvedNamedReferenceError(cliapp.AppException):
class RepoCache(object):
- def __init__(self, app, repo_cache_dir, bundle_cache_dir):
+ def __init__(self, app, repo_cache_dir, bundle_cache_dir, direct_mode):
self.app = app
self.repo_cache_dir = repo_cache_dir
self.bundle_cache_dir = bundle_cache_dir
+ self.direct_mode = direct_mode
def resolve_ref(self, repo_url, ref):
quoted_url = self._quote_url(repo_url)
repo_dir = os.path.join(self.repo_cache_dir, quoted_url)
if not os.path.exists(repo_dir):
- raise RepositoryNotFoundError(repo_url)
+ repo_dir = "%s.git" % repo_dir
+ if not os.path.exists(repo_dir):
+ raise RepositoryNotFoundError(repo_url)
try:
refs = self._show_ref(repo_dir, ref).split('\n')
- refs = [x.split() for x in refs if 'origin' in x]
+ if self.direct_mode:
+ refs = [x.split() for x in refs]
+ else:
+ refs = [x.split() for x in refs if 'origin' in x]
return refs[0][0]
except cliapp.AppException:
pass
@@ -70,6 +77,10 @@ class RepoCache(object):
def cat_file(self, repo_url, ref, filename):
quoted_url = self._quote_url(repo_url)
repo_dir = os.path.join(self.repo_cache_dir, quoted_url)
+ if not os.path.exists(repo_dir):
+ repo_dir = "%s.git" % repo_dir
+ if not os.path.exists(repo_dir):
+ raise RepositoryNotFoundError(repo_url)
if not self._is_valid_sha1(ref):
raise UnresolvedNamedReferenceError(repo_url, ref)
if not os.path.exists(repo_dir):
@@ -84,6 +95,10 @@ class RepoCache(object):
def ls_tree(self, repo_url, ref, path):
quoted_url = self._quote_url(repo_url)
repo_dir = os.path.join(self.repo_cache_dir, quoted_url)
+ if not os.path.exists(repo_dir):
+ repo_dir = "%s.git" % repo_dir
+ if not os.path.exists(repo_dir):
+ raise RepositoryNotFoundError(repo_url)
if not self._is_valid_sha1(ref):
raise UnresolvedNamedReferenceError(repo_url, ref)
if not os.path.exists(repo_dir):
@@ -108,13 +123,16 @@ class RepoCache(object):
return data
def get_bundle_filename(self, repo_url):
- quoted_url = self._quote_url(repo_url)
+ quoted_url = self._quote_url(repo_url, True)
return os.path.join(self.bundle_cache_dir, '%s.bndl' % quoted_url)
- def _quote_url(self, url):
- valid_chars = string.digits + string.letters + '%_'
- transl = lambda x: x if x in valid_chars else '_'
- return ''.join([transl(x) for x in url])
+ def _quote_url(self, url, always_indirect=False):
+ if self.direct_mode and not always_indirect:
+ return urlparse.urlparse(url)[2]
+ else:
+ valid_chars = string.digits + string.letters + '%_'
+ transl = lambda x: x if x in valid_chars else '_'
+ return ''.join([transl(x) for x in url])
def _show_ref(self, repo_dir, ref):
return self.app.runcmd(['git', 'show-ref', ref], cwd=repo_dir)