api: get_repos allows now to filter by root locations, and optionally traverse the returned data.
Fixes #5146
This commit is contained in:
parent
707e498026
commit
340d1b02d9
3 changed files with 117 additions and 5 deletions
|
|
@ -22,7 +22,8 @@
|
|||
import pytest
|
||||
|
||||
from rhodecode.model.repo import RepoModel
|
||||
from rhodecode.api.tests.utils import build_data, api_call, assert_ok, jsonify
|
||||
from rhodecode.api.tests.utils import (
|
||||
build_data, api_call, assert_ok, assert_error, jsonify)
|
||||
from rhodecode.model.db import User
|
||||
|
||||
|
||||
|
|
@ -40,6 +41,76 @@ class TestGetRepos(object):
|
|||
expected = ret
|
||||
assert_ok(id_, expected, given=response.body)
|
||||
|
||||
def test_api_get_repos_only_toplevel(self, user_util):
|
||||
repo_group = user_util.create_repo_group(auto_cleanup=True)
|
||||
user_util.create_repo(parent=repo_group)
|
||||
|
||||
id_, params = build_data(self.apikey, 'get_repos', traverse=0)
|
||||
response = api_call(self.app, params)
|
||||
|
||||
result = []
|
||||
for repo in RepoModel().get_repos_for_root(root=None):
|
||||
result.append(repo.get_api_data(include_secrets=True))
|
||||
expected = jsonify(result)
|
||||
|
||||
assert_ok(id_, expected, given=response.body)
|
||||
|
||||
def test_api_get_repos_with_wrong_root(self):
|
||||
id_, params = build_data(self.apikey, 'get_repos', root='abracadabra')
|
||||
response = api_call(self.app, params)
|
||||
|
||||
expected = 'Root repository group `abracadabra` does not exist'
|
||||
assert_error(id_, expected, given=response.body)
|
||||
|
||||
def test_api_get_repos_with_root(self, user_util):
|
||||
repo_group = user_util.create_repo_group(auto_cleanup=True)
|
||||
repo_group_name = repo_group.group_name
|
||||
|
||||
user_util.create_repo(parent=repo_group)
|
||||
user_util.create_repo(parent=repo_group)
|
||||
|
||||
# nested, should not show up
|
||||
user_util._test_name = '{}/'.format(repo_group_name)
|
||||
sub_repo_group = user_util.create_repo_group(auto_cleanup=True)
|
||||
user_util.create_repo(parent=sub_repo_group)
|
||||
|
||||
id_, params = build_data(self.apikey, 'get_repos',
|
||||
root=repo_group_name, traverse=0)
|
||||
response = api_call(self.app, params)
|
||||
|
||||
result = []
|
||||
for repo in RepoModel().get_repos_for_root(repo_group):
|
||||
result.append(repo.get_api_data(include_secrets=True))
|
||||
|
||||
assert len(result) == 2
|
||||
expected = jsonify(result)
|
||||
assert_ok(id_, expected, given=response.body)
|
||||
|
||||
def test_api_get_repos_with_root_and_traverse(self, user_util):
|
||||
repo_group = user_util.create_repo_group(auto_cleanup=True)
|
||||
repo_group_name = repo_group.group_name
|
||||
|
||||
user_util.create_repo(parent=repo_group)
|
||||
user_util.create_repo(parent=repo_group)
|
||||
|
||||
# nested, should not show up
|
||||
user_util._test_name = '{}/'.format(repo_group_name)
|
||||
sub_repo_group = user_util.create_repo_group(auto_cleanup=True)
|
||||
user_util.create_repo(parent=sub_repo_group)
|
||||
|
||||
id_, params = build_data(self.apikey, 'get_repos',
|
||||
root=repo_group_name, traverse=1)
|
||||
response = api_call(self.app, params)
|
||||
|
||||
result = []
|
||||
for repo in RepoModel().get_repos_for_root(
|
||||
repo_group_name, traverse=True):
|
||||
result.append(repo.get_api_data(include_secrets=True))
|
||||
|
||||
assert len(result) == 3
|
||||
expected = jsonify(result)
|
||||
assert_ok(id_, expected, given=response.body)
|
||||
|
||||
def test_api_get_repos_non_admin(self):
|
||||
id_, params = build_data(self.apikey_regular, 'get_repos')
|
||||
response = api_call(self.app, params)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ from rhodecode.lib.ext_json import json
|
|||
from rhodecode.model.changeset_status import ChangesetStatusModel
|
||||
from rhodecode.model.comment import ChangesetCommentsModel
|
||||
from rhodecode.model.db import (
|
||||
Session, ChangesetStatus, RepositoryField, Repository)
|
||||
Session, ChangesetStatus, RepositoryField, Repository, RepoGroup)
|
||||
from rhodecode.model.repo import RepoModel
|
||||
from rhodecode.model.scm import ScmModel, RepoList
|
||||
from rhodecode.model.settings import SettingsModel, VcsSettingsModel
|
||||
|
|
@ -217,7 +217,7 @@ def get_repo(request, apiuser, repoid, cache=Optional(True)):
|
|||
|
||||
|
||||
@jsonrpc_method()
|
||||
def get_repos(request, apiuser):
|
||||
def get_repos(request, apiuser, root=Optional(None), traverse=Optional(True)):
|
||||
"""
|
||||
Lists all existing repositories.
|
||||
|
||||
|
|
@ -226,6 +226,14 @@ def get_repos(request, apiuser):
|
|||
|
||||
:param apiuser: This is filled automatically from the |authtoken|.
|
||||
:type apiuser: AuthUser
|
||||
:param root: specify root repository group to fetch repositories.
|
||||
filters the returned repositories to be members of given root group.
|
||||
:type root: Optional(None)
|
||||
:param traverse: traverse given root into subrepositories. With this flag
|
||||
set to False, it will only return top-level repositories from `root`.
|
||||
if root is empty it will return just top-level repositories.
|
||||
:type traverse: Optional(True)
|
||||
|
||||
|
||||
Example output:
|
||||
|
||||
|
|
@ -257,8 +265,28 @@ def get_repos(request, apiuser):
|
|||
_perms = ('repository.read', 'repository.write', 'repository.admin',)
|
||||
extras = {'user': apiuser}
|
||||
|
||||
repo_list = RepoList(
|
||||
RepoModel().get_all(), perm_set=_perms, extra_kwargs=extras)
|
||||
root = Optional.extract(root)
|
||||
traverse = Optional.extract(traverse, binary=True)
|
||||
|
||||
if root:
|
||||
# verify parent existance, if it's empty return an error
|
||||
parent = RepoGroup.get_by_group_name(root)
|
||||
if not parent:
|
||||
raise JSONRPCError(
|
||||
'Root repository group `{}` does not exist'.format(root))
|
||||
|
||||
if traverse:
|
||||
repos = RepoModel().get_repos_for_root(root=root, traverse=traverse)
|
||||
else:
|
||||
repos = RepoModel().get_repos_for_root(root=parent)
|
||||
else:
|
||||
if traverse:
|
||||
repos = RepoModel().get_all()
|
||||
else:
|
||||
# return just top-level
|
||||
repos = RepoModel().get_repos_for_root(root=None)
|
||||
|
||||
repo_list = RepoList(repos, perm_set=_perms, extra_kwargs=extras)
|
||||
return [repo.get_api_data(include_secrets=include_secrets)
|
||||
for repo in repo_list]
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,19 @@ class RepoModel(BaseModel):
|
|||
|
||||
return None
|
||||
|
||||
def get_repos_for_root(self, root, traverse=False):
|
||||
if traverse:
|
||||
like_expression = u'{}%'.format(safe_unicode(root))
|
||||
repos = Repository.query().filter(
|
||||
Repository.repo_name.like(like_expression)).all()
|
||||
else:
|
||||
if root and not isinstance(root, RepoGroup):
|
||||
raise ValueError(
|
||||
'Root must be an instance '
|
||||
'of RepoGroup, got:{} instead'.format(type(root)))
|
||||
repos = Repository.query().filter(Repository.group == root).all()
|
||||
return repos
|
||||
|
||||
def get_url(self, repo):
|
||||
return h.url('summary_home', repo_name=safe_str(repo.repo_name),
|
||||
qualified=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue