##// END OF EJS Templates
fixes issue #884 Pull Request fails when setting the lang=ja
marcink -
r4097:7baea802 default
parent child Browse files
Show More
@@ -1,193 +1,193 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.model.changeset_status
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6
7 7 :created_on: Apr 30, 2012
8 8 :author: marcink
9 9 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
10 10 :license: GPLv3, see COPYING for more details.
11 11 """
12 12 # This program is free software: you can redistribute it and/or modify
13 13 # it under the terms of the GNU General Public License as published by
14 14 # the Free Software Foundation, either version 3 of the License, or
15 15 # (at your option) any later version.
16 16 #
17 17 # This program is distributed in the hope that it will be useful,
18 18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 20 # GNU General Public License for more details.
21 21 #
22 22 # You should have received a copy of the GNU General Public License
23 23 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 24
25 25
26 26 import logging
27 27 from collections import defaultdict
28 28
29 29 from rhodecode.model import BaseModel
30 30 from rhodecode.model.db import ChangesetStatus, PullRequest
31 31 from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
32 32
33 33 log = logging.getLogger(__name__)
34 34
35 35
36 36 class ChangesetStatusModel(BaseModel):
37 37
38 38 cls = ChangesetStatus
39 39
40 40 def __get_changeset_status(self, changeset_status):
41 41 return self._get_instance(ChangesetStatus, changeset_status)
42 42
43 43 def __get_pull_request(self, pull_request):
44 44 return self._get_instance(PullRequest, pull_request)
45 45
46 46 def _get_status_query(self, repo, revision, pull_request,
47 47 with_revisions=False):
48 48 repo = self._get_repo(repo)
49 49
50 50 q = ChangesetStatus.query()\
51 51 .filter(ChangesetStatus.repo == repo)
52 52 if not with_revisions:
53 53 q = q.filter(ChangesetStatus.version == 0)
54 54
55 55 if revision:
56 56 q = q.filter(ChangesetStatus.revision == revision)
57 57 elif pull_request:
58 58 pull_request = self.__get_pull_request(pull_request)
59 59 q = q.filter(ChangesetStatus.pull_request == pull_request)
60 60 else:
61 61 raise Exception('Please specify revision or pull_request')
62 62 q.order_by(ChangesetStatus.version.asc())
63 63 return q
64 64
65 65 def calculate_status(self, statuses_by_reviewers):
66 66 """
67 67 approved if consensus
68 68 (old description: leading one wins, if number of occurrences are equal than weaker wins)
69 69
70 70 :param statuses_by_reviewers:
71 71 """
72 72 votes = defaultdict(int)
73 73 reviewers_number = len(statuses_by_reviewers)
74 74 for user, statuses in statuses_by_reviewers:
75 75 if statuses:
76 76 ver, latest = statuses[0]
77 77 votes[latest.status] += 1
78 78 else:
79 79 votes[ChangesetStatus.DEFAULT] += 1
80 80
81 81 if votes.get(ChangesetStatus.STATUS_APPROVED) == reviewers_number:
82 82 return ChangesetStatus.STATUS_APPROVED
83 83 else:
84 84 return ChangesetStatus.STATUS_UNDER_REVIEW
85 85
86 86 def get_statuses(self, repo, revision=None, pull_request=None,
87 87 with_revisions=False):
88 88 q = self._get_status_query(repo, revision, pull_request,
89 89 with_revisions)
90 90 return q.all()
91 91
92 92 def get_status(self, repo, revision=None, pull_request=None, as_str=True):
93 93 """
94 94 Returns latest status of changeset for given revision or for given
95 95 pull request. Statuses are versioned inside a table itself and
96 96 version == 0 is always the current one
97 97
98 98 :param repo:
99 99 :param revision: 40char hash or None
100 100 :param pull_request: pull_request reference
101 101 :param as_str: return status as string not object
102 102 """
103 103 q = self._get_status_query(repo, revision, pull_request)
104 104
105 105 # need to use first here since there can be multiple statuses
106 106 # returned from pull_request
107 107 status = q.first()
108 108 if as_str:
109 109 status = status.status if status else status
110 110 st = status or ChangesetStatus.DEFAULT
111 111 return str(st)
112 112 return status
113 113
114 114 def set_status(self, repo, status, user, comment=None, revision=None,
115 115 pull_request=None, dont_allow_on_closed_pull_request=False):
116 116 """
117 117 Creates new status for changeset or updates the old ones bumping their
118 118 version, leaving the current status at
119 119
120 120 :param repo:
121 121 :param revision:
122 122 :param status:
123 123 :param user:
124 124 :param comment:
125 125 :param dont_allow_on_closed_pull_request: don't allow a status change
126 126 if last status was for pull request and it's closed. We shouldn't
127 127 mess around this manually
128 128 """
129 129 repo = self._get_repo(repo)
130 130
131 131 q = ChangesetStatus.query()
132 132 if not comment:
133 133 from rhodecode.model.comment import ChangesetCommentsModel
134 134 comment = ChangesetCommentsModel().create(
135 text='Auto status change to %s' % (ChangesetStatus.get_status_lbl(status)),
135 text=u'Auto status change to %s' % (ChangesetStatus.get_status_lbl(status)),
136 136 repo=repo,
137 137 user=user,
138 138 pull_request=pull_request,
139 139 send_email=False
140 140 )
141 141 if revision:
142 142 q = q.filter(ChangesetStatus.repo == repo)
143 143 q = q.filter(ChangesetStatus.revision == revision)
144 144 elif pull_request:
145 145 pull_request = self.__get_pull_request(pull_request)
146 146 q = q.filter(ChangesetStatus.repo == pull_request.org_repo)
147 147 q = q.filter(ChangesetStatus.revision.in_(pull_request.revisions))
148 148 cur_statuses = q.all()
149 149
150 150 #if statuses exists and last is associated with a closed pull request
151 151 # we need to check if we can allow this status change
152 152 if (dont_allow_on_closed_pull_request and cur_statuses
153 153 and getattr(cur_statuses[0].pull_request, 'status', '')
154 154 == PullRequest.STATUS_CLOSED):
155 155 raise StatusChangeOnClosedPullRequestError(
156 156 'Changing status on closed pull request is not allowed'
157 157 )
158 158
159 159 #update all current statuses with older version
160 160 if cur_statuses:
161 161 for st in cur_statuses:
162 162 st.version += 1
163 163 self.sa.add(st)
164 164
165 165 def _create_status(user, repo, status, comment, revision, pull_request):
166 166 new_status = ChangesetStatus()
167 167 new_status.author = self._get_user(user)
168 168 new_status.repo = self._get_repo(repo)
169 169 new_status.status = status
170 170 new_status.comment = comment
171 171 new_status.revision = revision
172 172 new_status.pull_request = pull_request
173 173 return new_status
174 174
175 175 if revision:
176 176 new_status = _create_status(user=user, repo=repo, status=status,
177 177 comment=comment, revision=revision,
178 178 pull_request=None)
179 179 self.sa.add(new_status)
180 180 return new_status
181 181 elif pull_request:
182 182 #pull request can have more than one revision associated to it
183 183 #we need to create new version for each one
184 184 new_statuses = []
185 185 repo = pull_request.org_repo
186 186 for rev in pull_request.revisions:
187 187 new_status = _create_status(user=user, repo=repo,
188 188 status=status, comment=comment,
189 189 revision=rev,
190 190 pull_request=pull_request)
191 191 new_statuses.append(new_status)
192 192 self.sa.add(new_status)
193 193 return new_statuses
General Comments 0
You need to be logged in to leave comments. Login now