launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #18318
[Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
Bayard 'kit' Randel has proposed merging lp:~blr/turnip/api-init-with-alternates into lp:turnip.
Commit message:
Add support for repo init with alternates.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~blr/turnip/api-init-with-alternates/+merge/256715
A list of repo_alternate_paths can be posted to /repo/{name} to set object alternates.
This MP also adds initial unit tests for the api store.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~blr/turnip/api-init-with-alternates into lp:turnip.
=== modified file 'turnip/api/store.py'
--- turnip/api/store.py 2015-04-16 21:47:08 +0000
+++ turnip/api/store.py 2015-04-17 21:06:50 +0000
@@ -63,6 +63,10 @@
}
+def is_bare(repo_path):
+ return not os.path.exists(os.path.join(repo_path, '.git'))
+
+
def is_valid_new_path(path):
"""Verify repo path is new, or raise Exception."""
if os.path.exists(path):
@@ -70,7 +74,25 @@
return True
-def init_repo(repo_path, clone_from=None, is_bare=True):
+def alternates_path(repo_path):
+ """Git object alternates path.
+ See http://git-scm.com/docs/gitrepository-layout
+ """
+ return os.path.join(repo_path, 'objects', 'info', 'alternates')
+
+
+def write_alternates(repo_path, alternate_repo_paths):
+ with open(alternates_path(repo_path), "w") as f:
+ for path in alternate_repo_paths:
+ if is_bare(path):
+ objects_path = os.path.join(path, 'objects')
+ else:
+ objects_path = os.path.join(path, '.git', 'objects')
+ f.write("{}\n".format(objects_path))
+
+
+def init_repo(repo_path, clone_from=None, alternate_repo_paths=None,
+ is_bare=True):
"""Initialise a new git repository or clone from existing."""
assert is_valid_new_path(repo_path)
if clone_from:
@@ -79,6 +101,8 @@
repo = clone_repository(clone_from_url, repo_path, is_bare)
else:
repo = init_repository(repo_path, is_bare)
+ if alternate_repo_paths:
+ write_alternates(repo_path, alternate_repo_paths)
return repo.path
=== modified file 'turnip/api/tests/test_api.py'
--- turnip/api/tests/test_api.py 2015-04-16 21:47:08 +0000
+++ turnip/api/tests/test_api.py 2015-04-17 21:06:50 +0000
@@ -72,6 +72,19 @@
self.assertEqual(200, resp.status_code)
self.assertIn(new_repo_path, resp.json['repo_url'])
+ def test_repo_init_with_alternate(self):
+ """Repo can be initialised with alternate."""
+ factory = RepoFactory(self.repo_store)
+ commit_oid = factory.add_commit('foo', 'foobar.txt')
+ new_repo_path = uuid.uuid4().hex
+ json = {'repo_path': new_repo_path,
+ 'alternate_repo_paths': [self.repo_store]}
+ resp = self.app.post_json('/repo', json)
+ self.assertEqual(200, resp.status_code)
+ resp_commit = self.app.get('/repo/{}/commits/{}'.format(
+ new_repo_path, commit_oid))
+ self.assertEqual(200, resp_commit.status_code)
+
def test_repo_delete(self):
self.app.post_json('/repo', {'repo_path': self.repo_path})
resp = self.app.delete('/repo/{}'.format(self.repo_path))
=== added file 'turnip/api/tests/test_store.py'
--- turnip/api/tests/test_store.py 1970-01-01 00:00:00 +0000
+++ turnip/api/tests/test_store.py 2015-04-17 21:06:50 +0000
@@ -0,0 +1,57 @@
+# Copyright 2015 Canonical Ltd. All rights reserved.
+# -*- coding: utf-8 -*-
+from __future__ import print_function
+
+import os
+import unittest
+import uuid
+
+from fixtures import (
+ EnvironmentVariable,
+ TempDir,
+ )
+from testtools import TestCase
+
+from turnip.api.store import (
+ alternates_path,
+ init_repo
+ )
+from turnip.api.tests.test_helpers import (
+ open_repo,
+ RepoFactory,
+ )
+
+
+class StoreTestCase(TestCase):
+
+ def setUp(self):
+ super(StoreTestCase, self).setUp()
+ self.repo_store = self.useFixture(TempDir()).path
+ self.useFixture(EnvironmentVariable("REPO_STORE", self.repo_store))
+ self.repo_path = os.path.join(self.repo_store, uuid.uuid1().hex)
+
+ def test_repo_with_alternates(self):
+ """Ensure objects path is defined correctly in repo alternates."""
+ factory = RepoFactory(self.repo_path)
+ new_repo_path = os.path.join(self.repo_store, uuid.uuid1().hex)
+ repo_path_with_alt = init_repo(
+ new_repo_path, alternate_repo_paths=[factory.repo.path])
+ objects_path = '{}\n'.format(
+ os.path.join(factory.repo.path, 'objects'))
+ with open(alternates_path(repo_path_with_alt), 'r') as alts:
+ alts_content = alts.read()
+ self.assertEquals(objects_path, alts_content)
+
+ def test_repo_alternates_objects_shared(self):
+ """Ensure objects are shared from alternate repo."""
+ factory = RepoFactory(self.repo_path)
+ commit_oid = factory.add_commit('foo', 'foobar.txt')
+ new_repo_path = os.path.join(self.repo_store, uuid.uuid4().hex)
+ repo_path_with_alt = init_repo(
+ new_repo_path, alternate_repo_paths=[factory.repo.path])
+ repo_with_alt = open_repo(repo_path_with_alt)
+ self.assertEqual(commit_oid.hex, repo_with_alt.get(commit_oid).hex)
+
+
+if __name__ == '__main__':
+ unittest.main()
=== modified file 'turnip/api/views.py'
--- turnip/api/views.py 2015-04-16 21:47:08 +0000
+++ turnip/api/views.py 2015-04-17 21:06:50 +0000
@@ -55,6 +55,8 @@
"""Initialise a new git repository, or clone from an existing repo."""
repo_path = extract_json_data(self.request).get('repo_path')
clone_path = extract_json_data(self.request).get('clone_from')
+ alternate_repo_paths = extract_json_data(self.request).get(
+ 'alternate_repo_paths')
if not repo_path:
self.request.errors.add('body', 'repo_path',
@@ -71,7 +73,8 @@
repo_clone = None
try:
- new_repo_path = store.init_repo(repo, repo_clone)
+ new_repo_path = store.init_repo(
+ repo, repo_clone, alternate_repo_paths=alternate_repo_paths)
repo_name = os.path.basename(os.path.normpath(new_repo_path))
return {'repo_url': '/'.join([self.request.url, repo_name])}
except GitError:
Follow ups
-
[Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
From: noreply, 2015-04-29
-
Re: [Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
From: Colin Watson, 2015-04-29
-
Re: [Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
From: William Grant, 2015-04-29
-
Re: [Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
From: William Grant, 2015-04-28
-
Re: [Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
From: Bayard 'kit' Randel, 2015-04-27
-
Re: [Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
From: Colin Watson, 2015-04-24
-
[Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
From: Bayard 'kit' Randel, 2015-04-22
-
[Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
From: Bayard 'kit' Randel, 2015-04-22
-
Re: [Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
From: William Grant, 2015-04-22
-
Re: [Merge] lp:~blr/turnip/api-init-with-alternates into lp:turnip
From: William Grant, 2015-04-17