##// END OF EJS Templates
events: send pushed commit ids in order
dan -
r782:1a5a75e1 default
parent child Browse files
Show More
@@ -1,257 +1,257 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 needed_commits = set(commit_ids)
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 for commit_id in list(needed_commits):
60 for commit_id in needed_commits:
61 61 try:
62 62 cs = vcs_repo.get_changeset(commit_id)
63 63 except CommitDoesNotExistError:
64 64 continue # maybe its in next repo
65 65
66 66 cs_data = cs.__json__()
67 67 cs_data['mentions'] = extract_mentioned_users(cs_data['message'])
68 68 cs_data['reviewers'] = reviewers
69 69 cs_data['url'] = h.url('changeset_home',
70 70 repo_name=repo.repo_name,
71 71 revision=cs_data['raw_id'],
72 72 qualified=True
73 73 )
74 74 urlified_message, issues_data = process_patterns(
75 75 cs_data['message'], repo.repo_name)
76 76 cs_data['issues'] = issues_data
77 77 cs_data['message_html'] = urlify_commit_message(cs_data['message'],
78 78 repo.repo_name)
79 79 commits.append(cs_data)
80 80
81 needed_commits.discard(commit_id)
81 needed_commits.remove(commit_id)
82 82
83 83 except Exception as e:
84 84 log.exception(e)
85 85 # we don't send any commits when crash happens, only full list matters
86 86 # we short circuit then.
87 87 return []
88 88
89 89 missing_commits = set(commit_ids) - set(c['raw_id'] for c in commits)
90 90 if missing_commits:
91 91 log.error('missing commits: %s' % ', '.join(missing_commits))
92 92
93 93 return commits
94 94
95 95
96 96 def _issues_as_dict(commits):
97 97 """ Helper function to serialize issues from commits """
98 98 issues = {}
99 99 for commit in commits:
100 100 for issue in commit['issues']:
101 101 issues[issue['id']] = issue
102 102 return issues
103 103
104 104 class RepoEvent(RhodecodeEvent):
105 105 """
106 106 Base class for events acting on a repository.
107 107
108 108 :param repo: a :class:`Repository` instance
109 109 """
110 110
111 111 def __init__(self, repo):
112 112 super(RepoEvent, self).__init__()
113 113 self.repo = repo
114 114
115 115 def as_dict(self):
116 116 from rhodecode.model.repo import RepoModel
117 117 data = super(RepoEvent, self).as_dict()
118 118 data.update({
119 119 'repo': {
120 120 'repo_id': self.repo.repo_id,
121 121 'repo_name': self.repo.repo_name,
122 122 'repo_type': self.repo.repo_type,
123 123 'url': RepoModel().get_url(self.repo)
124 124 }
125 125 })
126 126 return data
127 127
128 128
129 129 class RepoPreCreateEvent(RepoEvent):
130 130 """
131 131 An instance of this class is emitted as an :term:`event` before a repo is
132 132 created.
133 133 """
134 134 name = 'repo-pre-create'
135 135 display_name = lazy_ugettext('repository pre create')
136 136
137 137
138 138 class RepoCreateEvent(RepoEvent):
139 139 """
140 140 An instance of this class is emitted as an :term:`event` whenever a repo is
141 141 created.
142 142 """
143 143 name = 'repo-create'
144 144 display_name = lazy_ugettext('repository created')
145 145
146 146
147 147 class RepoPreDeleteEvent(RepoEvent):
148 148 """
149 149 An instance of this class is emitted as an :term:`event` whenever a repo is
150 150 created.
151 151 """
152 152 name = 'repo-pre-delete'
153 153 display_name = lazy_ugettext('repository pre delete')
154 154
155 155
156 156 class RepoDeleteEvent(RepoEvent):
157 157 """
158 158 An instance of this class is emitted as an :term:`event` whenever a repo is
159 159 created.
160 160 """
161 161 name = 'repo-delete'
162 162 display_name = lazy_ugettext('repository deleted')
163 163
164 164
165 165 class RepoVCSEvent(RepoEvent):
166 166 """
167 167 Base class for events triggered by the VCS
168 168 """
169 169 def __init__(self, repo_name, extras):
170 170 self.repo = Repository.get_by_repo_name(repo_name)
171 171 if not self.repo:
172 172 raise Exception('repo by this name %s does not exist' % repo_name)
173 173 self.extras = extras
174 174 super(RepoVCSEvent, self).__init__(self.repo)
175 175
176 176 @property
177 177 def actor(self):
178 178 if self.extras.get('username'):
179 179 return User.get_by_username(self.extras['username'])
180 180
181 181 @property
182 182 def actor_ip(self):
183 183 if self.extras.get('ip'):
184 184 return self.extras['ip']
185 185
186 186 @property
187 187 def server_url(self):
188 188 if self.extras.get('server_url'):
189 189 return self.extras['server_url']
190 190
191 191
192 192 class RepoPrePullEvent(RepoVCSEvent):
193 193 """
194 194 An instance of this class is emitted as an :term:`event` before commits
195 195 are pulled from a repo.
196 196 """
197 197 name = 'repo-pre-pull'
198 198 display_name = lazy_ugettext('repository pre pull')
199 199
200 200
201 201 class RepoPullEvent(RepoVCSEvent):
202 202 """
203 203 An instance of this class is emitted as an :term:`event` after commits
204 204 are pulled from a repo.
205 205 """
206 206 name = 'repo-pull'
207 207 display_name = lazy_ugettext('repository pull')
208 208
209 209
210 210 class RepoPrePushEvent(RepoVCSEvent):
211 211 """
212 212 An instance of this class is emitted as an :term:`event` before commits
213 213 are pushed to a repo.
214 214 """
215 215 name = 'repo-pre-push'
216 216 display_name = lazy_ugettext('repository pre push')
217 217
218 218
219 219 class RepoPushEvent(RepoVCSEvent):
220 220 """
221 221 An instance of this class is emitted as an :term:`event` after commits
222 222 are pushed to a repo.
223 223
224 224 :param extras: (optional) dict of data from proxied VCS actions
225 225 """
226 226 name = 'repo-push'
227 227 display_name = lazy_ugettext('repository push')
228 228
229 229 def __init__(self, repo_name, pushed_commit_ids, extras):
230 230 super(RepoPushEvent, self).__init__(repo_name, extras)
231 231 self.pushed_commit_ids = pushed_commit_ids
232 232
233 233 def as_dict(self):
234 234 data = super(RepoPushEvent, self).as_dict()
235 235 branch_url = repo_url = data['repo']['url']
236 236
237 237 commits = _commits_as_dict(
238 238 commit_ids=self.pushed_commit_ids, repos=[self.repo])
239 239 issues = _issues_as_dict(commits)
240 240
241 241 branches = set(
242 242 commit['branch'] for commit in commits if commit['branch'])
243 243 branches = [
244 244 {
245 245 'name': branch,
246 246 'url': '{}/changelog?branch={}'.format(
247 247 data['repo']['url'], branch)
248 248 }
249 249 for branch in branches
250 250 ]
251 251
252 252 data['push'] = {
253 253 'commits': commits,
254 254 'issues': issues,
255 255 'branches': branches,
256 256 }
257 257 return data
General Comments 0
You need to be logged in to leave comments. Login now