##// END OF EJS Templates
events: use branch from previous commit for repo push event commits...
dan -
r845:1e04fb3b stable
parent child Browse files
Show More
@@ -1,258 +1,263 b''
1 1 # Copyright (C) 2016-2016 RhodeCode GmbH
2 2 #
3 3 # This program is free software: you can redistribute it and/or modify
4 4 # it under the terms of the GNU Affero General Public License, version 3
5 5 # (only), as published by the Free Software Foundation.
6 6 #
7 7 # This program is distributed in the hope that it will be useful,
8 8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 # GNU General Public License for more details.
11 11 #
12 12 # You should have received a copy of the GNU Affero General Public License
13 13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 #
15 15 # This program is dual-licensed. If you wish to learn more about the
16 16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 18
19 19 import logging
20 20
21 21 from rhodecode.translation import lazy_ugettext
22 22 from rhodecode.model.db import User, Repository, Session
23 23 from rhodecode.events.base import RhodecodeEvent
24 24 from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
25 25
26 26 log = logging.getLogger(__name__)
27 27
28 28 def _commits_as_dict(commit_ids, repos):
29 29 """
30 30 Helper function to serialize commit_ids
31 31
32 32 :param commit_ids: commits to get
33 33 :param repos: list of repos to check
34 34 """
35 35 from rhodecode.lib.utils2 import extract_mentioned_users
36 36 from rhodecode.model.db import Repository
37 37 from rhodecode.lib import helpers as h
38 38 from rhodecode.lib.helpers import process_patterns
39 39 from rhodecode.lib.helpers import urlify_commit_message
40 40
41 41 if not repos:
42 42 raise Exception('no repo defined')
43 43
44 44 if not isinstance(repos, (tuple, list)):
45 45 repos = [repos]
46 46
47 47 if not commit_ids:
48 48 return []
49 49
50 50 needed_commits = list(commit_ids)
51 51
52 52 commits = []
53 53 reviewers = []
54 54 for repo in repos:
55 55 if not needed_commits:
56 56 return commits # return early if we have the commits we need
57 57
58 58 vcs_repo = repo.scm_instance(cache=False)
59 59 try:
60 60 # use copy of needed_commits since we modify it while iterating
61 61 for commit_id in list(needed_commits):
62 62 try:
63 63 cs = vcs_repo.get_changeset(commit_id)
64 64 except CommitDoesNotExistError:
65 65 continue # maybe its in next repo
66 66
67 67 cs_data = cs.__json__()
68 68 cs_data['mentions'] = extract_mentioned_users(cs_data['message'])
69 69 cs_data['reviewers'] = reviewers
70 70 cs_data['url'] = h.url('changeset_home',
71 71 repo_name=repo.repo_name,
72 72 revision=cs_data['raw_id'],
73 73 qualified=True
74 74 )
75 75 urlified_message, issues_data = process_patterns(
76 76 cs_data['message'], repo.repo_name)
77 77 cs_data['issues'] = issues_data
78 78 cs_data['message_html'] = urlify_commit_message(cs_data['message'],
79 79 repo.repo_name)
80 80 commits.append(cs_data)
81 81
82 82 needed_commits.remove(commit_id)
83 83
84 84 except Exception as e:
85 85 log.exception(e)
86 86 # we don't send any commits when crash happens, only full list matters
87 87 # we short circuit then.
88 88 return []
89 89
90 90 missing_commits = set(commit_ids) - set(c['raw_id'] for c in commits)
91 91 if missing_commits:
92 92 log.error('missing commits: %s' % ', '.join(missing_commits))
93 93
94 94 return commits
95 95
96 96
97 97 def _issues_as_dict(commits):
98 98 """ Helper function to serialize issues from commits """
99 99 issues = {}
100 100 for commit in commits:
101 101 for issue in commit['issues']:
102 102 issues[issue['id']] = issue
103 103 return issues
104 104
105 105 class RepoEvent(RhodecodeEvent):
106 106 """
107 107 Base class for events acting on a repository.
108 108
109 109 :param repo: a :class:`Repository` instance
110 110 """
111 111
112 112 def __init__(self, repo):
113 113 super(RepoEvent, self).__init__()
114 114 self.repo = repo
115 115
116 116 def as_dict(self):
117 117 from rhodecode.model.repo import RepoModel
118 118 data = super(RepoEvent, self).as_dict()
119 119 data.update({
120 120 'repo': {
121 121 'repo_id': self.repo.repo_id,
122 122 'repo_name': self.repo.repo_name,
123 123 'repo_type': self.repo.repo_type,
124 124 'url': RepoModel().get_url(self.repo)
125 125 }
126 126 })
127 127 return data
128 128
129 129
130 130 class RepoPreCreateEvent(RepoEvent):
131 131 """
132 132 An instance of this class is emitted as an :term:`event` before a repo is
133 133 created.
134 134 """
135 135 name = 'repo-pre-create'
136 136 display_name = lazy_ugettext('repository pre create')
137 137
138 138
139 139 class RepoCreateEvent(RepoEvent):
140 140 """
141 141 An instance of this class is emitted as an :term:`event` whenever a repo is
142 142 created.
143 143 """
144 144 name = 'repo-create'
145 145 display_name = lazy_ugettext('repository created')
146 146
147 147
148 148 class RepoPreDeleteEvent(RepoEvent):
149 149 """
150 150 An instance of this class is emitted as an :term:`event` whenever a repo is
151 151 created.
152 152 """
153 153 name = 'repo-pre-delete'
154 154 display_name = lazy_ugettext('repository pre delete')
155 155
156 156
157 157 class RepoDeleteEvent(RepoEvent):
158 158 """
159 159 An instance of this class is emitted as an :term:`event` whenever a repo is
160 160 created.
161 161 """
162 162 name = 'repo-delete'
163 163 display_name = lazy_ugettext('repository deleted')
164 164
165 165
166 166 class RepoVCSEvent(RepoEvent):
167 167 """
168 168 Base class for events triggered by the VCS
169 169 """
170 170 def __init__(self, repo_name, extras):
171 171 self.repo = Repository.get_by_repo_name(repo_name)
172 172 if not self.repo:
173 173 raise Exception('repo by this name %s does not exist' % repo_name)
174 174 self.extras = extras
175 175 super(RepoVCSEvent, self).__init__(self.repo)
176 176
177 177 @property
178 178 def actor(self):
179 179 if self.extras.get('username'):
180 180 return User.get_by_username(self.extras['username'])
181 181
182 182 @property
183 183 def actor_ip(self):
184 184 if self.extras.get('ip'):
185 185 return self.extras['ip']
186 186
187 187 @property
188 188 def server_url(self):
189 189 if self.extras.get('server_url'):
190 190 return self.extras['server_url']
191 191
192 192
193 193 class RepoPrePullEvent(RepoVCSEvent):
194 194 """
195 195 An instance of this class is emitted as an :term:`event` before commits
196 196 are pulled from a repo.
197 197 """
198 198 name = 'repo-pre-pull'
199 199 display_name = lazy_ugettext('repository pre pull')
200 200
201 201
202 202 class RepoPullEvent(RepoVCSEvent):
203 203 """
204 204 An instance of this class is emitted as an :term:`event` after commits
205 205 are pulled from a repo.
206 206 """
207 207 name = 'repo-pull'
208 208 display_name = lazy_ugettext('repository pull')
209 209
210 210
211 211 class RepoPrePushEvent(RepoVCSEvent):
212 212 """
213 213 An instance of this class is emitted as an :term:`event` before commits
214 214 are pushed to a repo.
215 215 """
216 216 name = 'repo-pre-push'
217 217 display_name = lazy_ugettext('repository pre push')
218 218
219 219
220 220 class RepoPushEvent(RepoVCSEvent):
221 221 """
222 222 An instance of this class is emitted as an :term:`event` after commits
223 223 are pushed to a repo.
224 224
225 225 :param extras: (optional) dict of data from proxied VCS actions
226 226 """
227 227 name = 'repo-push'
228 228 display_name = lazy_ugettext('repository push')
229 229
230 230 def __init__(self, repo_name, pushed_commit_ids, extras):
231 231 super(RepoPushEvent, self).__init__(repo_name, extras)
232 232 self.pushed_commit_ids = pushed_commit_ids
233 233
234 234 def as_dict(self):
235 235 data = super(RepoPushEvent, self).as_dict()
236 236 branch_url = repo_url = data['repo']['url']
237 237
238 238 commits = _commits_as_dict(
239 239 commit_ids=self.pushed_commit_ids, repos=[self.repo])
240
241 last_branch = None
242 for commit in reversed(commits):
243 commit['branch'] = commit['branch'] or last_branch
244 last_branch = commit['branch']
240 245 issues = _issues_as_dict(commits)
241 246
242 247 branches = set(
243 248 commit['branch'] for commit in commits if commit['branch'])
244 249 branches = [
245 250 {
246 251 'name': branch,
247 252 'url': '{}/changelog?branch={}'.format(
248 253 data['repo']['url'], branch)
249 254 }
250 255 for branch in branches
251 256 ]
252 257
253 258 data['push'] = {
254 259 'commits': commits,
255 260 'issues': issues,
256 261 'branches': branches,
257 262 }
258 263 return data
General Comments 0
You need to be logged in to leave comments. Login now