launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #18085
Re: [Merge] lp:~blr/turnip/api-refs into lp:turnip
Oh, and one more things ...
Diff comments:
> === modified file 'turnip/api/store.py'
> --- turnip/api/store.py 2015-02-26 21:34:02 +0000
> +++ turnip/api/store.py 2015-03-05 19:34:14 +0000
> @@ -3,29 +3,63 @@
> import os
> import shutil
>
> -import pygit2
> -
> -
> -class Store(object):
> - """Provides methods for manipulating repos on disk with pygit2."""
> -
> - @staticmethod
> - def init(repo, is_bare=True):
> - """Initialise a git repo with pygit2."""
> - if os.path.exists(repo):
> - raise Exception("Repository '%s' already exists" % repo)
> - try:
> - repo_path = pygit2.init_repository(repo, is_bare)
> - except pygit2.GitError:
> - print('Unable to create repository in {}.'.format(repo))
> - raise
> - return repo_path
> -
> - @staticmethod
> - def delete(repo):
> - """Permanently delete a git repository from repo store."""
> - try:
> - shutil.rmtree(repo)
> - except (IOError, OSError):
> - print('Unable to delete repository from {}.'.format(repo))
> - raise
> +from pygit2 import (
> + GIT_OBJ_BLOB,
> + GIT_OBJ_COMMIT,
> + GIT_OBJ_TREE,
> + GIT_OBJ_TAG,
> + init_repository,
> + Repository,
> +)
> +
> +
> +REF_TYPE_NAME = {GIT_OBJ_COMMIT: 'commit',
> + GIT_OBJ_TREE: 'tree',
> + GIT_OBJ_BLOB: 'blob',
> + GIT_OBJ_TAG: 'tag'}
> +
> +
> +def format_refs(ref, git_object):
> + return {
> + ref: {
> + "object": {'sha1': git_object.oid.hex,
> + 'type': REF_TYPE_NAME[git_object.type]}
> + }
> + }
> +
> +
> +def init_repo(repo, is_bare=True):
> + """Initialise a git repository."""
> + if os.path.exists(repo):
> + raise Exception("Repository '%s' already exists" % repo)
> + repo_path = init_repository(repo, is_bare)
> + return repo_path
> +
> +
> +def open_repo(repo_path):
> + """Open an existing git repository."""
> + repo = Repository(repo_path)
> + return repo
> +
> +
> +def delete_repo(repo):
> + """Permanently delete a git repository from repo store."""
> + shutil.rmtree(repo)
> +
> +
> +def get_refs(repo_path):
> + """Return all refs for a git repository."""
> + repo = open_repo(repo_path)
> + refs = {}
> + for ref in repo.listall_references():
> + git_object = repo.lookup_reference(ref).get_object()
This should be changed to .peel(), as you did elsewhere.
> + refs.update(format_refs(ref, git_object))
> + return refs
> +
> +
> +def get_ref(repo_path, ref):
> + """Return a specific ref for a git repository."""
> + repo = open_repo(repo_path)
> + git_object = repo.lookup_reference(ref).peel()
> + ref_obj = format_refs(ref, git_object)
> + return ref_obj
>
> === modified file 'turnip/api/tests/test_api.py'
> --- turnip/api/tests/test_api.py 2015-02-25 07:28:44 +0000
> +++ turnip/api/tests/test_api.py 2015-03-05 19:34:14 +0000
> @@ -15,6 +15,7 @@
> from webtest import TestApp
>
> from turnip import api
> +from turnip.api.tests import test_helpers
>
>
> class ApiTestCase(TestCase):
> @@ -26,9 +27,19 @@
> self.app = TestApp(api.main({}))
> self.repo_path = str(uuid.uuid1())
> self.repo_store = os.path.join(repo_store, self.repo_path)
> -
> - def test_repo_post(self):
> - resp = self.app.post('/repo', json.dumps({'repo_path': self.repo_path}))
> + self.commit = {'ref': 'refs/heads/master', 'message': 'test commit.'}
> + self.tag = {'name': 'test-tag', 'message': 'tag message'}
> +
> + def get_ref(self, ref):
> + test_helpers.init_repo(self.repo_store,
> + commits=[self.commit], tags=[self.tag])
> + resp = self.app.get('/repo/{}/{}'.format(
> + self.repo_path, ref))
> + return json.loads(resp.json_body)
> +
> + def test_repo_create(self):
> + resp = self.app.post('/repo', json.dumps(
> + {'repo_path': self.repo_path}))
> self.assertEqual(resp.status_code, 200)
>
> def test_repo_delete(self):
> @@ -37,6 +48,30 @@
> self.assertEqual(resp.status_code, 200)
> self.assertFalse(os.path.exists(self.repo_store))
>
> + def test_repo_get_refs(self):
> + """Ensure expected ref objects are returned and shas match."""
> + ref = self.commit.get('ref')
> + repo = test_helpers.init_repo(self.repo_store,
> + commits=[self.commit], tags=[self.tag])
> + resp = self.app.get('/repo/{}/refs'.format(self.repo_path))
> + body = json.loads(resp.json_body)
> + self.assertTrue(ref in body)
> + self.assertTrue('refs/tags/{}'.format(self.tag.get('name') in body))
> +
> + oid = repo.head.get_object().oid.hex # git object sha
> + resp_sha = body[ref]['object'].get('sha1')
> + self.assertEqual(oid, resp_sha)
> +
> + def test_repo_get_ref(self):
> + ref = 'refs/heads/master'
> + resp = self.get_ref(ref)
> + self.assertTrue(ref in resp)
> +
> + def test_repo_get_tag(self):
> + tag = 'refs/tags/test-tag'
> + resp = self.get_ref(tag)
> + self.assertTrue(tag in resp)
> +
>
> if __name__ == '__main__':
> unittest.main()
>
> === added file 'turnip/api/tests/test_helpers.py'
> --- turnip/api/tests/test_helpers.py 1970-01-01 00:00:00 +0000
> +++ turnip/api/tests/test_helpers.py 2015-03-05 19:34:14 +0000
> @@ -0,0 +1,39 @@
> +# Copyright 2015 Canonical Ltd. All rights reserved.
> +
> +from pygit2 import (
> + init_repository,
> + GIT_OBJ_COMMIT,
> + Signature,
> + )
> +
> +AUTHOR = Signature('Test Author', 'author@xxxxxxx')
> +COMMITTER = Signature('Test Commiter', 'committer@xxxxxxx')
> +
> +
> +def create_commits(repo, commits, parents=[]):
> + tree = repo.TreeBuilder().write()
> + for commit in commits:
> + commit = repo.create_commit(
> + commit['ref'],
> + AUTHOR, COMMITTER, commit['message'],
> + tree,
> + parents
> + )
> + return repo
> +
> +
> +def create_tags(repo, tags):
> + oid = repo.head.get_object().oid
> + for tag in tags:
> + tag = repo.create_tag(
> + tag['name'], oid, GIT_OBJ_COMMIT, COMMITTER, tag['message'])
> + return repo
> +
> +
> +def init_repo(repo_path, commits=None, tags=None):
> + repo = init_repository(repo_path, True)
> + if commits:
> + repo = create_commits(repo, commits)
> + if tags:
> + repo = create_tags(repo, tags)
> + return repo
>
> === modified file 'turnip/api/views.py'
> --- turnip/api/views.py 2015-03-04 08:39:15 +0000
> +++ turnip/api/views.py 2015-03-05 19:34:14 +0000
> @@ -1,16 +1,30 @@
> # Copyright 2015 Canonical Ltd. All rights reserved.
>
> +import json
> import os
>
> from cornice.resource import resource
> from cornice.util import extract_json_data
> +from pygit2 import GitError
> import pyramid.httpexceptions as exc
>
> from turnip.config import TurnipConfig
> -from turnip.api.store import Store
> -
> -
> -@resource(collection_path='repo', path='/repo/{name}')
> +from turnip.api import store
> +
> +
> +def repo_path(func):
> + """Decorator builds repo path from request name and repo_store."""
> + def func_wrapper(self):
> + name = self.request.matchdict['name']
> + if not name:
> + self.request.errors.add('body', 'name', 'repo name is missing')
> + return
> + self.repo = os.path.join(self.repo_store, name)
> + return func(self)
> + return func_wrapper
> +
> +
> +@resource(collection_path='/repo', path='/repo/{name}')
> class RepoAPI(object):
> """Provides HTTP API for repository actions."""
>
> @@ -28,18 +42,47 @@
> return
> repo = os.path.join(self.repo_store, repo_path)
> try:
> +<<<<<<< TREE
> Store.init(repo)
> except Exception:
> +=======
> + store.init_repo(repo, is_bare)
> + except GitError:
> +>>>>>>> MERGE-SOURCE
> return exc.HTTPConflict() # 409
>
> + @repo_path
> def delete(self):
> """Delete an existing git repository."""
> - name = self.request.matchdict['name']
> - if not name:
> - self.request.errors.add('body', 'name', 'repo name is missing')
> - return
> - repo = os.path.join(self.repo_store, name)
> - try:
> - Store.delete(repo)
> - except Exception:
> - return exc.HTTPNotFound() # 404
> + try:
> + store.delete_repo(self.repo)
> + except (IOError, OSError):
> + return exc.HTTPNotFound() # 404
> +
> +
> +@resource(collection_path='/repo/{name}/refs',
> + path='/repo/{name}/refs/{ref:.*}')
> +class RefAPI(object):
> + """Provides HTTP API for git references."""
> +
> + def __init__(self, request):
> + config = TurnipConfig()
> + self.request = request
> + self.repo_store = config.get('repo_store')
> +
> + @repo_path
> + def collection_get(self):
> + try:
> + refs = store.get_refs(self.repo)
> + except GitError:
> + return exc.HTTPNotFound() # 404
> + return json.dumps(refs)
> +
> + @repo_path
> + def get(self):
> + ref = 'refs/' + self.request.matchdict['ref']
> + try:
> + ref = store.get_ref(self.repo, ref)
> + except GitError:
> + return exc.HTTPNotFound()
> + return json.dumps(ref)
>
--
https://code.launchpad.net/~blr/turnip/api-refs/+merge/251394
Your team Launchpad code reviewers is subscribed to branch lp:turnip.
References