Show More
@@ -20,18 +20,23 b'' | |||
|
20 | 20 | |
|
21 | 21 | import logging |
|
22 | 22 | |
|
23 | import collections | |
|
24 | from pyramid.httpexceptions import HTTPFound, HTTPNotFound | |
|
23 | 25 | from pyramid.view import view_config |
|
24 | 26 | |
|
25 | 27 | from rhodecode.apps._base import RepoAppView, DataGridAppView |
|
26 | from rhodecode.lib import helpers as h | |
|
27 | from rhodecode.lib import audit_logger | |
|
28 | from rhodecode.lib import helpers as h, diffs, codeblocks | |
|
28 | 29 | from rhodecode.lib.auth import ( |
|
29 | 30 | LoginRequired, HasRepoPermissionAnyDecorator) |
|
30 | 31 | from rhodecode.lib.utils import PartialRenderer |
|
31 | from rhodecode.lib.utils2 import str2bool | |
|
32 | from rhodecode.lib.utils2 import str2bool, safe_int, safe_str | |
|
33 | from rhodecode.lib.vcs.backends.base import EmptyCommit | |
|
34 | from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError, \ | |
|
35 | RepositoryRequirementError, NodeDoesNotExistError | |
|
32 | 36 | from rhodecode.model.comment import CommentsModel |
|
33 | from rhodecode.model.db import PullRequest | |
|
34 | from rhodecode.model.pull_request import PullRequestModel | |
|
37 | from rhodecode.model.db import PullRequest, PullRequestVersion, \ | |
|
38 | ChangesetComment, ChangesetStatus | |
|
39 | from rhodecode.model.pull_request import PullRequestModel, MergeCheck | |
|
35 | 40 | |
|
36 | 41 | log = logging.getLogger(__name__) |
|
37 | 42 | |
@@ -39,11 +44,11 b' log = logging.getLogger(__name__)' | |||
|
39 | 44 | class RepoPullRequestsView(RepoAppView, DataGridAppView): |
|
40 | 45 | |
|
41 | 46 | def load_default_context(self): |
|
42 | c = self._get_local_tmpl_context() | |
|
43 | ||
|
47 | c = self._get_local_tmpl_context(include_app_defaults=True) | |
|
44 | 48 | # TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead |
|
45 | 49 | c.repo_info = self.db_repo |
|
46 | ||
|
50 | c.REVIEW_STATUS_APPROVED = ChangesetStatus.STATUS_APPROVED | |
|
51 | c.REVIEW_STATUS_REJECTED = ChangesetStatus.STATUS_REJECTED | |
|
47 | 52 | self._register_global_c(c) |
|
48 | 53 | return c |
|
49 | 54 | |
@@ -182,3 +187,398 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
182 | 187 | filter_type=filter_type, opened_by=opened_by, statuses=statuses) |
|
183 | 188 | |
|
184 | 189 | return data |
|
190 | ||
|
191 | def _get_pr_version(self, pull_request_id, version=None): | |
|
192 | pull_request_id = safe_int(pull_request_id) | |
|
193 | at_version = None | |
|
194 | ||
|
195 | if version and version == 'latest': | |
|
196 | pull_request_ver = PullRequest.get(pull_request_id) | |
|
197 | pull_request_obj = pull_request_ver | |
|
198 | _org_pull_request_obj = pull_request_obj | |
|
199 | at_version = 'latest' | |
|
200 | elif version: | |
|
201 | pull_request_ver = PullRequestVersion.get_or_404(version) | |
|
202 | pull_request_obj = pull_request_ver | |
|
203 | _org_pull_request_obj = pull_request_ver.pull_request | |
|
204 | at_version = pull_request_ver.pull_request_version_id | |
|
205 | else: | |
|
206 | _org_pull_request_obj = pull_request_obj = PullRequest.get_or_404( | |
|
207 | pull_request_id) | |
|
208 | ||
|
209 | pull_request_display_obj = PullRequest.get_pr_display_object( | |
|
210 | pull_request_obj, _org_pull_request_obj) | |
|
211 | ||
|
212 | return _org_pull_request_obj, pull_request_obj, \ | |
|
213 | pull_request_display_obj, at_version | |
|
214 | ||
|
215 | def _get_diffset(self, source_repo_name, source_repo, | |
|
216 | source_ref_id, target_ref_id, | |
|
217 | target_commit, source_commit, diff_limit, fulldiff, | |
|
218 | file_limit, display_inline_comments): | |
|
219 | ||
|
220 | vcs_diff = PullRequestModel().get_diff( | |
|
221 | source_repo, source_ref_id, target_ref_id) | |
|
222 | ||
|
223 | diff_processor = diffs.DiffProcessor( | |
|
224 | vcs_diff, format='newdiff', diff_limit=diff_limit, | |
|
225 | file_limit=file_limit, show_full_diff=fulldiff) | |
|
226 | ||
|
227 | _parsed = diff_processor.prepare() | |
|
228 | ||
|
229 | def _node_getter(commit): | |
|
230 | def get_node(fname): | |
|
231 | try: | |
|
232 | return commit.get_node(fname) | |
|
233 | except NodeDoesNotExistError: | |
|
234 | return None | |
|
235 | ||
|
236 | return get_node | |
|
237 | ||
|
238 | diffset = codeblocks.DiffSet( | |
|
239 | repo_name=self.db_repo_name, | |
|
240 | source_repo_name=source_repo_name, | |
|
241 | source_node_getter=_node_getter(target_commit), | |
|
242 | target_node_getter=_node_getter(source_commit), | |
|
243 | comments=display_inline_comments | |
|
244 | ) | |
|
245 | diffset = diffset.render_patchset( | |
|
246 | _parsed, target_commit.raw_id, source_commit.raw_id) | |
|
247 | ||
|
248 | return diffset | |
|
249 | ||
|
250 | @LoginRequired() | |
|
251 | @HasRepoPermissionAnyDecorator( | |
|
252 | 'repository.read', 'repository.write', 'repository.admin') | |
|
253 | # @view_config( | |
|
254 | # route_name='pullrequest_show', request_method='GET', | |
|
255 | # renderer='rhodecode:templates/pullrequests/pullrequest_show.mako') | |
|
256 | def pull_request_show(self): | |
|
257 | pull_request_id = safe_int( | |
|
258 | self.request.matchdict.get('pull_request_id')) | |
|
259 | c = self.load_default_context() | |
|
260 | ||
|
261 | version = self.request.GET.get('version') | |
|
262 | from_version = self.request.GET.get('from_version') or version | |
|
263 | merge_checks = self.request.GET.get('merge_checks') | |
|
264 | c.fulldiff = str2bool(self.request.GET.get('fulldiff')) | |
|
265 | ||
|
266 | (pull_request_latest, | |
|
267 | pull_request_at_ver, | |
|
268 | pull_request_display_obj, | |
|
269 | at_version) = self._get_pr_version( | |
|
270 | pull_request_id, version=version) | |
|
271 | pr_closed = pull_request_latest.is_closed() | |
|
272 | ||
|
273 | if pr_closed and (version or from_version): | |
|
274 | # not allow to browse versions | |
|
275 | raise HTTPFound(h.route_path( | |
|
276 | 'pullrequest_show', repo_name=self.db_repo_name, | |
|
277 | pull_request_id=pull_request_id)) | |
|
278 | ||
|
279 | versions = pull_request_display_obj.versions() | |
|
280 | ||
|
281 | c.at_version = at_version | |
|
282 | c.at_version_num = (at_version | |
|
283 | if at_version and at_version != 'latest' | |
|
284 | else None) | |
|
285 | c.at_version_pos = ChangesetComment.get_index_from_version( | |
|
286 | c.at_version_num, versions) | |
|
287 | ||
|
288 | (prev_pull_request_latest, | |
|
289 | prev_pull_request_at_ver, | |
|
290 | prev_pull_request_display_obj, | |
|
291 | prev_at_version) = self._get_pr_version( | |
|
292 | pull_request_id, version=from_version) | |
|
293 | ||
|
294 | c.from_version = prev_at_version | |
|
295 | c.from_version_num = (prev_at_version | |
|
296 | if prev_at_version and prev_at_version != 'latest' | |
|
297 | else None) | |
|
298 | c.from_version_pos = ChangesetComment.get_index_from_version( | |
|
299 | c.from_version_num, versions) | |
|
300 | ||
|
301 | # define if we're in COMPARE mode or VIEW at version mode | |
|
302 | compare = at_version != prev_at_version | |
|
303 | ||
|
304 | # pull_requests repo_name we opened it against | |
|
305 | # ie. target_repo must match | |
|
306 | if self.db_repo_name != pull_request_at_ver.target_repo.repo_name: | |
|
307 | raise HTTPNotFound() | |
|
308 | ||
|
309 | c.shadow_clone_url = PullRequestModel().get_shadow_clone_url( | |
|
310 | pull_request_at_ver) | |
|
311 | ||
|
312 | c.pull_request = pull_request_display_obj | |
|
313 | c.pull_request_latest = pull_request_latest | |
|
314 | ||
|
315 | if compare or (at_version and not at_version == 'latest'): | |
|
316 | c.allowed_to_change_status = False | |
|
317 | c.allowed_to_update = False | |
|
318 | c.allowed_to_merge = False | |
|
319 | c.allowed_to_delete = False | |
|
320 | c.allowed_to_comment = False | |
|
321 | c.allowed_to_close = False | |
|
322 | else: | |
|
323 | can_change_status = PullRequestModel().check_user_change_status( | |
|
324 | pull_request_at_ver, self._rhodecode_user) | |
|
325 | c.allowed_to_change_status = can_change_status and not pr_closed | |
|
326 | ||
|
327 | c.allowed_to_update = PullRequestModel().check_user_update( | |
|
328 | pull_request_latest, self._rhodecode_user) and not pr_closed | |
|
329 | c.allowed_to_merge = PullRequestModel().check_user_merge( | |
|
330 | pull_request_latest, self._rhodecode_user) and not pr_closed | |
|
331 | c.allowed_to_delete = PullRequestModel().check_user_delete( | |
|
332 | pull_request_latest, self._rhodecode_user) and not pr_closed | |
|
333 | c.allowed_to_comment = not pr_closed | |
|
334 | c.allowed_to_close = c.allowed_to_merge and not pr_closed | |
|
335 | ||
|
336 | c.forbid_adding_reviewers = False | |
|
337 | c.forbid_author_to_review = False | |
|
338 | c.forbid_commit_author_to_review = False | |
|
339 | ||
|
340 | if pull_request_latest.reviewer_data and \ | |
|
341 | 'rules' in pull_request_latest.reviewer_data: | |
|
342 | rules = pull_request_latest.reviewer_data['rules'] or {} | |
|
343 | try: | |
|
344 | c.forbid_adding_reviewers = rules.get( | |
|
345 | 'forbid_adding_reviewers') | |
|
346 | c.forbid_author_to_review = rules.get( | |
|
347 | 'forbid_author_to_review') | |
|
348 | c.forbid_commit_author_to_review = rules.get( | |
|
349 | 'forbid_commit_author_to_review') | |
|
350 | except Exception: | |
|
351 | pass | |
|
352 | ||
|
353 | # check merge capabilities | |
|
354 | _merge_check = MergeCheck.validate( | |
|
355 | pull_request_latest, user=self._rhodecode_user) | |
|
356 | c.pr_merge_errors = _merge_check.error_details | |
|
357 | c.pr_merge_possible = not _merge_check.failed | |
|
358 | c.pr_merge_message = _merge_check.merge_msg | |
|
359 | ||
|
360 | c.pull_request_review_status = _merge_check.review_status | |
|
361 | if merge_checks: | |
|
362 | self.request.override_renderer = \ | |
|
363 | 'rhodecode:templates/pullrequests/pullrequest_merge_checks.mako' | |
|
364 | return self._get_template_context(c) | |
|
365 | ||
|
366 | comments_model = CommentsModel() | |
|
367 | ||
|
368 | # reviewers and statuses | |
|
369 | c.pull_request_reviewers = pull_request_at_ver.reviewers_statuses() | |
|
370 | allowed_reviewers = [x[0].user_id for x in c.pull_request_reviewers] | |
|
371 | ||
|
372 | # GENERAL COMMENTS with versions # | |
|
373 | q = comments_model._all_general_comments_of_pull_request(pull_request_latest) | |
|
374 | q = q.order_by(ChangesetComment.comment_id.asc()) | |
|
375 | general_comments = q | |
|
376 | ||
|
377 | # pick comments we want to render at current version | |
|
378 | c.comment_versions = comments_model.aggregate_comments( | |
|
379 | general_comments, versions, c.at_version_num) | |
|
380 | c.comments = c.comment_versions[c.at_version_num]['until'] | |
|
381 | ||
|
382 | # INLINE COMMENTS with versions # | |
|
383 | q = comments_model._all_inline_comments_of_pull_request(pull_request_latest) | |
|
384 | q = q.order_by(ChangesetComment.comment_id.asc()) | |
|
385 | inline_comments = q | |
|
386 | ||
|
387 | c.inline_versions = comments_model.aggregate_comments( | |
|
388 | inline_comments, versions, c.at_version_num, inline=True) | |
|
389 | ||
|
390 | # inject latest version | |
|
391 | latest_ver = PullRequest.get_pr_display_object( | |
|
392 | pull_request_latest, pull_request_latest) | |
|
393 | ||
|
394 | c.versions = versions + [latest_ver] | |
|
395 | ||
|
396 | # if we use version, then do not show later comments | |
|
397 | # than current version | |
|
398 | display_inline_comments = collections.defaultdict( | |
|
399 | lambda: collections.defaultdict(list)) | |
|
400 | for co in inline_comments: | |
|
401 | if c.at_version_num: | |
|
402 | # pick comments that are at least UPTO given version, so we | |
|
403 | # don't render comments for higher version | |
|
404 | should_render = co.pull_request_version_id and \ | |
|
405 | co.pull_request_version_id <= c.at_version_num | |
|
406 | else: | |
|
407 | # showing all, for 'latest' | |
|
408 | should_render = True | |
|
409 | ||
|
410 | if should_render: | |
|
411 | display_inline_comments[co.f_path][co.line_no].append(co) | |
|
412 | ||
|
413 | # load diff data into template context, if we use compare mode then | |
|
414 | # diff is calculated based on changes between versions of PR | |
|
415 | ||
|
416 | source_repo = pull_request_at_ver.source_repo | |
|
417 | source_ref_id = pull_request_at_ver.source_ref_parts.commit_id | |
|
418 | ||
|
419 | target_repo = pull_request_at_ver.target_repo | |
|
420 | target_ref_id = pull_request_at_ver.target_ref_parts.commit_id | |
|
421 | ||
|
422 | if compare: | |
|
423 | # in compare switch the diff base to latest commit from prev version | |
|
424 | target_ref_id = prev_pull_request_display_obj.revisions[0] | |
|
425 | ||
|
426 | # despite opening commits for bookmarks/branches/tags, we always | |
|
427 | # convert this to rev to prevent changes after bookmark or branch change | |
|
428 | c.source_ref_type = 'rev' | |
|
429 | c.source_ref = source_ref_id | |
|
430 | ||
|
431 | c.target_ref_type = 'rev' | |
|
432 | c.target_ref = target_ref_id | |
|
433 | ||
|
434 | c.source_repo = source_repo | |
|
435 | c.target_repo = target_repo | |
|
436 | ||
|
437 | c.commit_ranges = [] | |
|
438 | source_commit = EmptyCommit() | |
|
439 | target_commit = EmptyCommit() | |
|
440 | c.missing_requirements = False | |
|
441 | ||
|
442 | source_scm = source_repo.scm_instance() | |
|
443 | target_scm = target_repo.scm_instance() | |
|
444 | ||
|
445 | # try first shadow repo, fallback to regular repo | |
|
446 | try: | |
|
447 | commits_source_repo = pull_request_latest.get_shadow_repo() | |
|
448 | except Exception: | |
|
449 | log.debug('Failed to get shadow repo', exc_info=True) | |
|
450 | commits_source_repo = source_scm | |
|
451 | ||
|
452 | c.commits_source_repo = commits_source_repo | |
|
453 | commit_cache = {} | |
|
454 | try: | |
|
455 | pre_load = ["author", "branch", "date", "message"] | |
|
456 | show_revs = pull_request_at_ver.revisions | |
|
457 | for rev in show_revs: | |
|
458 | comm = commits_source_repo.get_commit( | |
|
459 | commit_id=rev, pre_load=pre_load) | |
|
460 | c.commit_ranges.append(comm) | |
|
461 | commit_cache[comm.raw_id] = comm | |
|
462 | ||
|
463 | # Order here matters, we first need to get target, and then | |
|
464 | # the source | |
|
465 | target_commit = commits_source_repo.get_commit( | |
|
466 | commit_id=safe_str(target_ref_id)) | |
|
467 | ||
|
468 | source_commit = commits_source_repo.get_commit( | |
|
469 | commit_id=safe_str(source_ref_id)) | |
|
470 | ||
|
471 | except CommitDoesNotExistError: | |
|
472 | log.warning( | |
|
473 | 'Failed to get commit from `{}` repo'.format( | |
|
474 | commits_source_repo), exc_info=True) | |
|
475 | except RepositoryRequirementError: | |
|
476 | log.warning( | |
|
477 | 'Failed to get all required data from repo', exc_info=True) | |
|
478 | c.missing_requirements = True | |
|
479 | ||
|
480 | c.ancestor = None # set it to None, to hide it from PR view | |
|
481 | ||
|
482 | try: | |
|
483 | ancestor_id = source_scm.get_common_ancestor( | |
|
484 | source_commit.raw_id, target_commit.raw_id, target_scm) | |
|
485 | c.ancestor_commit = source_scm.get_commit(ancestor_id) | |
|
486 | except Exception: | |
|
487 | c.ancestor_commit = None | |
|
488 | ||
|
489 | c.statuses = source_repo.statuses( | |
|
490 | [x.raw_id for x in c.commit_ranges]) | |
|
491 | ||
|
492 | # auto collapse if we have more than limit | |
|
493 | collapse_limit = diffs.DiffProcessor._collapse_commits_over | |
|
494 | c.collapse_all_commits = len(c.commit_ranges) > collapse_limit | |
|
495 | c.compare_mode = compare | |
|
496 | ||
|
497 | # diff_limit is the old behavior, will cut off the whole diff | |
|
498 | # if the limit is applied otherwise will just hide the | |
|
499 | # big files from the front-end | |
|
500 | diff_limit = c.visual.cut_off_limit_diff | |
|
501 | file_limit = c.visual.cut_off_limit_file | |
|
502 | ||
|
503 | c.missing_commits = False | |
|
504 | if (c.missing_requirements | |
|
505 | or isinstance(source_commit, EmptyCommit) | |
|
506 | or source_commit == target_commit): | |
|
507 | ||
|
508 | c.missing_commits = True | |
|
509 | else: | |
|
510 | ||
|
511 | c.diffset = self._get_diffset( | |
|
512 | c.source_repo.repo_name, commits_source_repo, | |
|
513 | source_ref_id, target_ref_id, | |
|
514 | target_commit, source_commit, | |
|
515 | diff_limit, c.fulldiff, file_limit, display_inline_comments) | |
|
516 | ||
|
517 | c.limited_diff = c.diffset.limited_diff | |
|
518 | ||
|
519 | # calculate removed files that are bound to comments | |
|
520 | comment_deleted_files = [ | |
|
521 | fname for fname in display_inline_comments | |
|
522 | if fname not in c.diffset.file_stats] | |
|
523 | ||
|
524 | c.deleted_files_comments = collections.defaultdict(dict) | |
|
525 | for fname, per_line_comments in display_inline_comments.items(): | |
|
526 | if fname in comment_deleted_files: | |
|
527 | c.deleted_files_comments[fname]['stats'] = 0 | |
|
528 | c.deleted_files_comments[fname]['comments'] = list() | |
|
529 | for lno, comments in per_line_comments.items(): | |
|
530 | c.deleted_files_comments[fname]['comments'].extend( | |
|
531 | comments) | |
|
532 | ||
|
533 | # this is a hack to properly display links, when creating PR, the | |
|
534 | # compare view and others uses different notation, and | |
|
535 | # compare_commits.mako renders links based on the target_repo. | |
|
536 | # We need to swap that here to generate it properly on the html side | |
|
537 | c.target_repo = c.source_repo | |
|
538 | ||
|
539 | c.commit_statuses = ChangesetStatus.STATUSES | |
|
540 | ||
|
541 | c.show_version_changes = not pr_closed | |
|
542 | if c.show_version_changes: | |
|
543 | cur_obj = pull_request_at_ver | |
|
544 | prev_obj = prev_pull_request_at_ver | |
|
545 | ||
|
546 | old_commit_ids = prev_obj.revisions | |
|
547 | new_commit_ids = cur_obj.revisions | |
|
548 | commit_changes = PullRequestModel()._calculate_commit_id_changes( | |
|
549 | old_commit_ids, new_commit_ids) | |
|
550 | c.commit_changes_summary = commit_changes | |
|
551 | ||
|
552 | # calculate the diff for commits between versions | |
|
553 | c.commit_changes = [] | |
|
554 | mark = lambda cs, fw: list( | |
|
555 | h.itertools.izip_longest([], cs, fillvalue=fw)) | |
|
556 | for c_type, raw_id in mark(commit_changes.added, 'a') \ | |
|
557 | + mark(commit_changes.removed, 'r') \ | |
|
558 | + mark(commit_changes.common, 'c'): | |
|
559 | ||
|
560 | if raw_id in commit_cache: | |
|
561 | commit = commit_cache[raw_id] | |
|
562 | else: | |
|
563 | try: | |
|
564 | commit = commits_source_repo.get_commit(raw_id) | |
|
565 | except CommitDoesNotExistError: | |
|
566 | # in case we fail extracting still use "dummy" commit | |
|
567 | # for display in commit diff | |
|
568 | commit = h.AttributeDict( | |
|
569 | {'raw_id': raw_id, | |
|
570 | 'message': 'EMPTY or MISSING COMMIT'}) | |
|
571 | c.commit_changes.append([c_type, commit]) | |
|
572 | ||
|
573 | # current user review statuses for each version | |
|
574 | c.review_versions = {} | |
|
575 | if self._rhodecode_user.user_id in allowed_reviewers: | |
|
576 | for co in general_comments: | |
|
577 | if co.author.user_id == self._rhodecode_user.user_id: | |
|
578 | # each comment has a status change | |
|
579 | status = co.status_change | |
|
580 | if status: | |
|
581 | _ver_pr = status[0].comment.pull_request_version_id | |
|
582 | c.review_versions[_ver_pr] = status[0] | |
|
583 | ||
|
584 | return self._get_template_context(c) |
@@ -282,8 +282,9 b' class PullrequestsController(BaseRepoCon' | |||
|
282 | 282 | h.flash(msg, category='error') |
|
283 | 283 | return redirect(url('pullrequest_home', repo_name=repo_name)) |
|
284 | 284 | |
|
285 | return redirect(url('pullrequest_show', repo_name=target_repo, | |
|
286 | pull_request_id=pull_request.pull_request_id)) | |
|
285 | raise HTTPFound( | |
|
286 | h.route_path('pullrequest_show', repo_name=target_repo, | |
|
287 | pull_request_id=pull_request.pull_request_id)) | |
|
287 | 288 | |
|
288 | 289 | @LoginRequired() |
|
289 | 290 | @NotAnonymous() |
@@ -420,10 +421,10 b' class PullrequestsController(BaseRepoCon' | |||
|
420 | 421 | scm=pull_request.target_repo.repo_type) |
|
421 | 422 | self._merge_pull_request(pull_request, user, extras) |
|
422 | 423 | |
|
423 | return redirect(url( | |
|
424 | 'pullrequest_show', | |
|
425 | repo_name=pull_request.target_repo.repo_name, | |
|
426 | pull_request_id=pull_request.pull_request_id)) | |
|
424 | raise HTTPFound( | |
|
425 | h.route_path('pullrequest_show', | |
|
426 | repo_name=pull_request.target_repo.repo_name, | |
|
427 | pull_request_id=pull_request.pull_request_id)) | |
|
427 | 428 | |
|
428 | 429 | def _merge_pull_request(self, pull_request, user, extras): |
|
429 | 430 | merge_resp = PullRequestModel().merge( |
@@ -964,8 +965,10 b' class PullrequestsController(BaseRepoCon' | |||
|
964 | 965 | Session().commit() |
|
965 | 966 | |
|
966 | 967 | if not request.is_xhr: |
|
967 | return redirect(h.url('pullrequest_show', repo_name=repo_name, | |
|
968 | pull_request_id=pull_request_id)) | |
|
968 | raise HTTPFound( | |
|
969 | h.route_path('pullrequest_show', | |
|
970 | repo_name=repo_name, | |
|
971 | pull_request_id=pull_request_id)) | |
|
969 | 972 | |
|
970 | 973 | data = { |
|
971 | 974 | 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))), |
@@ -175,6 +175,7 b' class ActionParser(object):' | |||
|
175 | 175 | return group_name |
|
176 | 176 | |
|
177 | 177 | def get_pull_request(self): |
|
178 | from rhodecode.lib import helpers as h | |
|
178 | 179 | pull_request_id = self.action_params |
|
179 | 180 | if self.is_deleted(): |
|
180 | 181 | repo_name = self.user_log.repository_name |
@@ -182,8 +183,8 b' class ActionParser(object):' | |||
|
182 | 183 | repo_name = self.user_log.repository.repo_name |
|
183 | 184 | return link_to( |
|
184 | 185 | _('Pull request #%s') % pull_request_id, |
|
185 |
|
|
|
186 | pull_request_id=pull_request_id)) | |
|
186 | h.route_path('pullrequest_show', repo_name=repo_name, | |
|
187 | pull_request_id=pull_request_id)) | |
|
187 | 188 | |
|
188 | 189 | def get_archive_name(self): |
|
189 | 190 | archive_name = self.action_params |
@@ -330,6 +330,11 b' def attach_context_attributes(context, r' | |||
|
330 | 330 | |
|
331 | 331 | context.rhodecode_instanceid = config.get('instance_id') |
|
332 | 332 | |
|
333 | context.visual.cut_off_limit_diff = safe_int( | |
|
334 | config.get('cut_off_limit_diff')) | |
|
335 | context.visual.cut_off_limit_file = safe_int( | |
|
336 | config.get('cut_off_limit_file')) | |
|
337 | ||
|
333 | 338 | # AppEnlight |
|
334 | 339 | context.appenlight_enabled = str2bool(config.get('appenlight', 'false')) |
|
335 | 340 | context.appenlight_api_public_key = config.get( |
@@ -438,8 +438,7 b' class CommentsModel(BaseModel):' | |||
|
438 | 438 | pull_request_id=pull_request.pull_request_id, |
|
439 | 439 | _anchor='comment-%s' % comment.comment_id) |
|
440 | 440 | else: |
|
441 | return request.route_url( | |
|
442 | 'pullrequest_show', | |
|
441 | return request.route_url('pullrequest_show', | |
|
443 | 442 | repo_name=safe_str(pull_request.target_repo.repo_name), |
|
444 | 443 | pull_request_id=pull_request.pull_request_id, |
|
445 | 444 | _anchor='comment-%s' % comment.comment_id) |
@@ -997,8 +997,7 b' class PullRequestModel(BaseModel):' | |||
|
997 | 997 | 'pull_requests_global', |
|
998 | 998 | pull_request_id=pull_request.pull_request_id,) |
|
999 | 999 | else: |
|
1000 | return request.route_url( | |
|
1001 | 'pullrequest_show', | |
|
1000 | return request.route_url('pullrequest_show', | |
|
1002 | 1001 | repo_name=safe_str(pull_request.target_repo.repo_name), |
|
1003 | 1002 | pull_request_id=pull_request.pull_request_id,) |
|
1004 | 1003 | |
@@ -1027,11 +1026,9 b' class PullRequestModel(BaseModel):' | |||
|
1027 | 1026 | pr_source_repo = pull_request_obj.source_repo |
|
1028 | 1027 | pr_target_repo = pull_request_obj.target_repo |
|
1029 | 1028 | |
|
1030 | pr_url = h.url( | |
|
1031 | 'pullrequest_show', | |
|
1029 | pr_url = h.route_url('pullrequest_show', | |
|
1032 | 1030 | repo_name=pr_target_repo.repo_name, |
|
1033 | pull_request_id=pull_request_obj.pull_request_id, | |
|
1034 | qualified=True,) | |
|
1031 | pull_request_id=pull_request_obj.pull_request_id,) | |
|
1035 | 1032 | |
|
1036 | 1033 | # set some variables for email notification |
|
1037 | 1034 | pr_target_repo_url = h.route_url( |
@@ -23,7 +23,7 b'' | |||
|
23 | 23 | %if c.statuses.get(commit.raw_id): |
|
24 | 24 | <div class="changeset-status-ico"> |
|
25 | 25 | %if c.statuses.get(commit.raw_id)[2]: |
|
26 |
<a class="tooltip" title="${_('Commit status: %s\nClick to open associated pull request #%s') % (h.commit_status_lbl(c.statuses.get(commit.raw_id)[0]), c.statuses.get(commit.raw_id)[2])}" href="${h. |
|
|
26 | <a class="tooltip" title="${_('Commit status: %s\nClick to open associated pull request #%s') % (h.commit_status_lbl(c.statuses.get(commit.raw_id)[0]), c.statuses.get(commit.raw_id)[2])}" href="${h.route_path('pullrequest_show',repo_name=c.statuses.get(commit.raw_id)[3],pull_request_id=c.statuses.get(commit.raw_id)[2])}"> | |
|
27 | 27 | <div class="${'flag_status %s' % c.statuses.get(commit.raw_id)[0]}"></div> |
|
28 | 28 | </a> |
|
29 | 29 | %else: |
@@ -61,7 +61,7 b'' | |||
|
61 | 61 | % else: |
|
62 | 62 | <div class="status-change"> |
|
63 | 63 | % if comment.pull_request: |
|
64 |
<a href="${h. |
|
|
64 | <a href="${h.route_path('pullrequest_show',repo_name=comment.pull_request.target_repo.repo_name,pull_request_id=comment.pull_request.pull_request_id)}"> | |
|
65 | 65 | % if comment.status_change: |
|
66 | 66 | ${_('pull request #%s') % comment.pull_request.pull_request_id}: |
|
67 | 67 | % else: |
@@ -122,7 +122,7 b'' | |||
|
122 | 122 | </a> |
|
123 | 123 | % else: |
|
124 | 124 | <div title="${_('Comment from pull request version {0}').format(pr_index_ver)}"> |
|
125 |
<a href="${h. |
|
|
125 | <a href="${h.route_path('pullrequest_show',repo_name=comment.pull_request.target_repo.repo_name,pull_request_id=comment.pull_request.pull_request_id, version=comment.pull_request_version_id)}"> | |
|
126 | 126 | <code class="pr-version-num"> |
|
127 | 127 | ${'v{}'.format(pr_index_ver)} |
|
128 | 128 | </code> |
@@ -299,7 +299,7 b'' | |||
|
299 | 299 | </%def> |
|
300 | 300 | |
|
301 | 301 | <%def name="pullrequest_name(pull_request_id, target_repo_name, short=False)"> |
|
302 |
<a href="${h. |
|
|
302 | <a href="${h.route_path('pullrequest_show',repo_name=target_repo_name,pull_request_id=pull_request_id)}"> | |
|
303 | 303 | % if short: |
|
304 | 304 | #${pull_request_id} |
|
305 | 305 | % else: |
@@ -18,7 +18,7 b'' | |||
|
18 | 18 | %if c.statuses.get(cs.raw_id): |
|
19 | 19 | <div class="changeset-status-ico shortlog"> |
|
20 | 20 | %if c.statuses.get(cs.raw_id)[2]: |
|
21 |
<a class="tooltip" title="${_('Commit status: %s\nClick to open associated pull request #%s') % (c.statuses.get(cs.raw_id)[0], c.statuses.get(cs.raw_id)[2])}" href="${h. |
|
|
21 | <a class="tooltip" title="${_('Commit status: %s\nClick to open associated pull request #%s') % (c.statuses.get(cs.raw_id)[0], c.statuses.get(cs.raw_id)[2])}" href="${h.route_path('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}"> | |
|
22 | 22 | <div class="${'flag_status %s' % c.statuses.get(cs.raw_id)[0]}"></div> |
|
23 | 23 | </a> |
|
24 | 24 | %else: |
General Comments 0
You need to be logged in to leave comments.
Login now