Show More
@@ -21,11 +21,13 b'' | |||||
21 | """ |
|
21 | """ | |
22 | pull requests controller for rhodecode for initializing pull requests |
|
22 | pull requests controller for rhodecode for initializing pull requests | |
23 | """ |
|
23 | """ | |
|
24 | import types | |||
24 |
|
25 | |||
25 | import peppercorn |
|
26 | import peppercorn | |
26 | import formencode |
|
27 | import formencode | |
27 | import logging |
|
28 | import logging | |
28 |
|
29 | |||
|
30 | ||||
29 | from webob.exc import HTTPNotFound, HTTPForbidden, HTTPBadRequest |
|
31 | from webob.exc import HTTPNotFound, HTTPForbidden, HTTPBadRequest | |
30 | from pylons import request, tmpl_context as c, url |
|
32 | from pylons import request, tmpl_context as c, url | |
31 | from pylons.controllers.util import redirect |
|
33 | from pylons.controllers.util import redirect | |
@@ -46,8 +48,9 b' from rhodecode.lib.channelstream import ' | |||||
46 | from rhodecode.lib.compat import OrderedDict |
|
48 | from rhodecode.lib.compat import OrderedDict | |
47 | from rhodecode.lib.utils import jsonify |
|
49 | from rhodecode.lib.utils import jsonify | |
48 | from rhodecode.lib.utils2 import ( |
|
50 | from rhodecode.lib.utils2 import ( | |
49 |
safe_int, safe_str, str2bool, safe_unicode |
|
51 | safe_int, safe_str, str2bool, safe_unicode) | |
50 |
from rhodecode.lib.vcs.backends.base import |
|
52 | from rhodecode.lib.vcs.backends.base import ( | |
|
53 | EmptyCommit, UpdateFailureReason, EmptyRepository) | |||
51 | from rhodecode.lib.vcs.exceptions import ( |
|
54 | from rhodecode.lib.vcs.exceptions import ( | |
52 | EmptyRepositoryError, CommitDoesNotExistError, RepositoryRequirementError, |
|
55 | EmptyRepositoryError, CommitDoesNotExistError, RepositoryRequirementError, | |
53 | NodeDoesNotExistError) |
|
56 | NodeDoesNotExistError) | |
@@ -680,7 +683,13 b' class PullrequestsController(BaseRepoCon' | |||||
680 | def _get_pr_version(self, pull_request_id, version=None): |
|
683 | def _get_pr_version(self, pull_request_id, version=None): | |
681 | pull_request_id = safe_int(pull_request_id) |
|
684 | pull_request_id = safe_int(pull_request_id) | |
682 | at_version = None |
|
685 | at_version = None | |
683 | if version: |
|
686 | ||
|
687 | if version and version == 'latest': | |||
|
688 | pull_request_ver = PullRequest.get(pull_request_id) | |||
|
689 | pull_request_obj = pull_request_ver | |||
|
690 | _org_pull_request_obj = pull_request_obj | |||
|
691 | at_version = 'latest' | |||
|
692 | elif version: | |||
684 | pull_request_ver = PullRequestVersion.get_or_404(version) |
|
693 | pull_request_ver = PullRequestVersion.get_or_404(version) | |
685 | pull_request_obj = pull_request_ver |
|
694 | pull_request_obj = pull_request_ver | |
686 | _org_pull_request_obj = pull_request_ver.pull_request |
|
695 | _org_pull_request_obj = pull_request_ver.pull_request | |
@@ -688,57 +697,58 b' class PullrequestsController(BaseRepoCon' | |||||
688 | else: |
|
697 | else: | |
689 | _org_pull_request_obj = pull_request_obj = PullRequest.get_or_404(pull_request_id) |
|
698 | _org_pull_request_obj = pull_request_obj = PullRequest.get_or_404(pull_request_id) | |
690 |
|
699 | |||
691 |
|
|
700 | pull_request_display_obj = PullRequest.get_pr_display_object( | |
692 | """ |
|
701 | pull_request_obj, _org_pull_request_obj) | |
693 | Special object wrapper for showing PullRequest data via Versions |
|
|||
694 | It mimics PR object as close as possible. This is read only object |
|
|||
695 | just for display |
|
|||
696 | """ |
|
|||
697 | def __init__(self, attrs): |
|
|||
698 | self.attrs = attrs |
|
|||
699 | # internal have priority over the given ones via attrs |
|
|||
700 | self.internal = ['versions'] |
|
|||
701 |
|
||||
702 | def __getattr__(self, item): |
|
|||
703 | if item in self.internal: |
|
|||
704 | return getattr(self, item) |
|
|||
705 | try: |
|
|||
706 | return self.attrs[item] |
|
|||
707 | except KeyError: |
|
|||
708 | raise AttributeError( |
|
|||
709 | '%s object has no attribute %s' % (self, item)) |
|
|||
710 |
|
||||
711 | def versions(self): |
|
|||
712 | return pull_request_obj.versions.order_by( |
|
|||
713 | PullRequestVersion.pull_request_version_id).all() |
|
|||
714 |
|
||||
715 | def is_closed(self): |
|
|||
716 | return pull_request_obj.is_closed() |
|
|||
717 |
|
||||
718 | attrs = StrictAttributeDict(pull_request_obj.get_api_data()) |
|
|||
719 |
|
||||
720 | attrs.author = StrictAttributeDict( |
|
|||
721 | pull_request_obj.author.get_api_data()) |
|
|||
722 | if pull_request_obj.target_repo: |
|
|||
723 | attrs.target_repo = StrictAttributeDict( |
|
|||
724 | pull_request_obj.target_repo.get_api_data()) |
|
|||
725 | attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url |
|
|||
726 |
|
||||
727 | if pull_request_obj.source_repo: |
|
|||
728 | attrs.source_repo = StrictAttributeDict( |
|
|||
729 | pull_request_obj.source_repo.get_api_data()) |
|
|||
730 | attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url |
|
|||
731 |
|
||||
732 | attrs.source_ref_parts = pull_request_obj.source_ref_parts |
|
|||
733 | attrs.target_ref_parts = pull_request_obj.target_ref_parts |
|
|||
734 |
|
||||
735 | attrs.shadow_merge_ref = _org_pull_request_obj.shadow_merge_ref |
|
|||
736 |
|
||||
737 | pull_request_display_obj = PullRequestDisplay(attrs) |
|
|||
738 |
|
||||
739 | return _org_pull_request_obj, pull_request_obj, \ |
|
702 | return _org_pull_request_obj, pull_request_obj, \ | |
740 | pull_request_display_obj, at_version |
|
703 | pull_request_display_obj, at_version | |
741 |
|
704 | |||
|
705 | def _get_pr_version_changes(self, version, pull_request_latest): | |||
|
706 | """ | |||
|
707 | Generate changes commits, and diff data based on the current pr version | |||
|
708 | """ | |||
|
709 | ||||
|
710 | #TODO(marcink): save those changes as JSON metadata for chaching later. | |||
|
711 | ||||
|
712 | # fake the version to add the "initial" state object | |||
|
713 | pull_request_initial = PullRequest.get_pr_display_object( | |||
|
714 | pull_request_latest, pull_request_latest, | |||
|
715 | internal_methods=['get_commit', 'versions']) | |||
|
716 | pull_request_initial.revisions = [] | |||
|
717 | pull_request_initial.source_repo.get_commit = types.MethodType( | |||
|
718 | lambda *a, **k: EmptyCommit(), pull_request_initial) | |||
|
719 | pull_request_initial.source_repo.scm_instance = types.MethodType( | |||
|
720 | lambda *a, **k: EmptyRepository(), pull_request_initial) | |||
|
721 | ||||
|
722 | _changes_versions = [pull_request_latest] + \ | |||
|
723 | list(reversed(c.versions)) + \ | |||
|
724 | [pull_request_initial] | |||
|
725 | ||||
|
726 | if version == 'latest': | |||
|
727 | index = 0 | |||
|
728 | else: | |||
|
729 | for pos, prver in enumerate(_changes_versions): | |||
|
730 | ver = getattr(prver, 'pull_request_version_id', -1) | |||
|
731 | if ver == safe_int(version): | |||
|
732 | index = pos | |||
|
733 | break | |||
|
734 | else: | |||
|
735 | index = 0 | |||
|
736 | ||||
|
737 | cur_obj = _changes_versions[index] | |||
|
738 | prev_obj = _changes_versions[index + 1] | |||
|
739 | ||||
|
740 | old_commit_ids = set(prev_obj.revisions) | |||
|
741 | new_commit_ids = set(cur_obj.revisions) | |||
|
742 | ||||
|
743 | changes = PullRequestModel()._calculate_commit_id_changes( | |||
|
744 | old_commit_ids, new_commit_ids) | |||
|
745 | ||||
|
746 | old_diff_data, new_diff_data = PullRequestModel()._generate_update_diffs( | |||
|
747 | cur_obj, prev_obj) | |||
|
748 | file_changes = PullRequestModel()._calculate_file_changes( | |||
|
749 | old_diff_data, new_diff_data) | |||
|
750 | return changes, file_changes | |||
|
751 | ||||
742 | @LoginRequired() |
|
752 | @LoginRequired() | |
743 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
753 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
744 | 'repository.admin') |
|
754 | 'repository.admin') | |
@@ -763,7 +773,7 b' class PullrequestsController(BaseRepoCon' | |||||
763 | pull_request_at_ver) |
|
773 | pull_request_at_ver) | |
764 |
|
774 | |||
765 | pr_closed = pull_request_latest.is_closed() |
|
775 | pr_closed = pull_request_latest.is_closed() | |
766 | if at_version: |
|
776 | if at_version and not at_version == 'latest': | |
767 | c.allowed_to_change_status = False |
|
777 | c.allowed_to_change_status = False | |
768 | c.allowed_to_update = False |
|
778 | c.allowed_to_update = False | |
769 | c.allowed_to_merge = False |
|
779 | c.allowed_to_merge = False | |
@@ -840,11 +850,21 b' class PullrequestsController(BaseRepoCon' | |||||
840 | statuses = ChangesetStatus.STATUSES |
|
850 | statuses = ChangesetStatus.STATUSES | |
841 | c.commit_statuses = statuses |
|
851 | c.commit_statuses = statuses | |
842 |
|
852 | |||
843 | c.ancestor = None # TODO: add ancestor here |
|
853 | c.ancestor = None # TODO: add ancestor here | |
844 | c.pull_request = pull_request_display_obj |
|
854 | c.pull_request = pull_request_display_obj | |
845 | c.pull_request_latest = pull_request_latest |
|
855 | c.pull_request_latest = pull_request_latest | |
846 | c.at_version = at_version |
|
856 | c.at_version = at_version | |
847 |
|
857 | |||
|
858 | c.versions = pull_request_display_obj.versions() | |||
|
859 | c.changes = None | |||
|
860 | c.file_changes = None | |||
|
861 | ||||
|
862 | c.show_version_changes = 1 | |||
|
863 | ||||
|
864 | if at_version and c.show_version_changes: | |||
|
865 | c.changes, c.file_changes = self._get_pr_version_changes( | |||
|
866 | version, pull_request_latest) | |||
|
867 | ||||
848 | return render('/pullrequests/pullrequest_show.html') |
|
868 | return render('/pullrequests/pullrequest_show.html') | |
849 |
|
869 | |||
850 | @LoginRequired() |
|
870 | @LoginRequired() |
@@ -665,7 +665,8 b' class StrictAttributeDict(dict):' | |||||
665 | try: |
|
665 | try: | |
666 | return self[attr] |
|
666 | return self[attr] | |
667 | except KeyError: |
|
667 | except KeyError: | |
668 |
raise AttributeError('%s object has no attribute %s' % ( |
|
668 | raise AttributeError('%s object has no attribute %s' % ( | |
|
669 | self.__class__, attr)) | |||
669 | __setattr__ = dict.__setitem__ |
|
670 | __setattr__ = dict.__setitem__ | |
670 | __delattr__ = dict.__delitem__ |
|
671 | __delattr__ = dict.__delitem__ | |
671 |
|
672 |
@@ -1442,6 +1442,15 b' class EmptyChangeset(EmptyCommit):' | |||||
1442 | self.idx = value |
|
1442 | self.idx = value | |
1443 |
|
1443 | |||
1444 |
|
1444 | |||
|
1445 | class EmptyRepository(BaseRepository): | |||
|
1446 | def __init__(self, repo_path=None, config=None, create=False, **kwargs): | |||
|
1447 | pass | |||
|
1448 | ||||
|
1449 | def get_diff(self, *args, **kwargs): | |||
|
1450 | from rhodecode.lib.vcs.backends.git.diff import GitDiff | |||
|
1451 | return GitDiff('') | |||
|
1452 | ||||
|
1453 | ||||
1445 | class CollectionGenerator(object): |
|
1454 | class CollectionGenerator(object): | |
1446 |
|
1455 | |||
1447 | def __init__(self, repo, commit_ids, collection_size=None, pre_load=None): |
|
1456 | def __init__(self, repo, commit_ids, collection_size=None, pre_load=None): |
@@ -53,7 +53,7 b' from rhodecode.lib.vcs.backends.base imp' | |||||
53 | from rhodecode.lib.utils2 import ( |
|
53 | from rhodecode.lib.utils2 import ( | |
54 | str2bool, safe_str, get_commit_safe, safe_unicode, md5_safe, |
|
54 | str2bool, safe_str, get_commit_safe, safe_unicode, md5_safe, | |
55 | time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, |
|
55 | time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, | |
56 | glob2re) |
|
56 | glob2re, StrictAttributeDict) | |
57 | from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType |
|
57 | from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType | |
58 | from rhodecode.lib.ext_json import json |
|
58 | from rhodecode.lib.ext_json import json | |
59 | from rhodecode.lib.caching_query import FromCache |
|
59 | from rhodecode.lib.caching_query import FromCache | |
@@ -3213,6 +3213,64 b' class PullRequest(Base, _PullRequestBase' | |||||
3213 | cascade="all, delete, delete-orphan", |
|
3213 | cascade="all, delete, delete-orphan", | |
3214 | lazy='dynamic') |
|
3214 | lazy='dynamic') | |
3215 |
|
3215 | |||
|
3216 | ||||
|
3217 | @classmethod | |||
|
3218 | def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, | |||
|
3219 | internal_methods=None): | |||
|
3220 | ||||
|
3221 | class PullRequestDisplay(object): | |||
|
3222 | """ | |||
|
3223 | Special object wrapper for showing PullRequest data via Versions | |||
|
3224 | It mimics PR object as close as possible. This is read only object | |||
|
3225 | just for display | |||
|
3226 | """ | |||
|
3227 | ||||
|
3228 | def __init__(self, attrs, internal=None): | |||
|
3229 | self.attrs = attrs | |||
|
3230 | # internal have priority over the given ones via attrs | |||
|
3231 | self.internal = internal or ['versions'] | |||
|
3232 | ||||
|
3233 | def __getattr__(self, item): | |||
|
3234 | if item in self.internal: | |||
|
3235 | return getattr(self, item) | |||
|
3236 | try: | |||
|
3237 | return self.attrs[item] | |||
|
3238 | except KeyError: | |||
|
3239 | raise AttributeError( | |||
|
3240 | '%s object has no attribute %s' % (self, item)) | |||
|
3241 | ||||
|
3242 | def __repr__(self): | |||
|
3243 | return '<DB:PullRequestDisplay #%s>' % self.attrs.get('pull_request_id') | |||
|
3244 | ||||
|
3245 | def versions(self): | |||
|
3246 | return pull_request_obj.versions.order_by( | |||
|
3247 | PullRequestVersion.pull_request_version_id).all() | |||
|
3248 | ||||
|
3249 | def is_closed(self): | |||
|
3250 | return pull_request_obj.is_closed() | |||
|
3251 | ||||
|
3252 | attrs = StrictAttributeDict(pull_request_obj.get_api_data()) | |||
|
3253 | ||||
|
3254 | attrs.author = StrictAttributeDict( | |||
|
3255 | pull_request_obj.author.get_api_data()) | |||
|
3256 | if pull_request_obj.target_repo: | |||
|
3257 | attrs.target_repo = StrictAttributeDict( | |||
|
3258 | pull_request_obj.target_repo.get_api_data()) | |||
|
3259 | attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url | |||
|
3260 | ||||
|
3261 | if pull_request_obj.source_repo: | |||
|
3262 | attrs.source_repo = StrictAttributeDict( | |||
|
3263 | pull_request_obj.source_repo.get_api_data()) | |||
|
3264 | attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url | |||
|
3265 | ||||
|
3266 | attrs.source_ref_parts = pull_request_obj.source_ref_parts | |||
|
3267 | attrs.target_ref_parts = pull_request_obj.target_ref_parts | |||
|
3268 | attrs.revisions = pull_request_obj.revisions | |||
|
3269 | ||||
|
3270 | attrs.shadow_merge_ref = org_pull_request_obj.shadow_merge_ref | |||
|
3271 | ||||
|
3272 | return PullRequestDisplay(attrs, internal=internal_methods) | |||
|
3273 | ||||
3216 | def is_closed(self): |
|
3274 | def is_closed(self): | |
3217 | return self.status == self.STATUS_CLOSED |
|
3275 | return self.status == self.STATUS_CLOSED | |
3218 |
|
3276 |
@@ -1382,6 +1382,16 b' table.integrations {' | |||||
1382 | } |
|
1382 | } | |
1383 | } |
|
1383 | } | |
1384 |
|
1384 | |||
|
1385 | .compare_view_commits_title { | |||
|
1386 | .disabled { | |||
|
1387 | cursor: inherit; | |||
|
1388 | &:hover{ | |||
|
1389 | background-color: inherit; | |||
|
1390 | color: inherit; | |||
|
1391 | } | |||
|
1392 | } | |||
|
1393 | } | |||
|
1394 | ||||
1385 | // new entry in group_members |
|
1395 | // new entry in group_members | |
1386 | .td-author-new-entry { |
|
1396 | .td-author-new-entry { | |
1387 | background-color: rgba(red(@alert1), green(@alert1), blue(@alert1), 0.3); |
|
1397 | background-color: rgba(red(@alert1), green(@alert1), blue(@alert1), 0.3); |
@@ -45,7 +45,7 b'' | |||||
45 | <div class="summary-details block-left"> |
|
45 | <div class="summary-details block-left"> | |
46 | <%summary = lambda n:{False:'summary-short'}.get(n)%> |
|
46 | <%summary = lambda n:{False:'summary-short'}.get(n)%> | |
47 | <div class="pr-details-title"> |
|
47 | <div class="pr-details-title"> | |
48 | ${_('Pull request #%s') % c.pull_request.pull_request_id} ${_('From')} ${h.format_date(c.pull_request.created_on)} |
|
48 | <a href="${h.url('pull_requests_global', pull_request_id=c.pull_request.pull_request_id)}">${_('Pull request #%s') % c.pull_request.pull_request_id}</a> ${_('From')} ${h.format_date(c.pull_request.created_on)} | |
49 | %if c.allowed_to_update: |
|
49 | %if c.allowed_to_update: | |
50 | <div id="delete_pullrequest" class="pull-right action_button ${'' if c.allowed_to_delete else 'disabled' }" style="clear:inherit;padding: 0"> |
|
50 | <div id="delete_pullrequest" class="pull-right action_button ${'' if c.allowed_to_delete else 'disabled' }" style="clear:inherit;padding: 0"> | |
51 | % if c.allowed_to_delete: |
|
51 | % if c.allowed_to_delete: | |
@@ -112,22 +112,26 b'' | |||||
112 | </div> |
|
112 | </div> | |
113 |
|
113 | |||
114 | ## Link to the shadow repository. |
|
114 | ## Link to the shadow repository. | |
115 | %if not c.pull_request.is_closed() and c.pull_request.shadow_merge_ref: |
|
115 | <div class="field"> | |
116 |
<div class=" |
|
116 | <div class="label-summary"> | |
117 | <div class="label-summary"> |
|
117 | <label>${_('Merge')}:</label> | |
118 | <label>Merge:</label> |
|
118 | </div> | |
|
119 | <div class="input"> | |||
|
120 | % if not c.pull_request.is_closed() and c.pull_request.shadow_merge_ref: | |||
|
121 | <div class="pr-mergeinfo"> | |||
|
122 | %if h.is_hg(c.pull_request.target_repo): | |||
|
123 | <input type="text" value="hg clone -u ${c.pull_request.shadow_merge_ref.name} ${c.shadow_clone_url} pull-request-${c.pull_request.pull_request_id}" readonly="readonly"> | |||
|
124 | %elif h.is_git(c.pull_request.target_repo): | |||
|
125 | <input type="text" value="git clone --branch ${c.pull_request.shadow_merge_ref.name} ${c.shadow_clone_url} pull-request-${c.pull_request.pull_request_id}" readonly="readonly"> | |||
|
126 | %endif | |||
119 | </div> |
|
127 | </div> | |
120 |
|
|
128 | % else: | |
121 |
|
|
129 | <div class=""> | |
122 | %if h.is_hg(c.pull_request.target_repo): |
|
130 | ${_('Shadow repository data not available')}. | |
123 | <input type="text" value="hg clone -u ${c.pull_request.shadow_merge_ref.name} ${c.shadow_clone_url} pull-request-${c.pull_request.pull_request_id}" readonly="readonly"> |
|
|||
124 | %elif h.is_git(c.pull_request.target_repo): |
|
|||
125 | <input type="text" value="git clone --branch ${c.pull_request.shadow_merge_ref.name} ${c.shadow_clone_url} pull-request-${c.pull_request.pull_request_id}" readonly="readonly"> |
|
|||
126 | %endif |
|
|||
127 | </div> |
|
|||
128 | </div> |
|
131 | </div> | |
|
132 | % endif | |||
129 | </div> |
|
133 | </div> | |
130 |
|
|
134 | </div> | |
131 |
|
135 | |||
132 | <div class="field"> |
|
136 | <div class="field"> | |
133 | <div class="label-summary"> |
|
137 | <div class="label-summary"> | |
@@ -187,21 +191,23 b'' | |||||
187 |
|
191 | |||
188 | <div class="field"> |
|
192 | <div class="field"> | |
189 | <div class="label-summary"> |
|
193 | <div class="label-summary"> | |
190 | <label>${_('Versions')}:</label> |
|
194 | <label>${_('Versions')} (${len(c.versions)}):</label> | |
191 | </div> |
|
195 | </div> | |
|
196 | ||||
192 | <div> |
|
197 | <div> | |
|
198 | % if c.show_version_changes: | |||
193 | <table> |
|
199 | <table> | |
194 | <tr> |
|
200 | <tr> | |
195 | <td> |
|
201 | <td> | |
196 |
% if c.at_version |
|
202 | % if c.at_version in [None, 'latest']: | |
197 | <i class="icon-ok link"></i> |
|
203 | <i class="icon-ok link"></i> | |
198 | % endif |
|
204 | % endif | |
199 | </td> |
|
205 | </td> | |
200 | <td><code><a href="${h.url.current()}">latest</a></code></td> |
|
206 | <td><code><a href="${h.url.current(version='latest')}">latest</a></code></td> | |
201 | <td> |
|
207 | <td> | |
202 | <code>${c.pull_request_latest.source_ref_parts.commit_id[:6]}</code> |
|
208 | <code>${c.pull_request_latest.source_ref_parts.commit_id[:6]}</code> | |
203 | </td> |
|
209 | </td> | |
204 |
<td>${_('created')} ${h.age_component(c.pull_request |
|
210 | <td>${_('created')} ${h.age_component(c.pull_request_latest.updated_on)}</td> | |
205 | </tr> |
|
211 | </tr> | |
206 | % for ver in reversed(c.pull_request.versions()): |
|
212 | % for ver in reversed(c.pull_request.versions()): | |
207 | <tr> |
|
213 | <tr> | |
@@ -214,10 +220,36 b'' | |||||
214 | <td> |
|
220 | <td> | |
215 | <code>${ver.source_ref_parts.commit_id[:6]}</code> |
|
221 | <code>${ver.source_ref_parts.commit_id[:6]}</code> | |
216 | </td> |
|
222 | </td> | |
217 |
<td>${_('created')} ${h.age_component(ver. |
|
223 | <td>${_('created')} ${h.age_component(ver.updated_on)}</td> | |
218 | </tr> |
|
224 | </tr> | |
219 | % endfor |
|
225 | % endfor | |
220 | </table> |
|
226 | </table> | |
|
227 | ||||
|
228 | % if c.at_version: | |||
|
229 | <pre> | |||
|
230 | Changed commits: | |||
|
231 | * added: ${len(c.changes.added)} | |||
|
232 | * removed: ${len(c.changes.removed)} | |||
|
233 | ||||
|
234 | % if not (c.file_changes.added+c.file_changes.modified+c.file_changes.removed): | |||
|
235 | No file changes found | |||
|
236 | % else: | |||
|
237 | Changed files: | |||
|
238 | %for file_name in c.file_changes.added: | |||
|
239 | * A <a href="#${'a_' + h.FID('', file_name)}">${file_name}</a> | |||
|
240 | %endfor | |||
|
241 | %for file_name in c.file_changes.modified: | |||
|
242 | * M <a href="#${'a_' + h.FID('', file_name)}">${file_name}</a> | |||
|
243 | %endfor | |||
|
244 | %for file_name in c.file_changes.removed: | |||
|
245 | * R ${file_name} | |||
|
246 | %endfor | |||
|
247 | % endif | |||
|
248 | </pre> | |||
|
249 | % endif | |||
|
250 | % else: | |||
|
251 | ${_('Pull request versions not available')}. | |||
|
252 | % endif | |||
221 | </div> |
|
253 | </div> | |
222 | </div> |
|
254 | </div> | |
223 |
|
255 | |||
@@ -329,9 +361,9 b'' | |||||
329 | % endif |
|
361 | % endif | |
330 | <div class="compare_view_commits_title"> |
|
362 | <div class="compare_view_commits_title"> | |
331 | % if c.allowed_to_update and not c.pull_request.is_closed(): |
|
363 | % if c.allowed_to_update and not c.pull_request.is_closed(): | |
332 |
< |
|
364 | <a id="update_commits" class="btn btn-primary pull-right">${_('Update commits')}</a> | |
333 | % else: |
|
365 | % else: | |
334 |
< |
|
366 | <a class="tooltip btn disabled pull-right" disabled="disabled" title="${_('Update is disabled for current view')}">${_('Update commits')}</a> | |
335 | % endif |
|
367 | % endif | |
336 | % if len(c.commit_ranges): |
|
368 | % if len(c.commit_ranges): | |
337 | <h2>${ungettext('Compare View: %s commit','Compare View: %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}</h2> |
|
369 | <h2>${ungettext('Compare View: %s commit','Compare View: %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}</h2> |
@@ -1,5 +1,5 b'' | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 | Auto status change to |under_review| |
|
2 | Pull request updated. Auto status change to |under_review| | |
3 |
|
3 | |||
4 | .. role:: added |
|
4 | .. role:: added | |
5 | .. role:: removed |
|
5 | .. role:: removed |
@@ -95,7 +95,7 b' def test_rst_xss_raw_directive():' | |||||
95 |
|
95 | |||
96 | def test_render_rst_template_without_files(): |
|
96 | def test_render_rst_template_without_files(): | |
97 | expected = u'''\ |
|
97 | expected = u'''\ | |
98 | Auto status change to |under_review| |
|
98 | Pull request updated. Auto status change to |under_review| | |
99 |
|
99 | |||
100 | .. role:: added |
|
100 | .. role:: added | |
101 | .. role:: removed |
|
101 | .. role:: removed | |
@@ -125,7 +125,7 b' Auto status change to |under_review|' | |||||
125 |
|
125 | |||
126 | def test_render_rst_template_with_files(): |
|
126 | def test_render_rst_template_with_files(): | |
127 | expected = u'''\ |
|
127 | expected = u'''\ | |
128 | Auto status change to |under_review| |
|
128 | Pull request updated. Auto status change to |under_review| | |
129 |
|
129 | |||
130 | .. role:: added |
|
130 | .. role:: added | |
131 | .. role:: removed |
|
131 | .. role:: removed |
@@ -722,7 +722,7 b' def test_update_adds_a_comment_to_the_pu' | |||||
722 | # Expect to find a new comment about the change |
|
722 | # Expect to find a new comment about the change | |
723 | expected_message = textwrap.dedent( |
|
723 | expected_message = textwrap.dedent( | |
724 | """\ |
|
724 | """\ | |
725 | Auto status change to |under_review| |
|
725 | Pull request updated. Auto status change to |under_review| | |
726 |
|
726 | |||
727 | .. role:: added |
|
727 | .. role:: added | |
728 | .. role:: removed |
|
728 | .. role:: removed |
General Comments 0
You need to be logged in to leave comments.
Login now