##// END OF EJS Templates
rcextensions: improve example
milka -
r4603:42274a1d stable
parent child Browse files
Show More
@@ -1,120 +1,120 b''
1 1 # Example to validate pushed files names and size using some sort of rules
2 2
3 3
4 4
5 5 @has_kwargs({
6 6 'server_url': 'url of instance that triggered this hook',
7 7 'config': 'path to .ini config used',
8 8 'scm': 'type of version control "git", "hg", "svn"',
9 9 'username': 'username of actor who triggered this event',
10 10 'ip': 'ip address of actor who triggered this hook',
11 11 'action': '',
12 12 'repository': 'repository name',
13 13 'repo_store_path': 'full path to where repositories are stored',
14 14 'commit_ids': 'pre transaction metadata for commit ids',
15 15 'hook_type': '',
16 16 'user_agent': 'Client user agent, e.g git or mercurial CLI version',
17 17 })
18 18 def _pre_push_hook(*args, **kwargs):
19 19 """
20 20 Post push hook
21 21 To stop version control from storing the transaction and send a message to user
22 22 use non-zero HookResponse with a message, e.g return HookResponse(1, 'Not allowed')
23 23
24 24 This message will be shown back to client during PUSH operation
25 25
26 26 Commit ids might look like that::
27 27
28 28 [{u'hg_env|git_env': ...,
29 29 u'multiple_heads': [],
30 30 u'name': u'default',
31 31 u'new_rev': u'd0b2ae0692e722e01d5677f27a104631cf798b69',
32 32 u'old_rev': u'd0b1ae0692e722e01d5677f27a104631cf798b69',
33 33 u'ref': u'',
34 34 u'total_commits': 2,
35 35 u'type': u'branch'}]
36 36 """
37 37 import fnmatch
38 38 from .helpers import extra_fields, extract_pre_files
39 39 from .utils import str2bool, aslist
40 40 from rhodecode.lib.helpers import format_byte_size_binary
41 41
42 42 # returns list of dicts with key-val fetched from extra fields
43 43 repo_extra_fields = extra_fields.run(**kwargs)
44 44
45 45 # optionally use 'extra fields' to control the logic per repo
46 46 # e.g store a list of patterns to be forbidden e.g `*.exe, *.dump`
47 47 forbid_files = extra_fields.get_field(repo_extra_fields, key='forbid_files_glob',
48 48 convert_type=False, default=[])
49 forbid_files = aslist(forbid_files)
49 forbid_files = aslist(forbid_files, sep=',')
50 50
51 51 # forbid_files = ['*'] # example pattern
52 52
53 53 # optionally get bytes limit for a single file, e.g 1024 for 1KB
54 54 forbid_size_over = extra_fields.get_field(repo_extra_fields, key='forbid_size_over',
55 55 convert_type=False, default=0)
56 56
57 57 forbid_size_over = int(forbid_size_over or 0)
58 58
59 59 # forbid_size_over = 1024 # example 1024
60 60
61 61 def validate_file_name_and_size(file_data, forbidden_files=None, size_limit=None):
62 62 """
63 63 This function validates comited files against some sort of rules.
64 64 It should return a valid boolean, and a reason for failure
65 65
66 66 file_data =[
67 67 'raw_diff', 'old_revision', 'stats', 'original_filename', 'is_limited_diff',
68 68 'chunks', 'new_revision', 'operation', 'exceeds_limit', 'filename'
69 69 ]
70 70 file_data['ops'] = {
71 71 # is file binary
72 72 'binary': False,
73 73
74 74 # lines
75 75 'added': 32,
76 76 'deleted': 0
77 77
78 78 'ops': {3: 'modified file'},
79 79 'new_mode': '100644',
80 80 'old_mode': None
81 81 }
82 82 """
83 83 file_name = file_data['filename']
84 84 operation = file_data['operation'] # can be A(dded), M(odified), D(eleted)
85 85
86 86 # check files names
87 87 if forbidden_files:
88 88 reason = 'File {} is forbidden to be pushed'.format(file_name)
89 89 for forbidden_pattern in forbid_files:
90 90 # here we can also filter for operation, e.g if check for only ADDED files
91 91 # if operation == 'A':
92 92 if fnmatch.fnmatch(file_name, forbidden_pattern):
93 93 return False, reason
94 94
95 95 # validate A(dded) files and size
96 96 if size_limit and operation == 'A':
97 97 if 'file_size' in file_data:
98 98 size = file_data['file_size']
99 99 else:
100 100 size = len(file_data['raw_diff'])
101 101
102 102 reason = 'File {} size of {} bytes exceeds limit {}'.format(
103 103 file_name, format_byte_size_binary(size),
104 104 format_byte_size_binary(size_limit))
105 105 if size > size_limit:
106 106 return False, reason
107 107
108 108 return True, ''
109 109
110 110 if forbid_files or forbid_size_over:
111 111 # returns list of dicts with key-val fetched from extra fields
112 112 file_list = extract_pre_files.run(**kwargs)
113 113
114 114 for file_data in file_list:
115 115 file_valid, reason = validate_file_name_and_size(
116 116 file_data, forbid_files, forbid_size_over)
117 117 if not file_valid:
118 118 return HookResponse(1, reason)
119 119
120 120 return HookResponse(0, '')
General Comments 0
You need to be logged in to leave comments. Login now