repocache: change cached repo dir name
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Wed, 9 Oct 2013 09:38:51 +0000 (12:38 +0300)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Mon, 14 Oct 2013 06:17:56 +0000 (09:17 +0300)
Change the cached repo directory from "<base>/<reponame>_<hash>" to
"<base>/<hash>/<reponame>". That is, add another directory level to the
cache. This change makes gbp (and gbs) see the same project directory
name as the developers in their normal workflow, making spec file
guessing work identically for developers and the source service, for
example.

NOTE! Repository cache should be manually cleaned after this commit, in
order to get rid of the stale, unused caches.

Change-Id: I2ba4000928f5a645d76f69e7b02c619d09757d67
Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
gbp_repocache/__init__.py
setup.cfg
tests/test_gbp_repocache.py

index 22a116ac28c08f1bd331b39a42c124dc7544c1af..dab22809f385ac8a15441b31570da4cfec53d250 100644 (file)
@@ -94,19 +94,25 @@ class CachedRepo(object):
         self.repo = None
         self.lock = None
 
-        self._init_cache_base()
+        # Safe repo dir name
+        urlbase, reponame = self._split_url(url)
+        subdir = hashlib.sha1(urlbase).hexdigest() # pylint: disable=E1101
+        self.repodir = os.path.join(self.basedir, subdir, reponame)
+
+        self._init_cache_dir()
         self._init_git_repo(url, bare)
 
-    def _init_cache_base(self):
+    def _init_cache_dir(self):
         """Check and initialize repository cache base directory"""
         LOGGER.debug("Using cache basedir '%s'" % self.basedir)
-        if not os.path.exists(self.basedir):
-            LOGGER.debug('Creating missing cache basedir')
+        _subdir = os.path.dirname(self.repodir)
+        if not os.path.exists(_subdir):
+            LOGGER.debug('Creating missing cache subdir %s' % _subdir)
             try:
-                os.makedirs(self.basedir)
+                os.makedirs(_subdir)
             except OSError as err:
-                raise CachedRepoError('Failed to create cache base dir: %s' %
-                                     str(err))
+                raise CachedRepoError('Failed to create cache subdir %s: %s' %
+                                      (_subdir, str(err)))
 
     def _acquire_lock(self, repodir):
         """Acquire the repository lock"""
@@ -124,15 +130,34 @@ class CachedRepo(object):
             fcntl.flock(self.lock, fcntl.LOCK_UN)
             self.lock = None
 
+    @staticmethod
+    def _split_url(url):
+        """Split URL to base and reponame
+
+        >>> CachedRepo._split_url('http://foo.com/bar')
+        ('http://foo.com', 'bar')
+        >>> CachedRepo._split_url('foo.com:bar')
+        ('foo.com', 'bar')
+        >>> CachedRepo._split_url('/foo/bar')
+        ('/foo', 'bar')
+        >>> CachedRepo._split_url('foo/')
+        ('', 'foo')
+        """
+        sanitized = url.rstrip('/')
+        split = sanitized.rsplit('/', 1)
+        # Try to get base right for ssh-style "URLs", like git@github.com:foo
+        if len(split) == 1:
+            split = sanitized.rsplit(':', 1)
+        base = split[0] if len(split) > 1 else ''
+        repo = split[-1]
+        return (base, repo)
+
     def _init_git_repo(self, url, bare):
         """Clone / update a remote git repository"""
-        # Safe repo dir name
-        reponame = url.split('/')[-1].split(':')[-1]
-        postfix = hashlib.sha1(url).hexdigest() # pylint: disable=E1101
-        reponame = reponame + '_' + postfix
-        self.repodir = os.path.join(self.basedir, reponame)
         LOGGER.debug('Caching %s in %s' % (url, self.repodir))
-
+        # Create subdir, if it doesn't exist
+        if not os.path.exists(os.path.dirname(self.repodir)):
+            os.makedirs(os.path.dirname(self.repodir))
         # Acquire repository lock
         self._acquire_lock(self.repodir)
 
index 93c5735f34b8c279433ea9a92d167d24f4c593fc..d6883e6f49388a6a3597887e79770f477f0caadc 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,3 +2,4 @@
 with-coverage=1
 cover-package=obs_service_gbp,gbp_repocache
 with-xunit=1
+with-doctest=1
index 7403bdef5aa41de812126ffaec85a8cddb2429aa..12e4c1b61d26bb1020589ba1069ddcf6a0944fb4 100644 (file)
@@ -181,14 +181,25 @@ class TestCachedRepo(UnitTestsBase):
             finally:
                 os.chmod(self.cachedir, s_rwx)
         repo = self.MockCachedRepo(self.orig_repo.path)
+        subdir = os.path.dirname(repo.repodir)
+        del repo
+
+        # Check cache subdir access error
+        os.chmod(subdir, 0)
+        with assert_raises(CachedRepoError):
+            try:
+                repo = self.MockCachedRepo(self.orig_repo.path)
+            finally:
+                os.chmod(subdir, s_rwx)
+        repo = self.MockCachedRepo(self.orig_repo.path)
         del repo
 
         # Check repodir delete error
-        os.chmod(self.cachedir, stat.S_IREAD | stat.S_IEXEC)
+        os.chmod(subdir, stat.S_IREAD | stat.S_IEXEC)
         with assert_raises(CachedRepoError):
             try:
                 # Change repo type -> tries to delete
                 repo = self.MockCachedRepo(self.orig_repo.path, bare=True)
             finally:
-                os.chmod(self.cachedir, s_rwx)
+                os.chmod(subdir, s_rwx)