Skip to content

Commit

Permalink
Replace /repos/{repo_key}/description with /repos/{repo_key}, and mak…
Browse files Browse the repository at this point in the history
…e /repos/ list same (#47)
  • Loading branch information
rajivm authored and cvrebert committed Dec 17, 2013
1 parent c3da9ea commit ada2aa8
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 32 deletions.
55 changes: 36 additions & 19 deletions restfulgit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,37 @@ def _get_commit_for_refspec(repo, branch_or_tag_or_sha):
raise NotFound("no such branch, tag, or commit SHA")


DEFAULT_GIT_DESCRIPTION = "Unnamed repository; edit this file 'description' to name the repository.\n"


def _get_repo_description(repo_key):
relative_paths = (
os.path.join(repo_key, 'description'),
os.path.join(repo_key, '.git', 'description'),
)
extant_relative_paths = (
relative_path
for relative_path in relative_paths
if os.path.isfile(safe_join(current_app.config['RESTFULGIT_REPO_BASE_PATH'], relative_path))
)
extant_relative_path = next(extant_relative_paths, None)
if extant_relative_path is None:
return None
with open(os.path.join(current_app.config['RESTFULGIT_REPO_BASE_PATH'], extant_relative_path), 'r') as content_file:
description = content_file.read()
if description == DEFAULT_GIT_DESCRIPTION:
description = None
return description


def _convert_repo(repo_key):
description = _get_repo_description(repo_key)
return {
"name": repo_key,
"description": description,
"url": url_for('.get_repo', _external=True, repo_key=repo_key)
}

def _convert_signature(sig):
return {
"name": sig.name,
Expand Down Expand Up @@ -460,26 +491,12 @@ def get_tag(repo_key, sha):
return _convert_tag(repo_key, repo, tag)


PLAIN_TEXT = 'text/plain'


@restfulgit.route('/repos/<repo_key>/description/')
@restfulgit.route('/repos/<repo_key>/')
@corsify
def get_description(repo_key):
@jsonify
def get_repo(repo_key):
_get_repo(repo_key) # check repo_key validity
relative_paths = (
os.path.join(repo_key, 'description'),
os.path.join(repo_key, '.git', 'description'),
)
extant_relative_paths = (
relative_path
for relative_path in relative_paths
if os.path.isfile(safe_join(current_app.config['RESTFULGIT_REPO_BASE_PATH'], relative_path))
)
extant_relative_path = next(extant_relative_paths, None)
if extant_relative_path is None:
return Response("", mimetype=PLAIN_TEXT)
return send_from_directory(current_app.config['RESTFULGIT_REPO_BASE_PATH'], extant_relative_path, mimetype=PLAIN_TEXT)
return _convert_repo(repo_key)


@restfulgit.route('/repos/')
Expand All @@ -495,7 +512,7 @@ def get_repo_list():
working_copies = set(name for name, full_path in subdirs if os.path.isdir(safe_join(full_path, '.git')))
repositories = list(mirrors | working_copies)
repositories.sort()
return {'repos': repositories}
return [_convert_repo(repo_key) for repo_key in repositories]


@restfulgit.route('/repos/<repo_key>/git/refs/')
Expand Down
55 changes: 42 additions & 13 deletions tests/test_restfulgit.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,19 @@ def test_list_repos(self):
resp = self.client.get('/repos/')
self.assert200(resp)
result = resp.json
self.assertIsInstance(result, dict)
self.assertEqual(result.viewkeys(), {'repos'})
repo_list = result['repos']
self.assertIsInstance(repo_list, list)
self.assertIsInstance(result, list)
repo_list = [repo['name'] for repo in result]
self.assertIn('restfulgit', repo_list)
for repo in result:
if repo['name'] == 'restfulgit':
self.assertEqual(
repo,
{
'name': 'restfulgit',
'description': None,
'url': 'http://localhost/repos/restfulgit/',
}
)


class SHAConverterTestCase(_RestfulGitTestCase):
Expand Down Expand Up @@ -688,31 +696,45 @@ def test_branch_works(self):
)


class DescriptionTestCase(_RestfulGitTestCase):
class RepositoryInfoCase(_RestfulGitTestCase):
def test_no_description_file(self):
delete_file_quietly(NORMAL_CLONE_DESCRIPTION_FILEPATH)
delete_file_quietly(GIT_MIRROR_DESCRIPTION_FILEPATH)
resp = self.client.get('/repos/restfulgit/description/')
resp = self.client.get('/repos/restfulgit/')
self.assert200(resp)
self.assertEqual(resp.data, "")
self.assertEqual(
resp.json,
{
'name': 'restfulgit',
'description': None,
'url': 'http://localhost/repos/restfulgit/',
}
)

def test_dot_dot_disallowed(self):
restfulgit.REPO_BASE = TEST_SUBDIR
resp = self.client.get('/repos/../description/')
resp = self.client.get('/repos/../')
self.assertJson404(resp)

def test_nonexistent_repo(self):
restfulgit.REPO_BASE = RESTFULGIT_REPO
resp = self.client.get('/repos/test/description/')
resp = self.client.get('/repos/test/')
self.assertJson404(resp)

def test_works_normal_clone(self):
description = "REST API for Git data\n"
with io.open(NORMAL_CLONE_DESCRIPTION_FILEPATH, mode='wt', encoding='utf-8') as description_file:
description_file.write(description)
try:
resp = self.client.get('/repos/restfulgit/description/')
self.assertEqual(resp.data, description)
resp = self.client.get('/repos/restfulgit/')
self.assertEqual(
resp.json,
{
'name': 'restfulgit',
'description': description,
'url': 'http://localhost/repos/restfulgit/',
}
)
finally:
delete_file_quietly(NORMAL_CLONE_DESCRIPTION_FILEPATH)

Expand All @@ -721,8 +743,15 @@ def test_works_git_mirror(self):
with io.open(GIT_MIRROR_DESCRIPTION_FILEPATH, mode='wt', encoding='utf-8') as description_file:
description_file.write(description)
try:
resp = self.client.get('/repos/restfulgit/description/')
self.assertEqual(resp.data, description)
resp = self.client.get('/repos/restfulgit/')
self.assertEqual(
resp.json,
{
'name': 'restfulgit',
'description': description,
'url': 'http://localhost/repos/restfulgit/',
}
)
finally:
delete_file_quietly(GIT_MIRROR_DESCRIPTION_FILEPATH)

Expand Down

0 comments on commit ada2aa8

Please sign in to comment.