# HG changeset patch # User Marcin Kuzminski # Date 2020-05-05 11:24:19 # Node ID 4543620f2b6cf204ebe4c45bb135afbc50b95219 # Parent eca0587d6364e01b6f3b26b6334b590071827268 quick-search: added ability to search for pull-requests using `pr:` prefix. - permissions are checked against the access to target repositories diff --git a/rhodecode/apps/home/views.py b/rhodecode/apps/home/views.py --- a/rhodecode/apps/home/views.py +++ b/rhodecode/apps/home/views.py @@ -35,8 +35,8 @@ from rhodecode.lib.index import searcher from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int from rhodecode.lib.vcs.nodes import FileNode from rhodecode.model.db import ( - func, true, or_, case, in_filter_generator, Session, - Repository, RepoGroup, User, UserGroup) + func, true, or_, case, cast, in_filter_generator, String, Session, + Repository, RepoGroup, User, UserGroup, PullRequest) from rhodecode.model.repo import RepoModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.user import UserModel @@ -111,7 +111,7 @@ class HomeView(BaseAppView, DataGridAppV org_query = name_contains allowed_ids = self._rhodecode_user.repo_acl_ids( ['repository.read', 'repository.write', 'repository.admin'], - cache=False, name_filter=name_contains) or [-1] + cache=True, name_filter=name_contains) or [-1] query = Session().query( Repository.repo_name, @@ -162,7 +162,7 @@ class HomeView(BaseAppView, DataGridAppV org_query = name_contains allowed_ids = self._rhodecode_user.repo_group_acl_ids( ['group.read', 'group.write', 'group.admin'], - cache=False, name_filter=name_contains) or [-1] + cache=True, name_filter=name_contains) or [-1] query = Session().query( RepoGroup.group_id, @@ -282,6 +282,61 @@ class HomeView(BaseAppView, DataGridAppV } for obj in acl_iter], True + def _get_pull_request_list(self, name_contains=None, limit=20): + org_query = name_contains + if not name_contains: + return [], False + + # TODO(marcink): should all logged in users be allowed to search others? + allowed_user_search = self._rhodecode_user.username != User.DEFAULT_USER + if not allowed_user_search: + return [], False + + name_contains = re.compile('(?:pr:[ ]?)(.+)').findall(name_contains) + if len(name_contains) != 1: + return [], False + + name_contains = name_contains[0] + + allowed_ids = self._rhodecode_user.repo_acl_ids( + ['repository.read', 'repository.write', 'repository.admin'], + cache=True) or [-1] + + query = Session().query( + PullRequest.pull_request_id, + PullRequest.title, + ) + query = query.join(Repository, Repository.repo_id == PullRequest.target_repo_id) + + query = query.filter(or_( + # generate multiple IN to fix limitation problems + *in_filter_generator(Repository.repo_id, allowed_ids) + )) + + query = query.order_by(PullRequest.pull_request_id) + + if name_contains: + ilike_expression = u'%{}%'.format(safe_unicode(name_contains)) + query = query.filter(or_( + cast(PullRequest.pull_request_id, String).ilike(ilike_expression), + PullRequest.title.ilike(ilike_expression), + PullRequest.description.ilike(ilike_expression), + )) + + query = query.limit(limit) + + acl_iter = query + + return [ + { + 'id': obj.pull_request_id, + 'value': org_query, + 'value_display': 'pull request: `!{} - {}`'.format(obj.pull_request_id, obj.title[:50]), + 'type': 'pull_request', + 'url': h.route_path('pull_requests_global', pull_request_id=obj.pull_request_id) + } + for obj in acl_iter], True + def _get_hash_commit_list(self, auth_user, searcher, query, repo=None, repo_group=None): repo_name = repo_group_name = None if repo: @@ -624,6 +679,17 @@ class HomeView(BaseAppView, DataGridAppV has_specialized_search = True res.append(no_match('No matching user groups found')) + # pr: type search + if not prefix_match: + pull_requests, prefix_match = self._get_pull_request_list(query) + if pull_requests: + has_specialized_search = True + for serialized_pull_request in pull_requests: + res.append(serialized_pull_request) + elif prefix_match: + has_specialized_search = True + res.append(no_match('No matching pull requests found')) + # FTS commit: type search if not prefix_match: commits, prefix_match = self._get_hash_commit_list( diff --git a/rhodecode/templates/base/base.mako b/rhodecode/templates/base/base.mako --- a/rhodecode/templates/base/base.mako +++ b/rhodecode/templates/base/base.mako @@ -783,6 +783,8 @@ user_group:devops, to search for user groups, always global + pr:303, to search for pull request number, title, or description, always global + commit:efced4, to search for commits, scoped to repositories or groups file:models.py, to search for file paths, scoped to repositories or groups @@ -975,6 +977,10 @@ else if (searchType === 'user') { icon += ''.format(data['icon_link']); } + // pull request + else if (searchType === 'pull_request') { + icon += ' '; + } // commit else if (searchType === 'commit') { var repo_data = data['repo_data'];