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