##// END OF EJS Templates
extensions: adapt hooks to latest version of extensions (pre-push)
marcink -
r1456:c0280798 default
parent child Browse files
Show More
@@ -1,395 +1,396 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2013-2017 RhodeCode GmbH
3 # Copyright (C) 2013-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 """
22 """
23 Set of hooks run by RhodeCode Enterprise
23 Set of hooks run by RhodeCode Enterprise
24 """
24 """
25
25
26 import os
26 import os
27 import collections
27 import collections
28 import logging
28 import logging
29
29
30 import rhodecode
30 import rhodecode
31 from rhodecode import events
31 from rhodecode import events
32 from rhodecode.lib import helpers as h
32 from rhodecode.lib import helpers as h
33 from rhodecode.lib.utils import action_logger
33 from rhodecode.lib.utils import action_logger
34 from rhodecode.lib.utils2 import safe_str
34 from rhodecode.lib.utils2 import safe_str
35 from rhodecode.lib.exceptions import HTTPLockedRC, UserCreationError
35 from rhodecode.lib.exceptions import HTTPLockedRC, UserCreationError
36 from rhodecode.model.db import Repository, User
36 from rhodecode.model.db import Repository, User
37
37
38 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
39
39
40
40
41 HookResponse = collections.namedtuple('HookResponse', ('status', 'output'))
41 HookResponse = collections.namedtuple('HookResponse', ('status', 'output'))
42
42
43
43
44 def is_shadow_repo(extras):
44 def is_shadow_repo(extras):
45 """
45 """
46 Returns ``True`` if this is an action executed against a shadow repository.
46 Returns ``True`` if this is an action executed against a shadow repository.
47 """
47 """
48 return extras['is_shadow_repo']
48 return extras['is_shadow_repo']
49
49
50
50
51 def _get_scm_size(alias, root_path):
51 def _get_scm_size(alias, root_path):
52
52
53 if not alias.startswith('.'):
53 if not alias.startswith('.'):
54 alias += '.'
54 alias += '.'
55
55
56 size_scm, size_root = 0, 0
56 size_scm, size_root = 0, 0
57 for path, unused_dirs, files in os.walk(safe_str(root_path)):
57 for path, unused_dirs, files in os.walk(safe_str(root_path)):
58 if path.find(alias) != -1:
58 if path.find(alias) != -1:
59 for f in files:
59 for f in files:
60 try:
60 try:
61 size_scm += os.path.getsize(os.path.join(path, f))
61 size_scm += os.path.getsize(os.path.join(path, f))
62 except OSError:
62 except OSError:
63 pass
63 pass
64 else:
64 else:
65 for f in files:
65 for f in files:
66 try:
66 try:
67 size_root += os.path.getsize(os.path.join(path, f))
67 size_root += os.path.getsize(os.path.join(path, f))
68 except OSError:
68 except OSError:
69 pass
69 pass
70
70
71 size_scm_f = h.format_byte_size_binary(size_scm)
71 size_scm_f = h.format_byte_size_binary(size_scm)
72 size_root_f = h.format_byte_size_binary(size_root)
72 size_root_f = h.format_byte_size_binary(size_root)
73 size_total_f = h.format_byte_size_binary(size_root + size_scm)
73 size_total_f = h.format_byte_size_binary(size_root + size_scm)
74
74
75 return size_scm_f, size_root_f, size_total_f
75 return size_scm_f, size_root_f, size_total_f
76
76
77
77
78 # actual hooks called by Mercurial internally, and GIT by our Python Hooks
78 # actual hooks called by Mercurial internally, and GIT by our Python Hooks
79 def repo_size(extras):
79 def repo_size(extras):
80 """Present size of repository after push."""
80 """Present size of repository after push."""
81 repo = Repository.get_by_repo_name(extras.repository)
81 repo = Repository.get_by_repo_name(extras.repository)
82 vcs_part = safe_str(u'.%s' % repo.repo_type)
82 vcs_part = safe_str(u'.%s' % repo.repo_type)
83 size_vcs, size_root, size_total = _get_scm_size(vcs_part,
83 size_vcs, size_root, size_total = _get_scm_size(vcs_part,
84 repo.repo_full_path)
84 repo.repo_full_path)
85 msg = ('Repository `%s` size summary %s:%s repo:%s total:%s\n'
85 msg = ('Repository `%s` size summary %s:%s repo:%s total:%s\n'
86 % (repo.repo_name, vcs_part, size_vcs, size_root, size_total))
86 % (repo.repo_name, vcs_part, size_vcs, size_root, size_total))
87 return HookResponse(0, msg)
87 return HookResponse(0, msg)
88
88
89
89
90 def pre_push(extras):
90 def pre_push(extras):
91 """
91 """
92 Hook executed before pushing code.
92 Hook executed before pushing code.
93
93
94 It bans pushing when the repository is locked.
94 It bans pushing when the repository is locked.
95 """
95 """
96
96 usr = User.get_by_username(extras.username)
97 usr = User.get_by_username(extras.username)
97 output = ''
98 output = ''
98 if extras.locked_by[0] and usr.user_id != int(extras.locked_by[0]):
99 if extras.locked_by[0] and usr.user_id != int(extras.locked_by[0]):
99 locked_by = User.get(extras.locked_by[0]).username
100 locked_by = User.get(extras.locked_by[0]).username
100 reason = extras.locked_by[2]
101 reason = extras.locked_by[2]
101 # this exception is interpreted in git/hg middlewares and based
102 # this exception is interpreted in git/hg middlewares and based
102 # on that proper return code is server to client
103 # on that proper return code is server to client
103 _http_ret = HTTPLockedRC(
104 _http_ret = HTTPLockedRC(
104 _locked_by_explanation(extras.repository, locked_by, reason))
105 _locked_by_explanation(extras.repository, locked_by, reason))
105 if str(_http_ret.code).startswith('2'):
106 if str(_http_ret.code).startswith('2'):
106 # 2xx Codes don't raise exceptions
107 # 2xx Codes don't raise exceptions
107 output = _http_ret.title
108 output = _http_ret.title
108 else:
109 else:
109 raise _http_ret
110 raise _http_ret
110
111
111 # Propagate to external components. This is done after checking the
112 # Propagate to external components. This is done after checking the
112 # lock, for consistent behavior.
113 # lock, for consistent behavior.
113 if not is_shadow_repo(extras):
114 if not is_shadow_repo(extras):
114 pre_push_extension(repo_store_path=Repository.base_path(), **extras)
115 pre_push_extension(repo_store_path=Repository.base_path(), **extras)
115 events.trigger(events.RepoPrePushEvent(
116 events.trigger(events.RepoPrePushEvent(
116 repo_name=extras.repository, extras=extras))
117 repo_name=extras.repository, extras=extras))
117
118
118 return HookResponse(0, output)
119 return HookResponse(0, output)
119
120
120
121
121 def pre_pull(extras):
122 def pre_pull(extras):
122 """
123 """
123 Hook executed before pulling the code.
124 Hook executed before pulling the code.
124
125
125 It bans pulling when the repository is locked.
126 It bans pulling when the repository is locked.
126 """
127 """
127
128
128 output = ''
129 output = ''
129 if extras.locked_by[0]:
130 if extras.locked_by[0]:
130 locked_by = User.get(extras.locked_by[0]).username
131 locked_by = User.get(extras.locked_by[0]).username
131 reason = extras.locked_by[2]
132 reason = extras.locked_by[2]
132 # this exception is interpreted in git/hg middlewares and based
133 # this exception is interpreted in git/hg middlewares and based
133 # on that proper return code is server to client
134 # on that proper return code is server to client
134 _http_ret = HTTPLockedRC(
135 _http_ret = HTTPLockedRC(
135 _locked_by_explanation(extras.repository, locked_by, reason))
136 _locked_by_explanation(extras.repository, locked_by, reason))
136 if str(_http_ret.code).startswith('2'):
137 if str(_http_ret.code).startswith('2'):
137 # 2xx Codes don't raise exceptions
138 # 2xx Codes don't raise exceptions
138 output = _http_ret.title
139 output = _http_ret.title
139 else:
140 else:
140 raise _http_ret
141 raise _http_ret
141
142
142 # Propagate to external components. This is done after checking the
143 # Propagate to external components. This is done after checking the
143 # lock, for consistent behavior.
144 # lock, for consistent behavior.
144 if not is_shadow_repo(extras):
145 if not is_shadow_repo(extras):
145 pre_pull_extension(**extras)
146 pre_pull_extension(**extras)
146 events.trigger(events.RepoPrePullEvent(
147 events.trigger(events.RepoPrePullEvent(
147 repo_name=extras.repository, extras=extras))
148 repo_name=extras.repository, extras=extras))
148
149
149 return HookResponse(0, output)
150 return HookResponse(0, output)
150
151
151
152
152 def post_pull(extras):
153 def post_pull(extras):
153 """Hook executed after client pulls the code."""
154 """Hook executed after client pulls the code."""
154 user = User.get_by_username(extras.username)
155 user = User.get_by_username(extras.username)
155 action = 'pull'
156 action = 'pull'
156 action_logger(user, action, extras.repository, extras.ip, commit=True)
157 action_logger(user, action, extras.repository, extras.ip, commit=True)
157
158
158 # Propagate to external components.
159 # Propagate to external components.
159 if not is_shadow_repo(extras):
160 if not is_shadow_repo(extras):
160 post_pull_extension(**extras)
161 post_pull_extension(**extras)
161 events.trigger(events.RepoPullEvent(
162 events.trigger(events.RepoPullEvent(
162 repo_name=extras.repository, extras=extras))
163 repo_name=extras.repository, extras=extras))
163
164
164 output = ''
165 output = ''
165 # make lock is a tri state False, True, None. We only make lock on True
166 # make lock is a tri state False, True, None. We only make lock on True
166 if extras.make_lock is True and not is_shadow_repo(extras):
167 if extras.make_lock is True and not is_shadow_repo(extras):
167 Repository.lock(Repository.get_by_repo_name(extras.repository),
168 Repository.lock(Repository.get_by_repo_name(extras.repository),
168 user.user_id,
169 user.user_id,
169 lock_reason=Repository.LOCK_PULL)
170 lock_reason=Repository.LOCK_PULL)
170 msg = 'Made lock on repo `%s`' % (extras.repository,)
171 msg = 'Made lock on repo `%s`' % (extras.repository,)
171 output += msg
172 output += msg
172
173
173 if extras.locked_by[0]:
174 if extras.locked_by[0]:
174 locked_by = User.get(extras.locked_by[0]).username
175 locked_by = User.get(extras.locked_by[0]).username
175 reason = extras.locked_by[2]
176 reason = extras.locked_by[2]
176 _http_ret = HTTPLockedRC(
177 _http_ret = HTTPLockedRC(
177 _locked_by_explanation(extras.repository, locked_by, reason))
178 _locked_by_explanation(extras.repository, locked_by, reason))
178 if str(_http_ret.code).startswith('2'):
179 if str(_http_ret.code).startswith('2'):
179 # 2xx Codes don't raise exceptions
180 # 2xx Codes don't raise exceptions
180 output += _http_ret.title
181 output += _http_ret.title
181
182
182 return HookResponse(0, output)
183 return HookResponse(0, output)
183
184
184
185
185 def post_push(extras):
186 def post_push(extras):
186 """Hook executed after user pushes to the repository."""
187 """Hook executed after user pushes to the repository."""
187 action_tmpl = extras.action + ':%s'
188 action_tmpl = extras.action + ':%s'
188 commit_ids = extras.commit_ids[:29000]
189 commit_ids = extras.commit_ids[:29000]
189
190
190 action = action_tmpl % ','.join(commit_ids)
191 action = action_tmpl % ','.join(commit_ids)
191 action_logger(
192 action_logger(
192 extras.username, action, extras.repository, extras.ip, commit=True)
193 extras.username, action, extras.repository, extras.ip, commit=True)
193
194
194 # Propagate to external components.
195 # Propagate to external components.
195 if not is_shadow_repo(extras):
196 if not is_shadow_repo(extras):
196 post_push_extension(
197 post_push_extension(
197 repo_store_path=Repository.base_path(),
198 repo_store_path=Repository.base_path(),
198 pushed_revs=commit_ids,
199 pushed_revs=commit_ids,
199 **extras)
200 **extras)
200 events.trigger(events.RepoPushEvent(
201 events.trigger(events.RepoPushEvent(
201 repo_name=extras.repository,
202 repo_name=extras.repository,
202 pushed_commit_ids=commit_ids,
203 pushed_commit_ids=commit_ids,
203 extras=extras))
204 extras=extras))
204
205
205 output = ''
206 output = ''
206 # make lock is a tri state False, True, None. We only release lock on False
207 # make lock is a tri state False, True, None. We only release lock on False
207 if extras.make_lock is False and not is_shadow_repo(extras):
208 if extras.make_lock is False and not is_shadow_repo(extras):
208 Repository.unlock(Repository.get_by_repo_name(extras.repository))
209 Repository.unlock(Repository.get_by_repo_name(extras.repository))
209 msg = 'Released lock on repo `%s`\n' % extras.repository
210 msg = 'Released lock on repo `%s`\n' % extras.repository
210 output += msg
211 output += msg
211
212
212 if extras.locked_by[0]:
213 if extras.locked_by[0]:
213 locked_by = User.get(extras.locked_by[0]).username
214 locked_by = User.get(extras.locked_by[0]).username
214 reason = extras.locked_by[2]
215 reason = extras.locked_by[2]
215 _http_ret = HTTPLockedRC(
216 _http_ret = HTTPLockedRC(
216 _locked_by_explanation(extras.repository, locked_by, reason))
217 _locked_by_explanation(extras.repository, locked_by, reason))
217 # TODO: johbo: if not?
218 # TODO: johbo: if not?
218 if str(_http_ret.code).startswith('2'):
219 if str(_http_ret.code).startswith('2'):
219 # 2xx Codes don't raise exceptions
220 # 2xx Codes don't raise exceptions
220 output += _http_ret.title
221 output += _http_ret.title
221
222
222 output += 'RhodeCode: push completed\n'
223 output += 'RhodeCode: push completed\n'
223
224
224 return HookResponse(0, output)
225 return HookResponse(0, output)
225
226
226
227
227 def _locked_by_explanation(repo_name, user_name, reason):
228 def _locked_by_explanation(repo_name, user_name, reason):
228 message = (
229 message = (
229 'Repository `%s` locked by user `%s`. Reason:`%s`'
230 'Repository `%s` locked by user `%s`. Reason:`%s`'
230 % (repo_name, user_name, reason))
231 % (repo_name, user_name, reason))
231 return message
232 return message
232
233
233
234
234 def check_allowed_create_user(user_dict, created_by, **kwargs):
235 def check_allowed_create_user(user_dict, created_by, **kwargs):
235 # pre create hooks
236 # pre create hooks
236 if pre_create_user.is_active():
237 if pre_create_user.is_active():
237 allowed, reason = pre_create_user(created_by=created_by, **user_dict)
238 allowed, reason = pre_create_user(created_by=created_by, **user_dict)
238 if not allowed:
239 if not allowed:
239 raise UserCreationError(reason)
240 raise UserCreationError(reason)
240
241
241
242
242 class ExtensionCallback(object):
243 class ExtensionCallback(object):
243 """
244 """
244 Forwards a given call to rcextensions, sanitizes keyword arguments.
245 Forwards a given call to rcextensions, sanitizes keyword arguments.
245
246
246 Does check if there is an extension active for that hook. If it is
247 Does check if there is an extension active for that hook. If it is
247 there, it will forward all `kwargs_keys` keyword arguments to the
248 there, it will forward all `kwargs_keys` keyword arguments to the
248 extension callback.
249 extension callback.
249 """
250 """
250
251
251 def __init__(self, hook_name, kwargs_keys):
252 def __init__(self, hook_name, kwargs_keys):
252 self._hook_name = hook_name
253 self._hook_name = hook_name
253 self._kwargs_keys = set(kwargs_keys)
254 self._kwargs_keys = set(kwargs_keys)
254
255
255 def __call__(self, *args, **kwargs):
256 def __call__(self, *args, **kwargs):
256 log.debug('Calling extension callback for %s', self._hook_name)
257 log.debug('Calling extension callback for %s', self._hook_name)
257
258
258 kwargs_to_pass = dict((key, kwargs[key]) for key in self._kwargs_keys)
259 kwargs_to_pass = dict((key, kwargs[key]) for key in self._kwargs_keys)
259 callback = self._get_callback()
260 callback = self._get_callback()
260 if callback:
261 if callback:
261 return callback(**kwargs_to_pass)
262 return callback(**kwargs_to_pass)
262 else:
263 else:
263 log.debug('extensions callback not found skipping...')
264 log.debug('extensions callback not found skipping...')
264
265
265 def is_active(self):
266 def is_active(self):
266 return hasattr(rhodecode.EXTENSIONS, self._hook_name)
267 return hasattr(rhodecode.EXTENSIONS, self._hook_name)
267
268
268 def _get_callback(self):
269 def _get_callback(self):
269 return getattr(rhodecode.EXTENSIONS, self._hook_name, None)
270 return getattr(rhodecode.EXTENSIONS, self._hook_name, None)
270
271
271
272
272 pre_pull_extension = ExtensionCallback(
273 pre_pull_extension = ExtensionCallback(
273 hook_name='PRE_PULL_HOOK',
274 hook_name='PRE_PULL_HOOK',
274 kwargs_keys=(
275 kwargs_keys=(
275 'server_url', 'config', 'scm', 'username', 'ip', 'action',
276 'server_url', 'config', 'scm', 'username', 'ip', 'action',
276 'repository'))
277 'repository'))
277
278
278
279
279 post_pull_extension = ExtensionCallback(
280 post_pull_extension = ExtensionCallback(
280 hook_name='PULL_HOOK',
281 hook_name='PULL_HOOK',
281 kwargs_keys=(
282 kwargs_keys=(
282 'server_url', 'config', 'scm', 'username', 'ip', 'action',
283 'server_url', 'config', 'scm', 'username', 'ip', 'action',
283 'repository'))
284 'repository'))
284
285
285
286
286 pre_push_extension = ExtensionCallback(
287 pre_push_extension = ExtensionCallback(
287 hook_name='PRE_PUSH_HOOK',
288 hook_name='PRE_PUSH_HOOK',
288 kwargs_keys=(
289 kwargs_keys=(
289 'server_url', 'config', 'scm', 'username', 'ip', 'action',
290 'server_url', 'config', 'scm', 'username', 'ip', 'action',
290 'repository', 'repo_store_path'))
291 'repository', 'repo_store_path', 'commit_ids'))
291
292
292
293
293 post_push_extension = ExtensionCallback(
294 post_push_extension = ExtensionCallback(
294 hook_name='PUSH_HOOK',
295 hook_name='PUSH_HOOK',
295 kwargs_keys=(
296 kwargs_keys=(
296 'server_url', 'config', 'scm', 'username', 'ip', 'action',
297 'server_url', 'config', 'scm', 'username', 'ip', 'action',
297 'repository', 'repo_store_path', 'pushed_revs'))
298 'repository', 'repo_store_path', 'pushed_revs'))
298
299
299
300
300 pre_create_user = ExtensionCallback(
301 pre_create_user = ExtensionCallback(
301 hook_name='PRE_CREATE_USER_HOOK',
302 hook_name='PRE_CREATE_USER_HOOK',
302 kwargs_keys=(
303 kwargs_keys=(
303 'username', 'password', 'email', 'firstname', 'lastname', 'active',
304 'username', 'password', 'email', 'firstname', 'lastname', 'active',
304 'admin', 'created_by'))
305 'admin', 'created_by'))
305
306
306
307
307 log_create_pull_request = ExtensionCallback(
308 log_create_pull_request = ExtensionCallback(
308 hook_name='CREATE_PULL_REQUEST',
309 hook_name='CREATE_PULL_REQUEST',
309 kwargs_keys=(
310 kwargs_keys=(
310 'server_url', 'config', 'scm', 'username', 'ip', 'action',
311 'server_url', 'config', 'scm', 'username', 'ip', 'action',
311 'repository', 'pull_request_id', 'url', 'title', 'description',
312 'repository', 'pull_request_id', 'url', 'title', 'description',
312 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
313 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
313 'mergeable', 'source', 'target', 'author', 'reviewers'))
314 'mergeable', 'source', 'target', 'author', 'reviewers'))
314
315
315
316
316 log_merge_pull_request = ExtensionCallback(
317 log_merge_pull_request = ExtensionCallback(
317 hook_name='MERGE_PULL_REQUEST',
318 hook_name='MERGE_PULL_REQUEST',
318 kwargs_keys=(
319 kwargs_keys=(
319 'server_url', 'config', 'scm', 'username', 'ip', 'action',
320 'server_url', 'config', 'scm', 'username', 'ip', 'action',
320 'repository', 'pull_request_id', 'url', 'title', 'description',
321 'repository', 'pull_request_id', 'url', 'title', 'description',
321 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
322 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
322 'mergeable', 'source', 'target', 'author', 'reviewers'))
323 'mergeable', 'source', 'target', 'author', 'reviewers'))
323
324
324
325
325 log_close_pull_request = ExtensionCallback(
326 log_close_pull_request = ExtensionCallback(
326 hook_name='CLOSE_PULL_REQUEST',
327 hook_name='CLOSE_PULL_REQUEST',
327 kwargs_keys=(
328 kwargs_keys=(
328 'server_url', 'config', 'scm', 'username', 'ip', 'action',
329 'server_url', 'config', 'scm', 'username', 'ip', 'action',
329 'repository', 'pull_request_id', 'url', 'title', 'description',
330 'repository', 'pull_request_id', 'url', 'title', 'description',
330 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
331 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
331 'mergeable', 'source', 'target', 'author', 'reviewers'))
332 'mergeable', 'source', 'target', 'author', 'reviewers'))
332
333
333
334
334 log_review_pull_request = ExtensionCallback(
335 log_review_pull_request = ExtensionCallback(
335 hook_name='REVIEW_PULL_REQUEST',
336 hook_name='REVIEW_PULL_REQUEST',
336 kwargs_keys=(
337 kwargs_keys=(
337 'server_url', 'config', 'scm', 'username', 'ip', 'action',
338 'server_url', 'config', 'scm', 'username', 'ip', 'action',
338 'repository', 'pull_request_id', 'url', 'title', 'description',
339 'repository', 'pull_request_id', 'url', 'title', 'description',
339 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
340 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
340 'mergeable', 'source', 'target', 'author', 'reviewers'))
341 'mergeable', 'source', 'target', 'author', 'reviewers'))
341
342
342
343
343 log_update_pull_request = ExtensionCallback(
344 log_update_pull_request = ExtensionCallback(
344 hook_name='UPDATE_PULL_REQUEST',
345 hook_name='UPDATE_PULL_REQUEST',
345 kwargs_keys=(
346 kwargs_keys=(
346 'server_url', 'config', 'scm', 'username', 'ip', 'action',
347 'server_url', 'config', 'scm', 'username', 'ip', 'action',
347 'repository', 'pull_request_id', 'url', 'title', 'description',
348 'repository', 'pull_request_id', 'url', 'title', 'description',
348 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
349 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
349 'mergeable', 'source', 'target', 'author', 'reviewers'))
350 'mergeable', 'source', 'target', 'author', 'reviewers'))
350
351
351
352
352 log_create_user = ExtensionCallback(
353 log_create_user = ExtensionCallback(
353 hook_name='CREATE_USER_HOOK',
354 hook_name='CREATE_USER_HOOK',
354 kwargs_keys=(
355 kwargs_keys=(
355 'username', 'full_name_or_username', 'full_contact', 'user_id',
356 'username', 'full_name_or_username', 'full_contact', 'user_id',
356 'name', 'firstname', 'short_contact', 'admin', 'lastname',
357 'name', 'firstname', 'short_contact', 'admin', 'lastname',
357 'ip_addresses', 'extern_type', 'extern_name',
358 'ip_addresses', 'extern_type', 'extern_name',
358 'email', 'api_key', 'api_keys', 'last_login',
359 'email', 'api_key', 'api_keys', 'last_login',
359 'full_name', 'active', 'password', 'emails',
360 'full_name', 'active', 'password', 'emails',
360 'inherit_default_permissions', 'created_by', 'created_on'))
361 'inherit_default_permissions', 'created_by', 'created_on'))
361
362
362
363
363 log_delete_user = ExtensionCallback(
364 log_delete_user = ExtensionCallback(
364 hook_name='DELETE_USER_HOOK',
365 hook_name='DELETE_USER_HOOK',
365 kwargs_keys=(
366 kwargs_keys=(
366 'username', 'full_name_or_username', 'full_contact', 'user_id',
367 'username', 'full_name_or_username', 'full_contact', 'user_id',
367 'name', 'firstname', 'short_contact', 'admin', 'lastname',
368 'name', 'firstname', 'short_contact', 'admin', 'lastname',
368 'ip_addresses',
369 'ip_addresses',
369 'email', 'api_key', 'last_login',
370 'email', 'api_key', 'last_login',
370 'full_name', 'active', 'password', 'emails',
371 'full_name', 'active', 'password', 'emails',
371 'inherit_default_permissions', 'deleted_by'))
372 'inherit_default_permissions', 'deleted_by'))
372
373
373
374
374 log_create_repository = ExtensionCallback(
375 log_create_repository = ExtensionCallback(
375 hook_name='CREATE_REPO_HOOK',
376 hook_name='CREATE_REPO_HOOK',
376 kwargs_keys=(
377 kwargs_keys=(
377 'repo_name', 'repo_type', 'description', 'private', 'created_on',
378 'repo_name', 'repo_type', 'description', 'private', 'created_on',
378 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
379 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
379 'clone_uri', 'fork_id', 'group_id', 'created_by'))
380 'clone_uri', 'fork_id', 'group_id', 'created_by'))
380
381
381
382
382 log_delete_repository = ExtensionCallback(
383 log_delete_repository = ExtensionCallback(
383 hook_name='DELETE_REPO_HOOK',
384 hook_name='DELETE_REPO_HOOK',
384 kwargs_keys=(
385 kwargs_keys=(
385 'repo_name', 'repo_type', 'description', 'private', 'created_on',
386 'repo_name', 'repo_type', 'description', 'private', 'created_on',
386 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
387 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
387 'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on'))
388 'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on'))
388
389
389
390
390 log_create_repository_group = ExtensionCallback(
391 log_create_repository_group = ExtensionCallback(
391 hook_name='CREATE_REPO_GROUP_HOOK',
392 hook_name='CREATE_REPO_GROUP_HOOK',
392 kwargs_keys=(
393 kwargs_keys=(
393 'group_name', 'group_parent_id', 'group_description',
394 'group_name', 'group_parent_id', 'group_description',
394 'group_id', 'user_id', 'created_by', 'created_on',
395 'group_id', 'user_id', 'created_by', 'created_on',
395 'enable_locking'))
396 'enable_locking'))
@@ -1,520 +1,520 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Reference example of the rcextensions module.
22 Reference example of the rcextensions module.
23
23
24 This module is also used during integration tests to verify that all showed
24 This module is also used during integration tests to verify that all showed
25 examples are valid.
25 examples are valid.
26 """
26 """
27
27
28 import collections
28 import collections
29 import os
29 import os
30 import imp
30 import imp
31
31
32 here = os.path.dirname(os.path.abspath(__file__))
32 here = os.path.dirname(os.path.abspath(__file__))
33
33
34
34
35 def load_extension(filename, async=False):
35 def load_extension(filename, async=False):
36 """
36 """
37 use to load extensions inside rcextension folder.
37 use to load extensions inside rcextension folder.
38 for example::
38 for example::
39
39
40 callback = load_extension('email.py', async=False)
40 callback = load_extension('email.py', async=False)
41 if callback:
41 if callback:
42 callback('foobar')
42 callback('foobar')
43
43
44 put file named email.py inside rcextensions folder to load it. Changing
44 put file named email.py inside rcextensions folder to load it. Changing
45 async=True will make the call of the plugin async, it's useful for
45 async=True will make the call of the plugin async, it's useful for
46 blocking calls like sending an email or notification with APIs.
46 blocking calls like sending an email or notification with APIs.
47 """
47 """
48 mod = ''.join(filename.split('.')[:-1])
48 mod = ''.join(filename.split('.')[:-1])
49 loaded = imp.load_source(mod, os.path.join(here, filename))
49 loaded = imp.load_source(mod, os.path.join(here, filename))
50
50
51 callback = getattr(loaded, 'run', None)
51 callback = getattr(loaded, 'run', None)
52 if not callback:
52 if not callback:
53 raise Exception('Plugin missing `run` method')
53 raise Exception('Plugin missing `run` method')
54 if async:
54 if async:
55 # modify callback so it's actually an async call
55 # modify callback so it's actually an async call
56 def _async_callback(*args, **kwargs):
56 def _async_callback(*args, **kwargs):
57 import threading
57 import threading
58 thr = threading.Thread(target=callback, args=args, kwargs=kwargs)
58 thr = threading.Thread(target=callback, args=args, kwargs=kwargs)
59 thr.start()
59 thr.start()
60 if kwargs.get('_async_block'):
60 if kwargs.get('_async_block'):
61 del kwargs['_async_block']
61 del kwargs['_async_block']
62 thr.join()
62 thr.join()
63
63
64 return _async_callback
64 return _async_callback
65 return callback
65 return callback
66
66
67
67
68 # Additional mappings that are not present in the pygments lexers
68 # Additional mappings that are not present in the pygments lexers
69 # used for building stats
69 # used for building stats
70 # format is {'ext':['Names']} eg. {'py':['Python']} note: there can be
70 # format is {'ext':['Names']} eg. {'py':['Python']} note: there can be
71 # more than one name for extension
71 # more than one name for extension
72 # NOTE: that this will overide any mappings in LANGUAGES_EXTENSIONS_MAP
72 # NOTE: that this will override any mappings in LANGUAGES_EXTENSIONS_MAP
73 # build by pygments
73 # build by pygments
74 EXTRA_MAPPINGS = {}
74 EXTRA_MAPPINGS = {}
75
75
76 # additional lexer definitions for custom files it's overrides pygments lexers,
76 # additional lexer definitions for custom files it's overrides pygments lexers,
77 # and uses defined name of lexer to colorize the files. Format is {'ext':
77 # and uses defined name of lexer to colorize the files. Format is {'ext':
78 # 'lexer_name'} List of lexers can be printed running:
78 # 'lexer_name'} List of lexers can be printed running:
79 # >> python -c "import pprint;from pygments import lexers;
79 # >> python -c "import pprint;from pygments import lexers;
80 # pprint.pprint([(x[0], x[1]) for x in lexers.get_all_lexers()]);"
80 # pprint.pprint([(x[0], x[1]) for x in lexers.get_all_lexers()]);"
81
81
82 EXTRA_LEXERS = {}
82 EXTRA_LEXERS = {}
83
83
84
84
85 calls = collections.defaultdict(list)
85 calls = collections.defaultdict(list)
86
86
87
87
88 def log_call(name):
88 def log_call(name):
89 def wrap(f):
89 def wrap(f):
90 def wrapper(*args, **kwargs):
90 def wrapper(*args, **kwargs):
91 calls[name].append((args, kwargs))
91 calls[name].append((args, kwargs))
92 return f(*args, **kwargs)
92 return f(*args, **kwargs)
93 return wrapper
93 return wrapper
94 return wrap
94 return wrap
95
95
96
96
97 # =============================================================================
97 # =============================================================================
98 # POST CREATE REPOSITORY HOOK
98 # POST CREATE REPOSITORY HOOK
99 # =============================================================================
99 # =============================================================================
100 # this function will be executed after each repository is created
100 # this function will be executed after each repository is created
101
101
102
102
103 def _crrepohook(*args, **kwargs):
103 def _crrepohook(*args, **kwargs):
104 """
104 """
105 Post create repository HOOK
105 Post create repository HOOK
106 kwargs available:
106 kwargs available:
107 :param repo_name:
107 :param repo_name:
108 :param repo_type:
108 :param repo_type:
109 :param description:
109 :param description:
110 :param private:
110 :param private:
111 :param created_on:
111 :param created_on:
112 :param enable_downloads:
112 :param enable_downloads:
113 :param repo_id:
113 :param repo_id:
114 :param user_id:
114 :param user_id:
115 :param enable_statistics:
115 :param enable_statistics:
116 :param clone_uri:
116 :param clone_uri:
117 :param fork_id:
117 :param fork_id:
118 :param group_id:
118 :param group_id:
119 :param created_by:
119 :param created_by:
120 """
120 """
121
121
122 expected_parameters = (
122 expected_parameters = (
123 'repo_name', 'repo_type', 'description', 'private', 'created_on',
123 'repo_name', 'repo_type', 'description', 'private', 'created_on',
124 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
124 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
125 'clone_uri', 'fork_id', 'group_id', 'created_by')
125 'clone_uri', 'fork_id', 'group_id', 'created_by')
126 _verify_kwargs(expected_parameters, kwargs)
126 _verify_kwargs(expected_parameters, kwargs)
127
127
128 return 0
128 return 0
129
129
130 CREATE_REPO_HOOK = _crrepohook
130 CREATE_REPO_HOOK = _crrepohook
131
131
132
132
133 # =============================================================================
133 # =============================================================================
134 # POST CREATE REPOSITORY GROUP HOOK
134 # POST CREATE REPOSITORY GROUP HOOK
135 # =============================================================================
135 # =============================================================================
136 # this function will be executed after each repository group is created
136 # this function will be executed after each repository group is created
137
137
138
138
139 def _crrepogrouphook(*args, **kwargs):
139 def _crrepogrouphook(*args, **kwargs):
140 """
140 """
141 Post create repository group HOOK
141 Post create repository group HOOK
142 kwargs available:
142 kwargs available:
143
143
144 :param group_name:
144 :param group_name:
145 :param group_parent_id:
145 :param group_parent_id:
146 :param group_description:
146 :param group_description:
147 :param group_id:
147 :param group_id:
148 :param user_id:
148 :param user_id:
149 :param created_by:
149 :param created_by:
150 :param created_on:
150 :param created_on:
151 :param enable_locking:
151 :param enable_locking:
152 """
152 """
153
153
154 expected_parameters = (
154 expected_parameters = (
155 'group_name', 'group_parent_id', 'group_description',
155 'group_name', 'group_parent_id', 'group_description',
156 'group_id', 'user_id', 'created_by', 'created_on',
156 'group_id', 'user_id', 'created_by', 'created_on',
157 'enable_locking')
157 'enable_locking')
158 _verify_kwargs(expected_parameters, kwargs)
158 _verify_kwargs(expected_parameters, kwargs)
159
159
160 return 0
160 return 0
161
161
162 CREATE_REPO_GROUP_HOOK = _crrepogrouphook
162 CREATE_REPO_GROUP_HOOK = _crrepogrouphook
163
163
164 # =============================================================================
164 # =============================================================================
165 # PRE CREATE USER HOOK
165 # PRE CREATE USER HOOK
166 # =============================================================================
166 # =============================================================================
167 # this function will be executed before each user is created
167 # this function will be executed before each user is created
168
168
169
169
170 def _pre_cruserhook(*args, **kwargs):
170 def _pre_cruserhook(*args, **kwargs):
171 """
171 """
172 Pre create user HOOK, it returns a tuple of bool, reason.
172 Pre create user HOOK, it returns a tuple of bool, reason.
173 If bool is False the user creation will be stopped and reason
173 If bool is False the user creation will be stopped and reason
174 will be displayed to the user.
174 will be displayed to the user.
175 kwargs available:
175 kwargs available:
176 :param username:
176 :param username:
177 :param password:
177 :param password:
178 :param email:
178 :param email:
179 :param firstname:
179 :param firstname:
180 :param lastname:
180 :param lastname:
181 :param active:
181 :param active:
182 :param admin:
182 :param admin:
183 :param created_by:
183 :param created_by:
184 """
184 """
185
185
186 expected_parameters = (
186 expected_parameters = (
187 'username', 'password', 'email', 'firstname', 'lastname', 'active',
187 'username', 'password', 'email', 'firstname', 'lastname', 'active',
188 'admin', 'created_by')
188 'admin', 'created_by')
189 _verify_kwargs(expected_parameters, kwargs)
189 _verify_kwargs(expected_parameters, kwargs)
190
190
191 reason = 'allowed'
191 reason = 'allowed'
192 return True, reason
192 return True, reason
193 PRE_CREATE_USER_HOOK = _pre_cruserhook
193 PRE_CREATE_USER_HOOK = _pre_cruserhook
194
194
195 # =============================================================================
195 # =============================================================================
196 # POST CREATE USER HOOK
196 # POST CREATE USER HOOK
197 # =============================================================================
197 # =============================================================================
198 # this function will be executed after each user is created
198 # this function will be executed after each user is created
199
199
200
200
201 def _cruserhook(*args, **kwargs):
201 def _cruserhook(*args, **kwargs):
202 """
202 """
203 Post create user HOOK
203 Post create user HOOK
204 kwargs available:
204 kwargs available:
205 :param username:
205 :param username:
206 :param full_name_or_username:
206 :param full_name_or_username:
207 :param full_contact:
207 :param full_contact:
208 :param user_id:
208 :param user_id:
209 :param name:
209 :param name:
210 :param firstname:
210 :param firstname:
211 :param short_contact:
211 :param short_contact:
212 :param admin:
212 :param admin:
213 :param lastname:
213 :param lastname:
214 :param ip_addresses:
214 :param ip_addresses:
215 :param extern_type:
215 :param extern_type:
216 :param extern_name:
216 :param extern_name:
217 :param email:
217 :param email:
218 :param api_key:
218 :param api_key:
219 :parma api_keys:
219 :parma api_keys:
220 :param last_login:
220 :param last_login:
221 :param full_name:
221 :param full_name:
222 :param active:
222 :param active:
223 :param password:
223 :param password:
224 :param emails:
224 :param emails:
225 :param inherit_default_permissions:
225 :param inherit_default_permissions:
226 :param created_by:
226 :param created_by:
227 :param created_on:
227 :param created_on:
228 """
228 """
229
229
230 expected_parameters = (
230 expected_parameters = (
231 'username', 'full_name_or_username', 'full_contact', 'user_id',
231 'username', 'full_name_or_username', 'full_contact', 'user_id',
232 'name', 'firstname', 'short_contact', 'admin', 'lastname',
232 'name', 'firstname', 'short_contact', 'admin', 'lastname',
233 'ip_addresses', 'extern_type', 'extern_name',
233 'ip_addresses', 'extern_type', 'extern_name',
234 'email', 'api_key', 'api_keys', 'last_login',
234 'email', 'api_key', 'api_keys', 'last_login',
235 'full_name', 'active', 'password', 'emails',
235 'full_name', 'active', 'password', 'emails',
236 'inherit_default_permissions', 'created_by', 'created_on')
236 'inherit_default_permissions', 'created_by', 'created_on')
237 _verify_kwargs(expected_parameters, kwargs)
237 _verify_kwargs(expected_parameters, kwargs)
238
238
239 return 0
239 return 0
240 CREATE_USER_HOOK = _cruserhook
240 CREATE_USER_HOOK = _cruserhook
241
241
242
242
243 # =============================================================================
243 # =============================================================================
244 # POST DELETE REPOSITORY HOOK
244 # POST DELETE REPOSITORY HOOK
245 # =============================================================================
245 # =============================================================================
246 # this function will be executed after each repository deletion
246 # this function will be executed after each repository deletion
247
247
248
248
249 def _dlrepohook(*args, **kwargs):
249 def _dlrepohook(*args, **kwargs):
250 """
250 """
251 Post delete repository HOOK
251 Post delete repository HOOK
252 kwargs available:
252 kwargs available:
253 :param repo_name:
253 :param repo_name:
254 :param repo_type:
254 :param repo_type:
255 :param description:
255 :param description:
256 :param private:
256 :param private:
257 :param created_on:
257 :param created_on:
258 :param enable_downloads:
258 :param enable_downloads:
259 :param repo_id:
259 :param repo_id:
260 :param user_id:
260 :param user_id:
261 :param enable_statistics:
261 :param enable_statistics:
262 :param clone_uri:
262 :param clone_uri:
263 :param fork_id:
263 :param fork_id:
264 :param group_id:
264 :param group_id:
265 :param deleted_by:
265 :param deleted_by:
266 :param deleted_on:
266 :param deleted_on:
267 """
267 """
268
268
269 expected_parameters = (
269 expected_parameters = (
270 'repo_name', 'repo_type', 'description', 'private', 'created_on',
270 'repo_name', 'repo_type', 'description', 'private', 'created_on',
271 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
271 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
272 'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on')
272 'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on')
273 _verify_kwargs(expected_parameters, kwargs)
273 _verify_kwargs(expected_parameters, kwargs)
274
274
275 return 0
275 return 0
276 DELETE_REPO_HOOK = _dlrepohook
276 DELETE_REPO_HOOK = _dlrepohook
277
277
278
278
279 # =============================================================================
279 # =============================================================================
280 # POST DELETE USER HOOK
280 # POST DELETE USER HOOK
281 # =============================================================================
281 # =============================================================================
282 # this function will be executed after each user is deleted
282 # this function will be executed after each user is deleted
283
283
284
284
285 def _dluserhook(*args, **kwargs):
285 def _dluserhook(*args, **kwargs):
286 """
286 """
287 Post delete user HOOK
287 Post delete user HOOK
288 kwargs available:
288 kwargs available:
289 :param username:
289 :param username:
290 :param full_name_or_username:
290 :param full_name_or_username:
291 :param full_contact:
291 :param full_contact:
292 :param user_id:
292 :param user_id:
293 :param name:
293 :param name:
294 :param firstname:
294 :param firstname:
295 :param short_contact:
295 :param short_contact:
296 :param admin:
296 :param admin:
297 :param lastname:
297 :param lastname:
298 :param ip_addresses:
298 :param ip_addresses:
299 :param ldap_dn:
299 :param ldap_dn:
300 :param email:
300 :param email:
301 :param api_key:
301 :param api_key:
302 :param last_login:
302 :param last_login:
303 :param full_name:
303 :param full_name:
304 :param active:
304 :param active:
305 :param password:
305 :param password:
306 :param emails:
306 :param emails:
307 :param inherit_default_permissions:
307 :param inherit_default_permissions:
308 :param deleted_by:
308 :param deleted_by:
309 """
309 """
310
310
311 expected_parameters = (
311 expected_parameters = (
312 'username', 'full_name_or_username', 'full_contact', 'user_id',
312 'username', 'full_name_or_username', 'full_contact', 'user_id',
313 'name', 'firstname', 'short_contact', 'admin', 'lastname',
313 'name', 'firstname', 'short_contact', 'admin', 'lastname',
314 'ip_addresses',
314 'ip_addresses',
315 # TODO: johbo: Check what's the status with the ldap_dn parameter
315 # TODO: johbo: Check what's the status with the ldap_dn parameter
316 # 'ldap_dn',
316 # 'ldap_dn',
317 'email', 'api_key', 'last_login',
317 'email', 'api_key', 'last_login',
318 'full_name', 'active', 'password', 'emails',
318 'full_name', 'active', 'password', 'emails',
319 'inherit_default_permissions', 'deleted_by')
319 'inherit_default_permissions', 'deleted_by')
320 _verify_kwargs(expected_parameters, kwargs)
320 _verify_kwargs(expected_parameters, kwargs)
321
321
322 return 0
322 return 0
323 DELETE_USER_HOOK = _dluserhook
323 DELETE_USER_HOOK = _dluserhook
324
324
325
325
326 # =============================================================================
326 # =============================================================================
327 # PRE PUSH HOOK
327 # PRE PUSH HOOK
328 # =============================================================================
328 # =============================================================================
329
329
330
330
331 # this function will be executed after each push it's executed after the
331 # this function will be executed after each push it's executed after the
332 # build-in hook that RhodeCode uses for logging pushes
332 # build-in hook that RhodeCode uses for logging pushes
333 @log_call('pre_push')
333 @log_call('pre_push')
334 def _prepushhook(*args, **kwargs):
334 def _prepushhook(*args, **kwargs):
335 """
335 """
336 Pre push hook
336 Pre push hook
337 kwargs available:
337 kwargs available:
338
338
339 :param server_url: url of instance that triggered this hook
339 :param server_url: url of instance that triggered this hook
340 :param config: path to .ini config used
340 :param config: path to .ini config used
341 :param scm: type of VS 'git' or 'hg'
341 :param scm: type of VS 'git' or 'hg'
342 :param username: name of user who pushed
342 :param username: name of user who pushed
343 :param ip: ip of who pushed
343 :param ip: ip of who pushed
344 :param action: push
344 :param action: push
345 :param repository: repository name
345 :param repository: repository name
346 :param repo_store_path: full path to where repositories are stored
346 :param repo_store_path: full path to where repositories are stored
347 """
347 """
348
348
349 expected_parameters = (
349 expected_parameters = (
350 'server_url', 'config', 'scm', 'username', 'ip', 'action',
350 'server_url', 'config', 'scm', 'username', 'ip', 'action',
351 'repository', 'repo_store_path')
351 'repository', 'repo_store_path', 'commit_ids')
352 _verify_kwargs(expected_parameters, kwargs)
352 _verify_kwargs(expected_parameters, kwargs)
353
353
354 return 0
354 return 0
355 PRE_PUSH_HOOK = _prepushhook
355 PRE_PUSH_HOOK = _prepushhook
356
356
357
357
358 # =============================================================================
358 # =============================================================================
359 # POST PUSH HOOK
359 # POST PUSH HOOK
360 # =============================================================================
360 # =============================================================================
361
361
362
362
363 # this function will be executed after each push it's executed after the
363 # this function will be executed after each push it's executed after the
364 # build-in hook that RhodeCode uses for logging pushes
364 # build-in hook that RhodeCode uses for logging pushes
365 @log_call('post_push')
365 @log_call('post_push')
366 def _pushhook(*args, **kwargs):
366 def _pushhook(*args, **kwargs):
367 """
367 """
368 Post push hook
368 Post push hook
369 kwargs available:
369 kwargs available:
370
370
371 :param server_url: url of instance that triggered this hook
371 :param server_url: url of instance that triggered this hook
372 :param config: path to .ini config used
372 :param config: path to .ini config used
373 :param scm: type of VS 'git' or 'hg'
373 :param scm: type of VS 'git' or 'hg'
374 :param username: name of user who pushed
374 :param username: name of user who pushed
375 :param ip: ip of who pushed
375 :param ip: ip of who pushed
376 :param action: push
376 :param action: push
377 :param repository: repository name
377 :param repository: repository name
378 :param repo_store_path: full path to where repositories are stored
378 :param repo_store_path: full path to where repositories are stored
379 :param pushed_revs: list of pushed revisions
379 :param pushed_revs: list of pushed revisions
380 """
380 """
381
381
382 expected_parameters = (
382 expected_parameters = (
383 'server_url', 'config', 'scm', 'username', 'ip', 'action',
383 'server_url', 'config', 'scm', 'username', 'ip', 'action',
384 'repository', 'repo_store_path', 'pushed_revs')
384 'repository', 'repo_store_path', 'pushed_revs')
385 _verify_kwargs(expected_parameters, kwargs)
385 _verify_kwargs(expected_parameters, kwargs)
386
386
387 return 0
387 return 0
388 PUSH_HOOK = _pushhook
388 PUSH_HOOK = _pushhook
389
389
390
390
391 # =============================================================================
391 # =============================================================================
392 # PRE PULL HOOK
392 # PRE PULL HOOK
393 # =============================================================================
393 # =============================================================================
394
394
395 # this function will be executed after each push it's executed after the
395 # this function will be executed after each push it's executed after the
396 # build-in hook that RhodeCode uses for logging pulls
396 # build-in hook that RhodeCode uses for logging pulls
397 def _prepullhook(*args, **kwargs):
397 def _prepullhook(*args, **kwargs):
398 """
398 """
399 Post pull hook
399 Post pull hook
400 kwargs available::
400 kwargs available::
401
401
402 :param server_url: url of instance that triggered this hook
402 :param server_url: url of instance that triggered this hook
403 :param config: path to .ini config used
403 :param config: path to .ini config used
404 :param scm: type of VS 'git' or 'hg'
404 :param scm: type of VS 'git' or 'hg'
405 :param username: name of user who pulled
405 :param username: name of user who pulled
406 :param ip: ip of who pulled
406 :param ip: ip of who pulled
407 :param action: pull
407 :param action: pull
408 :param repository: repository name
408 :param repository: repository name
409 """
409 """
410
410
411 expected_parameters = (
411 expected_parameters = (
412 'server_url', 'config', 'scm', 'username', 'ip', 'action',
412 'server_url', 'config', 'scm', 'username', 'ip', 'action',
413 'repository')
413 'repository')
414 _verify_kwargs(expected_parameters, kwargs)
414 _verify_kwargs(expected_parameters, kwargs)
415
415
416 return 0
416 return 0
417 PRE_PULL_HOOK = _prepullhook
417 PRE_PULL_HOOK = _prepullhook
418
418
419
419
420
420
421 # =============================================================================
421 # =============================================================================
422 # POST PULL HOOK
422 # POST PULL HOOK
423 # =============================================================================
423 # =============================================================================
424
424
425 # this function will be executed after each push it's executed after the
425 # this function will be executed after each push it's executed after the
426 # build-in hook that RhodeCode uses for logging pulls
426 # build-in hook that RhodeCode uses for logging pulls
427 def _pullhook(*args, **kwargs):
427 def _pullhook(*args, **kwargs):
428 """
428 """
429 Post pull hook
429 Post pull hook
430 kwargs available::
430 kwargs available::
431
431
432 :param server_url: url of instance that triggered this hook
432 :param server_url: url of instance that triggered this hook
433 :param config: path to .ini config used
433 :param config: path to .ini config used
434 :param scm: type of VS 'git' or 'hg'
434 :param scm: type of VS 'git' or 'hg'
435 :param username: name of user who pulled
435 :param username: name of user who pulled
436 :param ip: ip of who pulled
436 :param ip: ip of who pulled
437 :param action: pull
437 :param action: pull
438 :param repository: repository name
438 :param repository: repository name
439 """
439 """
440
440
441 expected_parameters = (
441 expected_parameters = (
442 'server_url', 'config', 'scm', 'username', 'ip', 'action',
442 'server_url', 'config', 'scm', 'username', 'ip', 'action',
443 'repository')
443 'repository')
444 _verify_kwargs(expected_parameters, kwargs)
444 _verify_kwargs(expected_parameters, kwargs)
445
445
446 return 0
446 return 0
447 PULL_HOOK = _pullhook
447 PULL_HOOK = _pullhook
448
448
449
449
450 # =============================================================================
450 # =============================================================================
451 # PULL REQUEST RELATED HOOKS
451 # PULL REQUEST RELATED HOOKS
452 # =============================================================================
452 # =============================================================================
453
453
454 def _create_pull_request_hook(*args, **kwargs):
454 def _create_pull_request_hook(*args, **kwargs):
455 expected_parameters = (
455 expected_parameters = (
456 'server_url', 'config', 'scm', 'username', 'ip', 'action',
456 'server_url', 'config', 'scm', 'username', 'ip', 'action',
457 'repository', 'pull_request_id', 'url', 'title', 'description',
457 'repository', 'pull_request_id', 'url', 'title', 'description',
458 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
458 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
459 'mergeable', 'source', 'target', 'author', 'reviewers')
459 'mergeable', 'source', 'target', 'author', 'reviewers')
460 _verify_kwargs(expected_parameters, kwargs)
460 _verify_kwargs(expected_parameters, kwargs)
461 return 0
461 return 0
462 CREATE_PULL_REQUEST = _create_pull_request_hook
462 CREATE_PULL_REQUEST = _create_pull_request_hook
463
463
464
464
465 def _merge_pull_request_hook(*args, **kwargs):
465 def _merge_pull_request_hook(*args, **kwargs):
466 expected_parameters = (
466 expected_parameters = (
467 'server_url', 'config', 'scm', 'username', 'ip', 'action',
467 'server_url', 'config', 'scm', 'username', 'ip', 'action',
468 'repository', 'pull_request_id', 'url', 'title', 'description',
468 'repository', 'pull_request_id', 'url', 'title', 'description',
469 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
469 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
470 'mergeable', 'source', 'target', 'author', 'reviewers')
470 'mergeable', 'source', 'target', 'author', 'reviewers')
471 _verify_kwargs(expected_parameters, kwargs)
471 _verify_kwargs(expected_parameters, kwargs)
472 return 0
472 return 0
473 MERGE_PULL_REQUEST = _merge_pull_request_hook
473 MERGE_PULL_REQUEST = _merge_pull_request_hook
474
474
475
475
476 def _close_pull_request_hook(*args, **kwargs):
476 def _close_pull_request_hook(*args, **kwargs):
477 expected_parameters = (
477 expected_parameters = (
478 'server_url', 'config', 'scm', 'username', 'ip', 'action',
478 'server_url', 'config', 'scm', 'username', 'ip', 'action',
479 'repository', 'pull_request_id', 'url', 'title', 'description',
479 'repository', 'pull_request_id', 'url', 'title', 'description',
480 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
480 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
481 'mergeable', 'source', 'target', 'author', 'reviewers')
481 'mergeable', 'source', 'target', 'author', 'reviewers')
482 _verify_kwargs(expected_parameters, kwargs)
482 _verify_kwargs(expected_parameters, kwargs)
483 return 0
483 return 0
484 CLOSE_PULL_REQUEST = _close_pull_request_hook
484 CLOSE_PULL_REQUEST = _close_pull_request_hook
485
485
486
486
487 def _review_pull_request_hook(*args, **kwargs):
487 def _review_pull_request_hook(*args, **kwargs):
488 expected_parameters = (
488 expected_parameters = (
489 'server_url', 'config', 'scm', 'username', 'ip', 'action',
489 'server_url', 'config', 'scm', 'username', 'ip', 'action',
490 'repository', 'pull_request_id', 'url', 'title', 'description',
490 'repository', 'pull_request_id', 'url', 'title', 'description',
491 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
491 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
492 'mergeable', 'source', 'target', 'author', 'reviewers')
492 'mergeable', 'source', 'target', 'author', 'reviewers')
493 _verify_kwargs(expected_parameters, kwargs)
493 _verify_kwargs(expected_parameters, kwargs)
494 return 0
494 return 0
495 REVIEW_PULL_REQUEST = _review_pull_request_hook
495 REVIEW_PULL_REQUEST = _review_pull_request_hook
496
496
497
497
498 def _update_pull_request_hook(*args, **kwargs):
498 def _update_pull_request_hook(*args, **kwargs):
499 expected_parameters = (
499 expected_parameters = (
500 'server_url', 'config', 'scm', 'username', 'ip', 'action',
500 'server_url', 'config', 'scm', 'username', 'ip', 'action',
501 'repository', 'pull_request_id', 'url', 'title', 'description',
501 'repository', 'pull_request_id', 'url', 'title', 'description',
502 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
502 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
503 'mergeable', 'source', 'target', 'author', 'reviewers')
503 'mergeable', 'source', 'target', 'author', 'reviewers')
504 _verify_kwargs(expected_parameters, kwargs)
504 _verify_kwargs(expected_parameters, kwargs)
505 return 0
505 return 0
506 UPDATE_PULL_REQUEST = _update_pull_request_hook
506 UPDATE_PULL_REQUEST = _update_pull_request_hook
507
507
508
508
509 def _verify_kwargs(expected_parameters, kwargs):
509 def _verify_kwargs(expected_parameters, kwargs):
510 """
510 """
511 Verify that exactly `expected_parameters` are passed in as `kwargs`.
511 Verify that exactly `expected_parameters` are passed in as `kwargs`.
512 """
512 """
513 expected_parameters = set(expected_parameters)
513 expected_parameters = set(expected_parameters)
514 kwargs_keys = set(kwargs.keys())
514 kwargs_keys = set(kwargs.keys())
515 if kwargs_keys != expected_parameters:
515 if kwargs_keys != expected_parameters:
516 missing_kwargs = expected_parameters - kwargs_keys
516 missing_kwargs = expected_parameters - kwargs_keys
517 unexpected_kwargs = kwargs_keys - expected_parameters
517 unexpected_kwargs = kwargs_keys - expected_parameters
518 raise AssertionError(
518 raise AssertionError(
519 "Missing parameters: %r, unexpected parameters: %s" %
519 "rcextensions: Missing parameters: %r, unexpected parameters: %s" %
520 (missing_kwargs, unexpected_kwargs))
520 (missing_kwargs, unexpected_kwargs))
General Comments 0
You need to be logged in to leave comments. Login now