##// END OF EJS Templates
hooks: do not crash when hook files are empty
marcink -
r691:c982b816 default
parent child Browse files
Show More
@@ -1,203 +1,205 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # RhodeCode VCSServer provides access to different vcs backends via network.
3 # RhodeCode VCSServer provides access to different vcs backends via network.
4 # Copyright (C) 2014-2019 RhodeCode GmbH
4 # Copyright (C) 2014-2019 RhodeCode GmbH
5 #
5 #
6 # This program is free software; you can redistribute it and/or modify
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
9 # (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software Foundation,
17 # along with this program; if not, write to the Free Software Foundation,
18 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
19
20 import re
20 import re
21 import os
21 import os
22 import sys
22 import sys
23 import datetime
23 import datetime
24 import logging
24 import logging
25 import pkg_resources
25 import pkg_resources
26
26
27 import vcsserver
27 import vcsserver
28
28
29 log = logging.getLogger(__name__)
29 log = logging.getLogger(__name__)
30
30
31
31
32 def get_git_hooks_path(repo_path, bare):
32 def get_git_hooks_path(repo_path, bare):
33 hooks_path = os.path.join(repo_path, 'hooks')
33 hooks_path = os.path.join(repo_path, 'hooks')
34 if not bare:
34 if not bare:
35 hooks_path = os.path.join(repo_path, '.git', 'hooks')
35 hooks_path = os.path.join(repo_path, '.git', 'hooks')
36
36
37 return hooks_path
37 return hooks_path
38
38
39
39
40 def install_git_hooks(repo_path, bare, executable=None, force_create=False):
40 def install_git_hooks(repo_path, bare, executable=None, force_create=False):
41 """
41 """
42 Creates a RhodeCode hook inside a git repository
42 Creates a RhodeCode hook inside a git repository
43
43
44 :param repo_path: path to repository
44 :param repo_path: path to repository
45 :param executable: binary executable to put in the hooks
45 :param executable: binary executable to put in the hooks
46 :param force_create: Create even if same name hook exists
46 :param force_create: Create even if same name hook exists
47 """
47 """
48 executable = executable or sys.executable
48 executable = executable or sys.executable
49 hooks_path = get_git_hooks_path(repo_path, bare)
49 hooks_path = get_git_hooks_path(repo_path, bare)
50
50
51 if not os.path.isdir(hooks_path):
51 if not os.path.isdir(hooks_path):
52 os.makedirs(hooks_path, mode=0o777)
52 os.makedirs(hooks_path, mode=0o777)
53
53
54 tmpl_post = pkg_resources.resource_string(
54 tmpl_post = pkg_resources.resource_string(
55 'vcsserver', '/'.join(
55 'vcsserver', '/'.join(
56 ('hook_utils', 'hook_templates', 'git_post_receive.py.tmpl')))
56 ('hook_utils', 'hook_templates', 'git_post_receive.py.tmpl')))
57 tmpl_pre = pkg_resources.resource_string(
57 tmpl_pre = pkg_resources.resource_string(
58 'vcsserver', '/'.join(
58 'vcsserver', '/'.join(
59 ('hook_utils', 'hook_templates', 'git_pre_receive.py.tmpl')))
59 ('hook_utils', 'hook_templates', 'git_pre_receive.py.tmpl')))
60
60
61 path = '' # not used for now
61 path = '' # not used for now
62 timestamp = datetime.datetime.utcnow().isoformat()
62 timestamp = datetime.datetime.utcnow().isoformat()
63
63
64 for h_type, template in [('pre', tmpl_pre), ('post', tmpl_post)]:
64 for h_type, template in [('pre', tmpl_pre), ('post', tmpl_post)]:
65 log.debug('Installing git hook in repo %s', repo_path)
65 log.debug('Installing git hook in repo %s', repo_path)
66 _hook_file = os.path.join(hooks_path, '%s-receive' % h_type)
66 _hook_file = os.path.join(hooks_path, '%s-receive' % h_type)
67 _rhodecode_hook = check_rhodecode_hook(_hook_file)
67 _rhodecode_hook = check_rhodecode_hook(_hook_file)
68
68
69 if _rhodecode_hook or force_create:
69 if _rhodecode_hook or force_create:
70 log.debug('writing git %s hook file at %s !', h_type, _hook_file)
70 log.debug('writing git %s hook file at %s !', h_type, _hook_file)
71 try:
71 try:
72 with open(_hook_file, 'wb') as f:
72 with open(_hook_file, 'wb') as f:
73 template = template.replace(
73 template = template.replace(
74 '_TMPL_', vcsserver.__version__)
74 '_TMPL_', vcsserver.__version__)
75 template = template.replace('_DATE_', timestamp)
75 template = template.replace('_DATE_', timestamp)
76 template = template.replace('_ENV_', executable)
76 template = template.replace('_ENV_', executable)
77 template = template.replace('_PATH_', path)
77 template = template.replace('_PATH_', path)
78 f.write(template)
78 f.write(template)
79 os.chmod(_hook_file, 0o755)
79 os.chmod(_hook_file, 0o755)
80 except IOError:
80 except IOError:
81 log.exception('error writing hook file %s', _hook_file)
81 log.exception('error writing hook file %s', _hook_file)
82 else:
82 else:
83 log.debug('skipping writing hook file')
83 log.debug('skipping writing hook file')
84
84
85 return True
85 return True
86
86
87
87
88 def get_svn_hooks_path(repo_path):
88 def get_svn_hooks_path(repo_path):
89 hooks_path = os.path.join(repo_path, 'hooks')
89 hooks_path = os.path.join(repo_path, 'hooks')
90
90
91 return hooks_path
91 return hooks_path
92
92
93
93
94 def install_svn_hooks(repo_path, executable=None, force_create=False):
94 def install_svn_hooks(repo_path, executable=None, force_create=False):
95 """
95 """
96 Creates RhodeCode hooks inside a svn repository
96 Creates RhodeCode hooks inside a svn repository
97
97
98 :param repo_path: path to repository
98 :param repo_path: path to repository
99 :param executable: binary executable to put in the hooks
99 :param executable: binary executable to put in the hooks
100 :param force_create: Create even if same name hook exists
100 :param force_create: Create even if same name hook exists
101 """
101 """
102 executable = executable or sys.executable
102 executable = executable or sys.executable
103 hooks_path = get_svn_hooks_path(repo_path)
103 hooks_path = get_svn_hooks_path(repo_path)
104 if not os.path.isdir(hooks_path):
104 if not os.path.isdir(hooks_path):
105 os.makedirs(hooks_path, mode=0o777)
105 os.makedirs(hooks_path, mode=0o777)
106
106
107 tmpl_post = pkg_resources.resource_string(
107 tmpl_post = pkg_resources.resource_string(
108 'vcsserver', '/'.join(
108 'vcsserver', '/'.join(
109 ('hook_utils', 'hook_templates', 'svn_post_commit_hook.py.tmpl')))
109 ('hook_utils', 'hook_templates', 'svn_post_commit_hook.py.tmpl')))
110 tmpl_pre = pkg_resources.resource_string(
110 tmpl_pre = pkg_resources.resource_string(
111 'vcsserver', '/'.join(
111 'vcsserver', '/'.join(
112 ('hook_utils', 'hook_templates', 'svn_pre_commit_hook.py.tmpl')))
112 ('hook_utils', 'hook_templates', 'svn_pre_commit_hook.py.tmpl')))
113
113
114 path = '' # not used for now
114 path = '' # not used for now
115 timestamp = datetime.datetime.utcnow().isoformat()
115 timestamp = datetime.datetime.utcnow().isoformat()
116
116
117 for h_type, template in [('pre', tmpl_pre), ('post', tmpl_post)]:
117 for h_type, template in [('pre', tmpl_pre), ('post', tmpl_post)]:
118 log.debug('Installing svn hook in repo %s', repo_path)
118 log.debug('Installing svn hook in repo %s', repo_path)
119 _hook_file = os.path.join(hooks_path, '%s-commit' % h_type)
119 _hook_file = os.path.join(hooks_path, '%s-commit' % h_type)
120 _rhodecode_hook = check_rhodecode_hook(_hook_file)
120 _rhodecode_hook = check_rhodecode_hook(_hook_file)
121
121
122 if _rhodecode_hook or force_create:
122 if _rhodecode_hook or force_create:
123 log.debug('writing svn %s hook file at %s !', h_type, _hook_file)
123 log.debug('writing svn %s hook file at %s !', h_type, _hook_file)
124
124
125 try:
125 try:
126 with open(_hook_file, 'wb') as f:
126 with open(_hook_file, 'wb') as f:
127 template = template.replace(
127 template = template.replace(
128 '_TMPL_', vcsserver.__version__)
128 '_TMPL_', vcsserver.__version__)
129 template = template.replace('_DATE_', timestamp)
129 template = template.replace('_DATE_', timestamp)
130 template = template.replace('_ENV_', executable)
130 template = template.replace('_ENV_', executable)
131 template = template.replace('_PATH_', path)
131 template = template.replace('_PATH_', path)
132
132
133 f.write(template)
133 f.write(template)
134 os.chmod(_hook_file, 0o755)
134 os.chmod(_hook_file, 0o755)
135 except IOError:
135 except IOError:
136 log.exception('error writing hook file %s', _hook_file)
136 log.exception('error writing hook file %s', _hook_file)
137 else:
137 else:
138 log.debug('skipping writing hook file')
138 log.debug('skipping writing hook file')
139
139
140 return True
140 return True
141
141
142
142
143 def get_version_from_hook(hook_path):
143 def get_version_from_hook(hook_path):
144 version = ''
144 version = ''
145 hook_content = read_hook_content(hook_path)
145 hook_content = read_hook_content(hook_path)
146 matches = re.search(r'(?:RC_HOOK_VER)\s*=\s*(.*)', hook_content)
146 matches = re.search(r'(?:RC_HOOK_VER)\s*=\s*(.*)', hook_content)
147 if matches:
147 if matches:
148 try:
148 try:
149 version = matches.groups()[0]
149 version = matches.groups()[0]
150 log.debug('got version %s from hooks.', version)
150 log.debug('got version %s from hooks.', version)
151 except Exception:
151 except Exception:
152 log.exception("Exception while reading the hook version.")
152 log.exception("Exception while reading the hook version.")
153 return version.replace("'", "")
153 return version.replace("'", "")
154
154
155
155
156 def check_rhodecode_hook(hook_path):
156 def check_rhodecode_hook(hook_path):
157 """
157 """
158 Check if the hook was created by RhodeCode
158 Check if the hook was created by RhodeCode
159 """
159 """
160 if not os.path.exists(hook_path):
160 if not os.path.exists(hook_path):
161 return True
161 return True
162
162
163 log.debug('hook exists, checking if it is from RhodeCode')
163 log.debug('hook exists, checking if it is from RhodeCode')
164
164
165 version = get_version_from_hook(hook_path)
165 version = get_version_from_hook(hook_path)
166 if version:
166 if version:
167 return True
167 return True
168
168
169 return False
169 return False
170
170
171
171
172 def read_hook_content(hook_path):
172 def read_hook_content(hook_path):
173 content = ''
174 if os.path.isfile(hook_path):
173 with open(hook_path, 'rb') as f:
175 with open(hook_path, 'rb') as f:
174 content = f.read()
176 content = f.read()
175 return content
177 return content
176
178
177
179
178 def get_git_pre_hook_version(repo_path, bare):
180 def get_git_pre_hook_version(repo_path, bare):
179 hooks_path = get_git_hooks_path(repo_path, bare)
181 hooks_path = get_git_hooks_path(repo_path, bare)
180 _hook_file = os.path.join(hooks_path, 'pre-receive')
182 _hook_file = os.path.join(hooks_path, 'pre-receive')
181 version = get_version_from_hook(_hook_file)
183 version = get_version_from_hook(_hook_file)
182 return version
184 return version
183
185
184
186
185 def get_git_post_hook_version(repo_path, bare):
187 def get_git_post_hook_version(repo_path, bare):
186 hooks_path = get_git_hooks_path(repo_path, bare)
188 hooks_path = get_git_hooks_path(repo_path, bare)
187 _hook_file = os.path.join(hooks_path, 'post-receive')
189 _hook_file = os.path.join(hooks_path, 'post-receive')
188 version = get_version_from_hook(_hook_file)
190 version = get_version_from_hook(_hook_file)
189 return version
191 return version
190
192
191
193
192 def get_svn_pre_hook_version(repo_path):
194 def get_svn_pre_hook_version(repo_path):
193 hooks_path = get_svn_hooks_path(repo_path)
195 hooks_path = get_svn_hooks_path(repo_path)
194 _hook_file = os.path.join(hooks_path, 'pre-commit')
196 _hook_file = os.path.join(hooks_path, 'pre-commit')
195 version = get_version_from_hook(_hook_file)
197 version = get_version_from_hook(_hook_file)
196 return version
198 return version
197
199
198
200
199 def get_svn_post_hook_version(repo_path):
201 def get_svn_post_hook_version(repo_path):
200 hooks_path = get_svn_hooks_path(repo_path)
202 hooks_path = get_svn_hooks_path(repo_path)
201 _hook_file = os.path.join(hooks_path, 'post-commit')
203 _hook_file = os.path.join(hooks_path, 'post-commit')
202 version = get_version_from_hook(_hook_file)
204 version = get_version_from_hook(_hook_file)
203 return version
205 return version
General Comments 0
You need to be logged in to leave comments. Login now