##// END OF EJS Templates
rcextensions: added logging for basic function calls
marcink -
r3921:36433cb7 default
parent child Browse files
Show More
@@ -1,431 +1,432 b''
1 # Copyright (C) 2016-2019 RhodeCode GmbH
1 # Copyright (C) 2016-2019 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
5 # (only), as published by the Free Software Foundation.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU Affero General Public License
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
14 #
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18 import logging
19 from .utils import DotDict, HookResponse, has_kwargs
19 from .utils import DotDict, HookResponse, has_kwargs
20 log = logging.getLogger('rhodecode.' + __name__)
20
21
21
22
22 # Config shortcut to keep, all configuration in one place
23 # Config shortcut to keep, all configuration in one place
23 # Example: api_key = CONFIG.my_config.api_key
24 # Example: api_key = CONFIG.my_config.api_key
24 CONFIG = DotDict(
25 CONFIG = DotDict(
25 my_config=DotDict(
26 my_config=DotDict(
26 api_key='<secret>',
27 api_key='<secret>',
27 ),
28 ),
28
29
29 )
30 )
30
31
31
32
32 @has_kwargs({
33 @has_kwargs({
33 'repo_name': '',
34 'repo_name': '',
34 'repo_type': '',
35 'repo_type': '',
35 'description': '',
36 'description': '',
36 'private': '',
37 'private': '',
37 'created_on': '',
38 'created_on': '',
38 'enable_downloads': '',
39 'enable_downloads': '',
39 'repo_id': '',
40 'repo_id': '',
40 'user_id': '',
41 'user_id': '',
41 'enable_statistics': '',
42 'enable_statistics': '',
42 'clone_uri': '',
43 'clone_uri': '',
43 'fork_id': '',
44 'fork_id': '',
44 'group_id': '',
45 'group_id': '',
45 'created_by': ''
46 'created_by': ''
46 })
47 })
47 def _create_repo_hook(*args, **kwargs):
48 def _create_repo_hook(*args, **kwargs):
48 """
49 """
49 POST CREATE REPOSITORY HOOK. This function will be executed after
50 POST CREATE REPOSITORY HOOK. This function will be executed after
50 each repository is created. kwargs available:
51 each repository is created. kwargs available:
51
52
52 """
53 """
53 return HookResponse(0, '')
54 return HookResponse(0, '')
54
55
55
56
56 @has_kwargs({
57 @has_kwargs({
57 'group_name': '',
58 'group_name': '',
58 'group_parent_id': '',
59 'group_parent_id': '',
59 'group_description': '',
60 'group_description': '',
60 'group_id': '',
61 'group_id': '',
61 'user_id': '',
62 'user_id': '',
62 'created_by': '',
63 'created_by': '',
63 'created_on': '',
64 'created_on': '',
64 'enable_locking': ''
65 'enable_locking': ''
65 })
66 })
66 def _create_repo_group_hook(*args, **kwargs):
67 def _create_repo_group_hook(*args, **kwargs):
67 """
68 """
68 POST CREATE REPOSITORY GROUP HOOK, this function will be
69 POST CREATE REPOSITORY GROUP HOOK, this function will be
69 executed after each repository group is created. kwargs available:
70 executed after each repository group is created. kwargs available:
70 """
71 """
71 return HookResponse(0, '')
72 return HookResponse(0, '')
72
73
73
74
74 @has_kwargs({
75 @has_kwargs({
75 'username': '',
76 'username': '',
76 'password': '',
77 'password': '',
77 'email': '',
78 'email': '',
78 'firstname': '',
79 'firstname': '',
79 'lastname': '',
80 'lastname': '',
80 'active': '',
81 'active': '',
81 'admin': '',
82 'admin': '',
82 'created_by': '',
83 'created_by': '',
83 })
84 })
84 def _pre_create_user_hook(*args, **kwargs):
85 def _pre_create_user_hook(*args, **kwargs):
85 """
86 """
86 PRE CREATE USER HOOK, this function will be executed before each
87 PRE CREATE USER HOOK, this function will be executed before each
87 user is created, it returns a tuple of bool, reason.
88 user is created, it returns a tuple of bool, reason.
88 If bool is False the user creation will be stopped and reason
89 If bool is False the user creation will be stopped and reason
89 will be displayed to the user.
90 will be displayed to the user.
90
91
91 Return HookResponse(1, reason) to block user creation
92 Return HookResponse(1, reason) to block user creation
92
93
93 """
94 """
94
95
95 reason = 'allowed'
96 reason = 'allowed'
96 return HookResponse(0, reason)
97 return HookResponse(0, reason)
97
98
98
99
99 @has_kwargs({
100 @has_kwargs({
100 'username': '',
101 'username': '',
101 'full_name_or_username': '',
102 'full_name_or_username': '',
102 'full_contact': '',
103 'full_contact': '',
103 'user_id': '',
104 'user_id': '',
104 'name': '',
105 'name': '',
105 'firstname': '',
106 'firstname': '',
106 'short_contact': '',
107 'short_contact': '',
107 'admin': '',
108 'admin': '',
108 'lastname': '',
109 'lastname': '',
109 'ip_addresses': '',
110 'ip_addresses': '',
110 'extern_type': '',
111 'extern_type': '',
111 'extern_name': '',
112 'extern_name': '',
112 'email': '',
113 'email': '',
113 'api_key': '',
114 'api_key': '',
114 'api_keys': '',
115 'api_keys': '',
115 'last_login': '',
116 'last_login': '',
116 'full_name': '',
117 'full_name': '',
117 'active': '',
118 'active': '',
118 'password': '',
119 'password': '',
119 'emails': '',
120 'emails': '',
120 'inherit_default_permissions': '',
121 'inherit_default_permissions': '',
121 'created_by': '',
122 'created_by': '',
122 'created_on': '',
123 'created_on': '',
123 })
124 })
124 def _create_user_hook(*args, **kwargs):
125 def _create_user_hook(*args, **kwargs):
125 """
126 """
126 POST CREATE USER HOOK, this function will be executed after each user is created
127 POST CREATE USER HOOK, this function will be executed after each user is created
127 """
128 """
128 return HookResponse(0, '')
129 return HookResponse(0, '')
129
130
130
131
131 @has_kwargs({
132 @has_kwargs({
132 'repo_name': '',
133 'repo_name': '',
133 'repo_type': '',
134 'repo_type': '',
134 'description': '',
135 'description': '',
135 'private': '',
136 'private': '',
136 'created_on': '',
137 'created_on': '',
137 'enable_downloads': '',
138 'enable_downloads': '',
138 'repo_id': '',
139 'repo_id': '',
139 'user_id': '',
140 'user_id': '',
140 'enable_statistics': '',
141 'enable_statistics': '',
141 'clone_uri': '',
142 'clone_uri': '',
142 'fork_id': '',
143 'fork_id': '',
143 'group_id': '',
144 'group_id': '',
144 'deleted_by': '',
145 'deleted_by': '',
145 'deleted_on': '',
146 'deleted_on': '',
146 })
147 })
147 def _delete_repo_hook(*args, **kwargs):
148 def _delete_repo_hook(*args, **kwargs):
148 """
149 """
149 POST DELETE REPOSITORY HOOK, this function will be executed after
150 POST DELETE REPOSITORY HOOK, this function will be executed after
150 each repository deletion
151 each repository deletion
151 """
152 """
152 return HookResponse(0, '')
153 return HookResponse(0, '')
153
154
154
155
155 @has_kwargs({
156 @has_kwargs({
156 'username': '',
157 'username': '',
157 'full_name_or_username': '',
158 'full_name_or_username': '',
158 'full_contact': '',
159 'full_contact': '',
159 'user_id': '',
160 'user_id': '',
160 'name': '',
161 'name': '',
161 'short_contact': '',
162 'short_contact': '',
162 'admin': '',
163 'admin': '',
163 'firstname': '',
164 'firstname': '',
164 'lastname': '',
165 'lastname': '',
165 'ip_addresses': '',
166 'ip_addresses': '',
166 'email': '',
167 'email': '',
167 'api_key': '',
168 'api_key': '',
168 'last_login': '',
169 'last_login': '',
169 'full_name': '',
170 'full_name': '',
170 'active': '',
171 'active': '',
171 'password': '',
172 'password': '',
172 'emails': '',
173 'emails': '',
173 'inherit_default_permissions': '',
174 'inherit_default_permissions': '',
174 'deleted_by': '',
175 'deleted_by': '',
175 })
176 })
176 def _delete_user_hook(*args, **kwargs):
177 def _delete_user_hook(*args, **kwargs):
177 """
178 """
178 POST DELETE USER HOOK, this function will be executed after each
179 POST DELETE USER HOOK, this function will be executed after each
179 user is deleted kwargs available:
180 user is deleted kwargs available:
180 """
181 """
181 return HookResponse(0, '')
182 return HookResponse(0, '')
182
183
183
184
184 # =============================================================================
185 # =============================================================================
185 # PUSH/PULL RELATED HOOKS
186 # PUSH/PULL RELATED HOOKS
186 # =============================================================================
187 # =============================================================================
187 @has_kwargs({
188 @has_kwargs({
188 'server_url': 'url of instance that triggered this hook',
189 'server_url': 'url of instance that triggered this hook',
189 'config': 'path to .ini config used',
190 'config': 'path to .ini config used',
190 'scm': 'type of version control "git", "hg", "svn"',
191 'scm': 'type of version control "git", "hg", "svn"',
191 'username': 'username of actor who triggered this event',
192 'username': 'username of actor who triggered this event',
192 'ip': 'ip address of actor who triggered this hook',
193 'ip': 'ip address of actor who triggered this hook',
193 'action': '',
194 'action': '',
194 'repository': 'repository name',
195 'repository': 'repository name',
195 'repo_store_path': 'full path to where repositories are stored',
196 'repo_store_path': 'full path to where repositories are stored',
196 'commit_ids': 'pre transaction metadata for commit ids',
197 'commit_ids': 'pre transaction metadata for commit ids',
197 'hook_type': '',
198 'hook_type': '',
198 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
199 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
199 })
200 })
200 def _pre_push_hook(*args, **kwargs):
201 def _pre_push_hook(*args, **kwargs):
201 """
202 """
202 Post push hook
203 Post push hook
203 To stop version control from storing the transaction and send a message to user
204 To stop version control from storing the transaction and send a message to user
204 use non-zero HookResponse with a message, e.g return HookResponse(1, 'Not allowed')
205 use non-zero HookResponse with a message, e.g return HookResponse(1, 'Not allowed')
205
206
206 This message will be shown back to client during PUSH operation
207 This message will be shown back to client during PUSH operation
207
208
208 Commit ids might look like that::
209 Commit ids might look like that::
209
210
210 [{u'hg_env|git_env': ...,
211 [{u'hg_env|git_env': ...,
211 u'multiple_heads': [],
212 u'multiple_heads': [],
212 u'name': u'default',
213 u'name': u'default',
213 u'new_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
214 u'new_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
214 u'old_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
215 u'old_rev': u'd0befe0692e722e01d5677f27a104631cf798b69',
215 u'ref': u'',
216 u'ref': u'',
216 u'total_commits': 2,
217 u'total_commits': 2,
217 u'type': u'branch'}]
218 u'type': u'branch'}]
218 """
219 """
219 return HookResponse(0, '')
220 return HookResponse(0, '')
220
221
221
222
222 @has_kwargs({
223 @has_kwargs({
223 'server_url': 'url of instance that triggered this hook',
224 'server_url': 'url of instance that triggered this hook',
224 'config': 'path to .ini config used',
225 'config': 'path to .ini config used',
225 'scm': 'type of version control "git", "hg", "svn"',
226 'scm': 'type of version control "git", "hg", "svn"',
226 'username': 'username of actor who triggered this event',
227 'username': 'username of actor who triggered this event',
227 'ip': 'ip address of actor who triggered this hook',
228 'ip': 'ip address of actor who triggered this hook',
228 'action': '',
229 'action': '',
229 'repository': 'repository name',
230 'repository': 'repository name',
230 'repo_store_path': 'full path to where repositories are stored',
231 'repo_store_path': 'full path to where repositories are stored',
231 'commit_ids': 'list of pushed commit_ids (sha1)',
232 'commit_ids': 'list of pushed commit_ids (sha1)',
232 'hook_type': '',
233 'hook_type': '',
233 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
234 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
234 })
235 })
235 def _push_hook(*args, **kwargs):
236 def _push_hook(*args, **kwargs):
236 """
237 """
237 POST PUSH HOOK, this function will be executed after each push it's
238 POST PUSH HOOK, this function will be executed after each push it's
238 executed after the build-in hook that RhodeCode uses for logging pushes
239 executed after the build-in hook that RhodeCode uses for logging pushes
239 """
240 """
240 return HookResponse(0, '')
241 return HookResponse(0, '')
241
242
242
243
243 @has_kwargs({
244 @has_kwargs({
244 'server_url': 'url of instance that triggered this hook',
245 'server_url': 'url of instance that triggered this hook',
245 'repo_store_path': 'full path to where repositories are stored',
246 'repo_store_path': 'full path to where repositories are stored',
246 'config': 'path to .ini config used',
247 'config': 'path to .ini config used',
247 'scm': 'type of version control "git", "hg", "svn"',
248 'scm': 'type of version control "git", "hg", "svn"',
248 'username': 'username of actor who triggered this event',
249 'username': 'username of actor who triggered this event',
249 'ip': 'ip address of actor who triggered this hook',
250 'ip': 'ip address of actor who triggered this hook',
250 'action': '',
251 'action': '',
251 'repository': 'repository name',
252 'repository': 'repository name',
252 'hook_type': '',
253 'hook_type': '',
253 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
254 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
254 })
255 })
255 def _pre_pull_hook(*args, **kwargs):
256 def _pre_pull_hook(*args, **kwargs):
256 """
257 """
257 Post pull hook
258 Post pull hook
258 """
259 """
259 return HookResponse(0, '')
260 return HookResponse(0, '')
260
261
261
262
262 @has_kwargs({
263 @has_kwargs({
263 'server_url': 'url of instance that triggered this hook',
264 'server_url': 'url of instance that triggered this hook',
264 'repo_store_path': 'full path to where repositories are stored',
265 'repo_store_path': 'full path to where repositories are stored',
265 'config': 'path to .ini config used',
266 'config': 'path to .ini config used',
266 'scm': 'type of version control "git", "hg", "svn"',
267 'scm': 'type of version control "git", "hg", "svn"',
267 'username': 'username of actor who triggered this event',
268 'username': 'username of actor who triggered this event',
268 'ip': 'ip address of actor who triggered this hook',
269 'ip': 'ip address of actor who triggered this hook',
269 'action': '',
270 'action': '',
270 'repository': 'repository name',
271 'repository': 'repository name',
271 'hook_type': '',
272 'hook_type': '',
272 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
273 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
273 })
274 })
274 def _pull_hook(*args, **kwargs):
275 def _pull_hook(*args, **kwargs):
275 """
276 """
276 This hook will be executed after each code pull.
277 This hook will be executed after each code pull.
277 """
278 """
278 return HookResponse(0, '')
279 return HookResponse(0, '')
279
280
280
281
281 # =============================================================================
282 # =============================================================================
282 # PULL REQUEST RELATED HOOKS
283 # PULL REQUEST RELATED HOOKS
283 # =============================================================================
284 # =============================================================================
284 @has_kwargs({
285 @has_kwargs({
285 'server_url': 'url of instance that triggered this hook',
286 'server_url': 'url of instance that triggered this hook',
286 'config': 'path to .ini config used',
287 'config': 'path to .ini config used',
287 'scm': 'type of version control "git", "hg", "svn"',
288 'scm': 'type of version control "git", "hg", "svn"',
288 'username': 'username of actor who triggered this event',
289 'username': 'username of actor who triggered this event',
289 'ip': 'ip address of actor who triggered this hook',
290 'ip': 'ip address of actor who triggered this hook',
290 'action': '',
291 'action': '',
291 'repository': 'repository name',
292 'repository': 'repository name',
292 'pull_request_id': '',
293 'pull_request_id': '',
293 'url': '',
294 'url': '',
294 'title': '',
295 'title': '',
295 'description': '',
296 'description': '',
296 'status': '',
297 'status': '',
297 'created_on': '',
298 'created_on': '',
298 'updated_on': '',
299 'updated_on': '',
299 'commit_ids': '',
300 'commit_ids': '',
300 'review_status': '',
301 'review_status': '',
301 'mergeable': '',
302 'mergeable': '',
302 'source': '',
303 'source': '',
303 'target': '',
304 'target': '',
304 'author': '',
305 'author': '',
305 'reviewers': '',
306 'reviewers': '',
306 })
307 })
307 def _create_pull_request_hook(*args, **kwargs):
308 def _create_pull_request_hook(*args, **kwargs):
308 """
309 """
309 This hook will be executed after creation of a pull request.
310 This hook will be executed after creation of a pull request.
310 """
311 """
311 return HookResponse(0, '')
312 return HookResponse(0, '')
312
313
313
314
314 @has_kwargs({
315 @has_kwargs({
315 'server_url': 'url of instance that triggered this hook',
316 'server_url': 'url of instance that triggered this hook',
316 'config': 'path to .ini config used',
317 'config': 'path to .ini config used',
317 'scm': 'type of version control "git", "hg", "svn"',
318 'scm': 'type of version control "git", "hg", "svn"',
318 'username': 'username of actor who triggered this event',
319 'username': 'username of actor who triggered this event',
319 'ip': 'ip address of actor who triggered this hook',
320 'ip': 'ip address of actor who triggered this hook',
320 'action': '',
321 'action': '',
321 'repository': 'repository name',
322 'repository': 'repository name',
322 'pull_request_id': '',
323 'pull_request_id': '',
323 'url': '',
324 'url': '',
324 'title': '',
325 'title': '',
325 'description': '',
326 'description': '',
326 'status': '',
327 'status': '',
327 'created_on': '',
328 'created_on': '',
328 'updated_on': '',
329 'updated_on': '',
329 'commit_ids': '',
330 'commit_ids': '',
330 'review_status': '',
331 'review_status': '',
331 'mergeable': '',
332 'mergeable': '',
332 'source': '',
333 'source': '',
333 'target': '',
334 'target': '',
334 'author': '',
335 'author': '',
335 'reviewers': '',
336 'reviewers': '',
336 })
337 })
337 def _review_pull_request_hook(*args, **kwargs):
338 def _review_pull_request_hook(*args, **kwargs):
338 """
339 """
339 This hook will be executed after review action was made on a pull request.
340 This hook will be executed after review action was made on a pull request.
340 """
341 """
341 return HookResponse(0, '')
342 return HookResponse(0, '')
342
343
343
344
344 @has_kwargs({
345 @has_kwargs({
345 'server_url': 'url of instance that triggered this hook',
346 'server_url': 'url of instance that triggered this hook',
346 'config': 'path to .ini config used',
347 'config': 'path to .ini config used',
347 'scm': 'type of version control "git", "hg", "svn"',
348 'scm': 'type of version control "git", "hg", "svn"',
348 'username': 'username of actor who triggered this event',
349 'username': 'username of actor who triggered this event',
349 'ip': 'ip address of actor who triggered this hook',
350 'ip': 'ip address of actor who triggered this hook',
350 'action': '',
351 'action': '',
351 'repository': 'repository name',
352 'repository': 'repository name',
352 'pull_request_id': '',
353 'pull_request_id': '',
353 'url': '',
354 'url': '',
354 'title': '',
355 'title': '',
355 'description': '',
356 'description': '',
356 'status': '',
357 'status': '',
357 'created_on': '',
358 'created_on': '',
358 'updated_on': '',
359 'updated_on': '',
359 'commit_ids': '',
360 'commit_ids': '',
360 'review_status': '',
361 'review_status': '',
361 'mergeable': '',
362 'mergeable': '',
362 'source': '',
363 'source': '',
363 'target': '',
364 'target': '',
364 'author': '',
365 'author': '',
365 'reviewers': '',
366 'reviewers': '',
366 })
367 })
367 def _update_pull_request_hook(*args, **kwargs):
368 def _update_pull_request_hook(*args, **kwargs):
368 """
369 """
369 This hook will be executed after pull requests has been updated with new commits.
370 This hook will be executed after pull requests has been updated with new commits.
370 """
371 """
371 return HookResponse(0, '')
372 return HookResponse(0, '')
372
373
373
374
374 @has_kwargs({
375 @has_kwargs({
375 'server_url': 'url of instance that triggered this hook',
376 'server_url': 'url of instance that triggered this hook',
376 'config': 'path to .ini config used',
377 'config': 'path to .ini config used',
377 'scm': 'type of version control "git", "hg", "svn"',
378 'scm': 'type of version control "git", "hg", "svn"',
378 'username': 'username of actor who triggered this event',
379 'username': 'username of actor who triggered this event',
379 'ip': 'ip address of actor who triggered this hook',
380 'ip': 'ip address of actor who triggered this hook',
380 'action': '',
381 'action': '',
381 'repository': 'repository name',
382 'repository': 'repository name',
382 'pull_request_id': '',
383 'pull_request_id': '',
383 'url': '',
384 'url': '',
384 'title': '',
385 'title': '',
385 'description': '',
386 'description': '',
386 'status': '',
387 'status': '',
387 'created_on': '',
388 'created_on': '',
388 'updated_on': '',
389 'updated_on': '',
389 'commit_ids': '',
390 'commit_ids': '',
390 'review_status': '',
391 'review_status': '',
391 'mergeable': '',
392 'mergeable': '',
392 'source': '',
393 'source': '',
393 'target': '',
394 'target': '',
394 'author': '',
395 'author': '',
395 'reviewers': '',
396 'reviewers': '',
396 })
397 })
397 def _merge_pull_request_hook(*args, **kwargs):
398 def _merge_pull_request_hook(*args, **kwargs):
398 """
399 """
399 This hook will be executed after merge of a pull request.
400 This hook will be executed after merge of a pull request.
400 """
401 """
401 return HookResponse(0, '')
402 return HookResponse(0, '')
402
403
403
404
404 @has_kwargs({
405 @has_kwargs({
405 'server_url': 'url of instance that triggered this hook',
406 'server_url': 'url of instance that triggered this hook',
406 'config': 'path to .ini config used',
407 'config': 'path to .ini config used',
407 'scm': 'type of version control "git", "hg", "svn"',
408 'scm': 'type of version control "git", "hg", "svn"',
408 'username': 'username of actor who triggered this event',
409 'username': 'username of actor who triggered this event',
409 'ip': 'ip address of actor who triggered this hook',
410 'ip': 'ip address of actor who triggered this hook',
410 'action': '',
411 'action': '',
411 'repository': 'repository name',
412 'repository': 'repository name',
412 'pull_request_id': '',
413 'pull_request_id': '',
413 'url': '',
414 'url': '',
414 'title': '',
415 'title': '',
415 'description': '',
416 'description': '',
416 'status': '',
417 'status': '',
417 'created_on': '',
418 'created_on': '',
418 'updated_on': '',
419 'updated_on': '',
419 'commit_ids': '',
420 'commit_ids': '',
420 'review_status': '',
421 'review_status': '',
421 'mergeable': '',
422 'mergeable': '',
422 'source': '',
423 'source': '',
423 'target': '',
424 'target': '',
424 'author': '',
425 'author': '',
425 'reviewers': '',
426 'reviewers': '',
426 })
427 })
427 def _close_pull_request_hook(*args, **kwargs):
428 def _close_pull_request_hook(*args, **kwargs):
428 """
429 """
429 This hook will be executed after close of a pull request.
430 This hook will be executed after close of a pull request.
430 """
431 """
431 return HookResponse(0, '')
432 return HookResponse(0, '')
@@ -1,185 +1,189 b''
1 # Copyright (C) 2016-2019 RhodeCode GmbH
1 # Copyright (C) 2016-2019 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
5 # (only), as published by the Free Software Foundation.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU Affero General Public License
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
14 #
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 import logging
19 import os
20 import os
20 import functools
21 import functools
21 import collections
22 import collections
22
23
24 log = logging.getLogger('rhodecode.' + __name__)
25
23
26
24 class HookResponse(object):
27 class HookResponse(object):
25 def __init__(self, status, output):
28 def __init__(self, status, output):
26 self.status = status
29 self.status = status
27 self.output = output
30 self.output = output
28
31
29 def __add__(self, other):
32 def __add__(self, other):
30 other_status = getattr(other, 'status', 0)
33 other_status = getattr(other, 'status', 0)
31 new_status = max(self.status, other_status)
34 new_status = max(self.status, other_status)
32 other_output = getattr(other, 'output', '')
35 other_output = getattr(other, 'output', '')
33 new_output = self.output + other_output
36 new_output = self.output + other_output
34
37
35 return HookResponse(new_status, new_output)
38 return HookResponse(new_status, new_output)
36
39
37 def __bool__(self):
40 def __bool__(self):
38 return self.status == 0
41 return self.status == 0
39
42
40
43
41 class DotDict(dict):
44 class DotDict(dict):
42
45
43 def __contains__(self, k):
46 def __contains__(self, k):
44 try:
47 try:
45 return dict.__contains__(self, k) or hasattr(self, k)
48 return dict.__contains__(self, k) or hasattr(self, k)
46 except:
49 except:
47 return False
50 return False
48
51
49 # only called if k not found in normal places
52 # only called if k not found in normal places
50 def __getattr__(self, k):
53 def __getattr__(self, k):
51 try:
54 try:
52 return object.__getattribute__(self, k)
55 return object.__getattribute__(self, k)
53 except AttributeError:
56 except AttributeError:
54 try:
57 try:
55 return self[k]
58 return self[k]
56 except KeyError:
59 except KeyError:
57 raise AttributeError(k)
60 raise AttributeError(k)
58
61
59 def __setattr__(self, k, v):
62 def __setattr__(self, k, v):
60 try:
63 try:
61 object.__getattribute__(self, k)
64 object.__getattribute__(self, k)
62 except AttributeError:
65 except AttributeError:
63 try:
66 try:
64 self[k] = v
67 self[k] = v
65 except:
68 except:
66 raise AttributeError(k)
69 raise AttributeError(k)
67 else:
70 else:
68 object.__setattr__(self, k, v)
71 object.__setattr__(self, k, v)
69
72
70 def __delattr__(self, k):
73 def __delattr__(self, k):
71 try:
74 try:
72 object.__getattribute__(self, k)
75 object.__getattribute__(self, k)
73 except AttributeError:
76 except AttributeError:
74 try:
77 try:
75 del self[k]
78 del self[k]
76 except KeyError:
79 except KeyError:
77 raise AttributeError(k)
80 raise AttributeError(k)
78 else:
81 else:
79 object.__delattr__(self, k)
82 object.__delattr__(self, k)
80
83
81 def toDict(self):
84 def toDict(self):
82 return unserialize(self)
85 return unserialize(self)
83
86
84 def __repr__(self):
87 def __repr__(self):
85 keys = list(self.keys())
88 keys = list(self.keys())
86 keys.sort()
89 keys.sort()
87 args = ', '.join(['%s=%r' % (key, self[key]) for key in keys])
90 args = ', '.join(['%s=%r' % (key, self[key]) for key in keys])
88 return '%s(%s)' % (self.__class__.__name__, args)
91 return '%s(%s)' % (self.__class__.__name__, args)
89
92
90 @staticmethod
93 @staticmethod
91 def fromDict(d):
94 def fromDict(d):
92 return serialize(d)
95 return serialize(d)
93
96
94
97
95 def serialize(x):
98 def serialize(x):
96 if isinstance(x, dict):
99 if isinstance(x, dict):
97 return DotDict((k, serialize(v)) for k, v in x.items())
100 return DotDict((k, serialize(v)) for k, v in x.items())
98 elif isinstance(x, (list, tuple)):
101 elif isinstance(x, (list, tuple)):
99 return type(x)(serialize(v) for v in x)
102 return type(x)(serialize(v) for v in x)
100 else:
103 else:
101 return x
104 return x
102
105
103
106
104 def unserialize(x):
107 def unserialize(x):
105 if isinstance(x, dict):
108 if isinstance(x, dict):
106 return dict((k, unserialize(v)) for k, v in x.items())
109 return dict((k, unserialize(v)) for k, v in x.items())
107 elif isinstance(x, (list, tuple)):
110 elif isinstance(x, (list, tuple)):
108 return type(x)(unserialize(v) for v in x)
111 return type(x)(unserialize(v) for v in x)
109 else:
112 else:
110 return x
113 return x
111
114
112
115
113 def _verify_kwargs(func_name, expected_parameters, kwargs):
116 def _verify_kwargs(func_name, expected_parameters, kwargs):
114 """
117 """
115 Verify that exactly `expected_parameters` are passed in as `kwargs`.
118 Verify that exactly `expected_parameters` are passed in as `kwargs`.
116 """
119 """
117 expected_parameters = set(expected_parameters)
120 expected_parameters = set(expected_parameters)
118 kwargs_keys = set(kwargs.keys())
121 kwargs_keys = set(kwargs.keys())
119 if kwargs_keys != expected_parameters:
122 if kwargs_keys != expected_parameters:
120 missing_kwargs = expected_parameters - kwargs_keys
123 missing_kwargs = expected_parameters - kwargs_keys
121 unexpected_kwargs = kwargs_keys - expected_parameters
124 unexpected_kwargs = kwargs_keys - expected_parameters
122 raise AssertionError(
125 raise AssertionError(
123 "func:%s: missing parameters: %r, unexpected parameters: %s" %
126 "func:%s: missing parameters: %r, unexpected parameters: %s" %
124 (func_name, missing_kwargs, unexpected_kwargs))
127 (func_name, missing_kwargs, unexpected_kwargs))
125
128
126
129
127 def has_kwargs(required_args):
130 def has_kwargs(required_args):
128 """
131 """
129 decorator to verify extension calls arguments.
132 decorator to verify extension calls arguments.
130
133
131 :param required_args:
134 :param required_args:
132 """
135 """
133 def wrap(func):
136 def wrap(func):
134 def wrapper(*args, **kwargs):
137 def wrapper(*args, **kwargs):
135 _verify_kwargs(func.func_name, required_args.keys(), kwargs)
138 _verify_kwargs(func.func_name, required_args.keys(), kwargs)
136 # in case there's `calls` defined on module we store the data
139 # in case there's `calls` defined on module we store the data
137 maybe_log_call(func.func_name, args, kwargs)
140 maybe_log_call(func.func_name, args, kwargs)
141 log.debug('Calling rcextensions function %s', func.func_name)
138 return func(*args, **kwargs)
142 return func(*args, **kwargs)
139 return wrapper
143 return wrapper
140 return wrap
144 return wrap
141
145
142
146
143 def maybe_log_call(name, args, kwargs):
147 def maybe_log_call(name, args, kwargs):
144 from rhodecode.config import rcextensions
148 from rhodecode.config import rcextensions
145 if hasattr(rcextensions, 'calls'):
149 if hasattr(rcextensions, 'calls'):
146 calls = rcextensions.calls
150 calls = rcextensions.calls
147 calls[name].append((args, kwargs))
151 calls[name].append((args, kwargs))
148
152
149
153
150 def str2bool(_str):
154 def str2bool(_str):
151 """
155 """
152 returns True/False value from given string, it tries to translate the
156 returns True/False value from given string, it tries to translate the
153 string into boolean
157 string into boolean
154
158
155 :param _str: string value to translate into boolean
159 :param _str: string value to translate into boolean
156 :rtype: boolean
160 :rtype: boolean
157 :returns: boolean from given string
161 :returns: boolean from given string
158 """
162 """
159 if _str is None:
163 if _str is None:
160 return False
164 return False
161 if _str in (True, False):
165 if _str in (True, False):
162 return _str
166 return _str
163 _str = str(_str).strip().lower()
167 _str = str(_str).strip().lower()
164 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
168 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
165
169
166
170
167 def aslist(obj, sep=None, strip=True):
171 def aslist(obj, sep=None, strip=True):
168 """
172 """
169 Returns given string separated by sep as list
173 Returns given string separated by sep as list
170
174
171 :param obj:
175 :param obj:
172 :param sep:
176 :param sep:
173 :param strip:
177 :param strip:
174 """
178 """
175 if isinstance(obj, (basestring,)):
179 if isinstance(obj, (basestring,)):
176 lst = obj.split(sep)
180 lst = obj.split(sep)
177 if strip:
181 if strip:
178 lst = [v.strip() for v in lst]
182 lst = [v.strip() for v in lst]
179 return lst
183 return lst
180 elif isinstance(obj, (list, tuple)):
184 elif isinstance(obj, (list, tuple)):
181 return obj
185 return obj
182 elif obj is None:
186 elif obj is None:
183 return []
187 return []
184 else:
188 else:
185 return [obj] No newline at end of file
189 return [obj]
General Comments 0
You need to be logged in to leave comments. Login now