##// END OF EJS Templates
release: Merge default into stable for release preparation
marcink -
r411:ce60257b merge stable
parent child Browse files
Show More
@@ -0,0 +1,20 b''
1 diff -rup Beaker-1.9.1-orig/beaker/container.py Beaker-1.9.1/beaker/container.py
2 --- Beaker-1.9.1-orig/beaker/container.py 2018-04-10 10:23:04.000000000 +0200
3 +++ Beaker-1.9.1/beaker/container.py 2018-04-10 10:23:34.000000000 +0200
4 @@ -353,13 +353,13 @@ class Value(object):
5 debug("get_value returning old value while new one is created")
6 return value
7 else:
8 - debug("lock_creatfunc (didnt wait)")
9 + debug("lock_creatfunc `%s` (didnt wait)", self.createfunc.__name__)
10 has_createlock = True
11
12 if not has_createlock:
13 - debug("lock_createfunc (waiting)")
14 + debug("lock_createfunc `%s` (waiting)", self.createfunc.__name__)
15 creation_lock.acquire()
16 - debug("lock_createfunc (waited)")
17 + debug("lock_createfunc `%s` (waited)", self.createfunc.__name__)
18
19 try:
20 # see if someone created the value already
@@ -0,0 +1,154 b''
1 # -*- coding: utf-8 -*-
2
3 # RhodeCode VCSServer provides access to different vcs backends via network.
4 # Copyright (C) 2014-2018 RhodeCode GmbH
5 #
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
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
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,
18 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
20 import re
21 import os
22 import sys
23 import datetime
24 import logging
25 import pkg_resources
26
27 import vcsserver
28
29 log = logging.getLogger(__name__)
30
31
32 def install_git_hooks(repo_path, bare, executable=None, force_create=False):
33 """
34 Creates a RhodeCode hook inside a git repository
35
36 :param repo_path: path to repository
37 :param executable: binary executable to put in the hooks
38 :param force_create: Create even if same name hook exists
39 """
40 executable = executable or sys.executable
41 hooks_path = os.path.join(repo_path, 'hooks')
42 if not bare:
43 hooks_path = os.path.join(repo_path, '.git', 'hooks')
44 if not os.path.isdir(hooks_path):
45 os.makedirs(hooks_path, mode=0777)
46
47 tmpl_post = pkg_resources.resource_string(
48 'vcsserver', '/'.join(
49 ('hook_utils', 'hook_templates', 'git_post_receive.py.tmpl')))
50 tmpl_pre = pkg_resources.resource_string(
51 'vcsserver', '/'.join(
52 ('hook_utils', 'hook_templates', 'git_pre_receive.py.tmpl')))
53
54 path = '' # not used for now
55 timestamp = datetime.datetime.utcnow().isoformat()
56
57 for h_type, template in [('pre', tmpl_pre), ('post', tmpl_post)]:
58 log.debug('Installing git hook in repo %s', repo_path)
59 _hook_file = os.path.join(hooks_path, '%s-receive' % h_type)
60 _rhodecode_hook = check_rhodecode_hook(_hook_file)
61
62 if _rhodecode_hook or force_create:
63 log.debug('writing git %s hook file at %s !', h_type, _hook_file)
64 try:
65 with open(_hook_file, 'wb') as f:
66 template = template.replace(
67 '_TMPL_', vcsserver.__version__)
68 template = template.replace('_DATE_', timestamp)
69 template = template.replace('_ENV_', executable)
70 template = template.replace('_PATH_', path)
71 f.write(template)
72 os.chmod(_hook_file, 0755)
73 except IOError:
74 log.exception('error writing hook file %s', _hook_file)
75 else:
76 log.debug('skipping writing hook file')
77
78 return True
79
80
81 def install_svn_hooks(repo_path, executable=None, force_create=False):
82 """
83 Creates RhodeCode hooks inside a svn repository
84
85 :param repo_path: path to repository
86 :param executable: binary executable to put in the hooks
87 :param force_create: Create even if same name hook exists
88 """
89 executable = executable or sys.executable
90 hooks_path = os.path.join(repo_path, 'hooks')
91 if not os.path.isdir(hooks_path):
92 os.makedirs(hooks_path, mode=0777)
93
94 tmpl_post = pkg_resources.resource_string(
95 'vcsserver', '/'.join(
96 ('hook_utils', 'hook_templates', 'svn_post_commit_hook.py.tmpl')))
97 tmpl_pre = pkg_resources.resource_string(
98 'vcsserver', '/'.join(
99 ('hook_utils', 'hook_templates', 'svn_pre_commit_hook.py.tmpl')))
100
101 path = '' # not used for now
102 timestamp = datetime.datetime.utcnow().isoformat()
103
104 for h_type, template in [('pre', tmpl_pre), ('post', tmpl_post)]:
105 log.debug('Installing svn hook in repo %s', repo_path)
106 _hook_file = os.path.join(hooks_path, '%s-commit' % h_type)
107 _rhodecode_hook = check_rhodecode_hook(_hook_file)
108
109 if _rhodecode_hook or force_create:
110 log.debug('writing svn %s hook file at %s !', h_type, _hook_file)
111
112 try:
113 with open(_hook_file, 'wb') as f:
114 template = template.replace(
115 '_TMPL_', vcsserver.__version__)
116 template = template.replace('_DATE_', timestamp)
117 template = template.replace('_ENV_', executable)
118 template = template.replace('_PATH_', path)
119
120 f.write(template)
121 os.chmod(_hook_file, 0755)
122 except IOError:
123 log.exception('error writing hook file %s', _hook_file)
124 else:
125 log.debug('skipping writing hook file')
126
127 return True
128
129
130 def check_rhodecode_hook(hook_path):
131 """
132 Check if the hook was created by RhodeCode
133 """
134 if not os.path.exists(hook_path):
135 return True
136
137 log.debug('hook exists, checking if it is from rhodecode')
138 hook_content = read_hook_content(hook_path)
139 matches = re.search(r'(?:RC_HOOK_VER)\s*=\s*(.*)', hook_content)
140 if matches:
141 try:
142 version = matches.groups()[0]
143 log.debug('got version %s from hooks.', version)
144 return True
145 except Exception:
146 log.exception("Exception while reading the hook version.")
147
148 return False
149
150
151 def read_hook_content(hook_path):
152 with open(hook_path, 'rb') as f:
153 content = f.read()
154 return content
@@ -0,0 +1,51 b''
1 #!_ENV_
2 import os
3 import sys
4 path_adjust = [_PATH_]
5
6 if path_adjust:
7 sys.path = path_adjust
8
9 try:
10 from vcsserver import hooks
11 except ImportError:
12 if os.environ.get('RC_DEBUG_GIT_HOOK'):
13 import traceback
14 print traceback.format_exc()
15 hooks = None
16
17
18 # TIMESTAMP: _DATE_
19 RC_HOOK_VER = '_TMPL_'
20
21
22 def main():
23 if hooks is None:
24 # exit with success if we cannot import vcsserver.hooks !!
25 # this allows simply push to this repo even without rhodecode
26 sys.exit(0)
27
28 if os.environ.get('RC_SKIP_HOOKS'):
29 sys.exit(0)
30
31 repo_path = os.getcwd()
32 push_data = sys.stdin.readlines()
33 os.environ['RC_HOOK_VER'] = RC_HOOK_VER
34 # os.environ is modified here by a subprocess call that
35 # runs git and later git executes this hook.
36 # Environ gets some additional info from rhodecode system
37 # like IP or username from basic-auth
38 try:
39 result = hooks.git_post_receive(repo_path, push_data, os.environ)
40 sys.exit(result)
41 except Exception as error:
42 # TODO: johbo: Improve handling of this special case
43 if not getattr(error, '_vcs_kind', None) == 'repo_locked':
44 raise
45 print 'ERROR:', error
46 sys.exit(1)
47 sys.exit(0)
48
49
50 if __name__ == '__main__':
51 main()
@@ -0,0 +1,51 b''
1 #!_ENV_
2 import os
3 import sys
4 path_adjust = [_PATH_]
5
6 if path_adjust:
7 sys.path = path_adjust
8
9 try:
10 from vcsserver import hooks
11 except ImportError:
12 if os.environ.get('RC_DEBUG_GIT_HOOK'):
13 import traceback
14 print traceback.format_exc()
15 hooks = None
16
17
18 # TIMESTAMP: _DATE_
19 RC_HOOK_VER = '_TMPL_'
20
21
22 def main():
23 if hooks is None:
24 # exit with success if we cannot import vcsserver.hooks !!
25 # this allows simply push to this repo even without rhodecode
26 sys.exit(0)
27
28 if os.environ.get('RC_SKIP_HOOKS'):
29 sys.exit(0)
30
31 repo_path = os.getcwd()
32 push_data = sys.stdin.readlines()
33 os.environ['RC_HOOK_VER'] = RC_HOOK_VER
34 # os.environ is modified here by a subprocess call that
35 # runs git and later git executes this hook.
36 # Environ gets some additional info from rhodecode system
37 # like IP or username from basic-auth
38 try:
39 result = hooks.git_pre_receive(repo_path, push_data, os.environ)
40 sys.exit(result)
41 except Exception as error:
42 # TODO: johbo: Improve handling of this special case
43 if not getattr(error, '_vcs_kind', None) == 'repo_locked':
44 raise
45 print 'ERROR:', error
46 sys.exit(1)
47 sys.exit(0)
48
49
50 if __name__ == '__main__':
51 main()
@@ -0,0 +1,50 b''
1 #!_ENV_
2
3 import os
4 import sys
5 path_adjust = [_PATH_]
6
7 if path_adjust:
8 sys.path = path_adjust
9
10 try:
11 from vcsserver import hooks
12 except ImportError:
13 if os.environ.get('RC_DEBUG_SVN_HOOK'):
14 import traceback
15 print traceback.format_exc()
16 hooks = None
17
18
19 # TIMESTAMP: _DATE_
20 RC_HOOK_VER = '_TMPL_'
21
22
23 def main():
24 if hooks is None:
25 # exit with success if we cannot import vcsserver.hooks !!
26 # this allows simply push to this repo even without rhodecode
27 sys.exit(0)
28
29 if os.environ.get('RC_SKIP_HOOKS'):
30 sys.exit(0)
31 repo_path = os.getcwd()
32 push_data = sys.argv[1:]
33
34 os.environ['RC_HOOK_VER'] = RC_HOOK_VER
35
36 try:
37 result = hooks.svn_post_commit(repo_path, push_data, os.environ)
38 sys.exit(result)
39 except Exception as error:
40 # TODO: johbo: Improve handling of this special case
41 if not getattr(error, '_vcs_kind', None) == 'repo_locked':
42 raise
43 print 'ERROR:', error
44 sys.exit(1)
45 sys.exit(0)
46
47
48
49 if __name__ == '__main__':
50 main()
@@ -0,0 +1,52 b''
1 #!_ENV_
2
3 import os
4 import sys
5 path_adjust = [_PATH_]
6
7 if path_adjust:
8 sys.path = path_adjust
9
10 try:
11 from vcsserver import hooks
12 except ImportError:
13 if os.environ.get('RC_DEBUG_SVN_HOOK'):
14 import traceback
15 print traceback.format_exc()
16 hooks = None
17
18
19 # TIMESTAMP: _DATE_
20 RC_HOOK_VER = '_TMPL_'
21
22
23 def main():
24 if os.environ.get('SSH_READ_ONLY') == '1':
25 sys.stderr.write('Only read-only access is allowed')
26 sys.exit(1)
27
28 if hooks is None:
29 # exit with success if we cannot import vcsserver.hooks !!
30 # this allows simply push to this repo even without rhodecode
31 sys.exit(0)
32 if os.environ.get('RC_SKIP_HOOKS'):
33 sys.exit(0)
34 repo_path = os.getcwd()
35 push_data = sys.argv[1:]
36
37 os.environ['RC_HOOK_VER'] = RC_HOOK_VER
38
39 try:
40 result = hooks.svn_pre_commit(repo_path, push_data, os.environ)
41 sys.exit(result)
42 except Exception as error:
43 # TODO: johbo: Improve handling of this special case
44 if not getattr(error, '_vcs_kind', None) == 'repo_locked':
45 raise
46 print 'ERROR:', error
47 sys.exit(1)
48 sys.exit(0)
49
50
51 if __name__ == '__main__':
52 main()
@@ -0,0 +1,16 b''
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2018 RhodeCode GmbH
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -0,0 +1,206 b''
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2018 RhodeCode GmbH
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18 import os
19 import sys
20 import stat
21 import pytest
22 import vcsserver
23 import tempfile
24 from vcsserver import hook_utils
25 from vcsserver.tests.fixture import no_newline_id_generator
26 from vcsserver.utils import AttributeDict
27
28
29 class TestCheckRhodecodeHook(object):
30
31 def test_returns_false_when_hook_file_is_wrong_found(self, tmpdir):
32 hook = os.path.join(str(tmpdir), 'fake_hook_file.py')
33 with open(hook, 'wb') as f:
34 f.write('dummy test')
35 result = hook_utils.check_rhodecode_hook(hook)
36 assert result is False
37
38 def test_returns_true_when_no_hook_file_found(self, tmpdir):
39 hook = os.path.join(str(tmpdir), 'fake_hook_file_not_existing.py')
40 result = hook_utils.check_rhodecode_hook(hook)
41 assert result
42
43 @pytest.mark.parametrize("file_content, expected_result", [
44 ("RC_HOOK_VER = '3.3.3'\n", True),
45 ("RC_HOOK = '3.3.3'\n", False),
46 ], ids=no_newline_id_generator)
47 def test_signatures(self, file_content, expected_result, tmpdir):
48 hook = os.path.join(str(tmpdir), 'fake_hook_file_1.py')
49 with open(hook, 'wb') as f:
50 f.write(file_content)
51
52 result = hook_utils.check_rhodecode_hook(hook)
53
54 assert result is expected_result
55
56
57 class BaseInstallHooks(object):
58 HOOK_FILES = ()
59
60 def _check_hook_file_mode(self, file_path):
61 assert os.path.exists(file_path), 'path %s missing' % file_path
62 stat_info = os.stat(file_path)
63
64 file_mode = stat.S_IMODE(stat_info.st_mode)
65 expected_mode = int('755', 8)
66 assert expected_mode == file_mode
67
68 def _check_hook_file_content(self, file_path, executable):
69 executable = executable or sys.executable
70 with open(file_path, 'rt') as hook_file:
71 content = hook_file.read()
72
73 expected_env = '#!{}'.format(executable)
74 expected_rc_version = "\nRC_HOOK_VER = '{}'\n".format(
75 vcsserver.__version__)
76 assert content.strip().startswith(expected_env)
77 assert expected_rc_version in content
78
79 def _create_fake_hook(self, file_path, content):
80 with open(file_path, 'w') as hook_file:
81 hook_file.write(content)
82
83 def create_dummy_repo(self, repo_type):
84 tmpdir = tempfile.mkdtemp()
85 repo = AttributeDict()
86 if repo_type == 'git':
87 repo.path = os.path.join(tmpdir, 'test_git_hooks_installation_repo')
88 os.makedirs(repo.path)
89 os.makedirs(os.path.join(repo.path, 'hooks'))
90 repo.bare = True
91
92 elif repo_type == 'svn':
93 repo.path = os.path.join(tmpdir, 'test_svn_hooks_installation_repo')
94 os.makedirs(repo.path)
95 os.makedirs(os.path.join(repo.path, 'hooks'))
96
97 return repo
98
99 def check_hooks(self, repo_path, repo_bare=True):
100 for file_name in self.HOOK_FILES:
101 if repo_bare:
102 file_path = os.path.join(repo_path, 'hooks', file_name)
103 else:
104 file_path = os.path.join(repo_path, '.git', 'hooks', file_name)
105 self._check_hook_file_mode(file_path)
106 self._check_hook_file_content(file_path, sys.executable)
107
108
109 class TestInstallGitHooks(BaseInstallHooks):
110 HOOK_FILES = ('pre-receive', 'post-receive')
111
112 def test_hooks_are_installed(self):
113 repo = self.create_dummy_repo('git')
114 result = hook_utils.install_git_hooks(repo.path, repo.bare)
115 assert result
116 self.check_hooks(repo.path, repo.bare)
117
118 def test_hooks_are_replaced(self):
119 repo = self.create_dummy_repo('git')
120 hooks_path = os.path.join(repo.path, 'hooks')
121 for file_path in [os.path.join(hooks_path, f) for f in self.HOOK_FILES]:
122 self._create_fake_hook(
123 file_path, content="RC_HOOK_VER = 'abcde'\n")
124
125 result = hook_utils.install_git_hooks(repo.path, repo.bare)
126 assert result
127 self.check_hooks(repo.path, repo.bare)
128
129 def test_non_rc_hooks_are_not_replaced(self):
130 repo = self.create_dummy_repo('git')
131 hooks_path = os.path.join(repo.path, 'hooks')
132 non_rc_content = 'echo "non rc hook"\n'
133 for file_path in [os.path.join(hooks_path, f) for f in self.HOOK_FILES]:
134 self._create_fake_hook(
135 file_path, content=non_rc_content)
136
137 result = hook_utils.install_git_hooks(repo.path, repo.bare)
138 assert result
139
140 for file_path in [os.path.join(hooks_path, f) for f in self.HOOK_FILES]:
141 with open(file_path, 'rt') as hook_file:
142 content = hook_file.read()
143 assert content == non_rc_content
144
145 def test_non_rc_hooks_are_replaced_with_force_flag(self):
146 repo = self.create_dummy_repo('git')
147 hooks_path = os.path.join(repo.path, 'hooks')
148 non_rc_content = 'echo "non rc hook"\n'
149 for file_path in [os.path.join(hooks_path, f) for f in self.HOOK_FILES]:
150 self._create_fake_hook(
151 file_path, content=non_rc_content)
152
153 result = hook_utils.install_git_hooks(
154 repo.path, repo.bare, force_create=True)
155 assert result
156 self.check_hooks(repo.path, repo.bare)
157
158
159 class TestInstallSvnHooks(BaseInstallHooks):
160 HOOK_FILES = ('pre-commit', 'post-commit')
161
162 def test_hooks_are_installed(self):
163 repo = self.create_dummy_repo('svn')
164 result = hook_utils.install_svn_hooks(repo.path)
165 assert result
166 self.check_hooks(repo.path)
167
168 def test_hooks_are_replaced(self):
169 repo = self.create_dummy_repo('svn')
170 hooks_path = os.path.join(repo.path, 'hooks')
171 for file_path in [os.path.join(hooks_path, f) for f in self.HOOK_FILES]:
172 self._create_fake_hook(
173 file_path, content="RC_HOOK_VER = 'abcde'\n")
174
175 result = hook_utils.install_svn_hooks(repo.path)
176 assert result
177 self.check_hooks(repo.path)
178
179 def test_non_rc_hooks_are_not_replaced(self):
180 repo = self.create_dummy_repo('svn')
181 hooks_path = os.path.join(repo.path, 'hooks')
182 non_rc_content = 'echo "non rc hook"\n'
183 for file_path in [os.path.join(hooks_path, f) for f in self.HOOK_FILES]:
184 self._create_fake_hook(
185 file_path, content=non_rc_content)
186
187 result = hook_utils.install_svn_hooks(repo.path)
188 assert result
189
190 for file_path in [os.path.join(hooks_path, f) for f in self.HOOK_FILES]:
191 with open(file_path, 'rt') as hook_file:
192 content = hook_file.read()
193 assert content == non_rc_content
194
195 def test_non_rc_hooks_are_replaced_with_force_flag(self):
196 repo = self.create_dummy_repo('svn')
197 hooks_path = os.path.join(repo.path, 'hooks')
198 non_rc_content = 'echo "non rc hook"\n'
199 for file_path in [os.path.join(hooks_path, f) for f in self.HOOK_FILES]:
200 self._create_fake_hook(
201 file_path, content=non_rc_content)
202
203 result = hook_utils.install_svn_hooks(
204 repo.path, force_create=True)
205 assert result
206 self.check_hooks(repo.path, )
@@ -1,5 +1,5 b''
1 [bumpversion]
1 [bumpversion]
2 current_version = 4.11.6
2 current_version = 4.12.0
3 message = release: Bump version {current_version} to {new_version}
3 message = release: Bump version {current_version} to {new_version}
4
4
5 [bumpversion:file:vcsserver/VERSION]
5 [bumpversion:file:vcsserver/VERSION]
@@ -5,12 +5,10 b' done = false'
5 done = true
5 done = true
6
6
7 [task:fixes_on_stable]
7 [task:fixes_on_stable]
8 done = true
9
8
10 [task:pip2nix_generated]
9 [task:pip2nix_generated]
11 done = true
12
10
13 [release]
11 [release]
14 state = prepared
12 state = in_progress
15 version = 4.11.6
13 version = 4.12.0
16
14
@@ -8,6 +8,9 b' include vcsserver/VERSION'
8 # all config files
8 # all config files
9 recursive-include configs *
9 recursive-include configs *
10
10
11 # hook templates
12 recursive-include vcsserver/hook_utils/hook_templates *
13
11 # skip any tests files
14 # skip any tests files
12 recursive-exclude vcsserver/tests *
15 recursive-exclude vcsserver/tests *
13
16
@@ -20,6 +20,10 b' beaker.cache.repo_object.max_items = 100'
20 beaker.cache.repo_object.expire = 300
20 beaker.cache.repo_object.expire = 300
21 beaker.cache.repo_object.enabled = true
21 beaker.cache.repo_object.enabled = true
22
22
23 # path to binaries for vcsserver, it should be set by the installer
24 # at installation time, e.g /home/user/vcsserver-1/profile/bin
25 core.binary_dir = ""
26
23 [server:main]
27 [server:main]
24 ## COMMON ##
28 ## COMMON ##
25 host = 0.0.0.0
29 host = 0.0.0.0
@@ -39,7 +39,7 b' use = egg:rhodecode-vcsserver'
39 pyramid.default_locale_name = en
39 pyramid.default_locale_name = en
40 pyramid.includes =
40 pyramid.includes =
41
41
42 ## default locale used by VCS systems
42 # default locale used by VCS systems
43 locale = en_US.UTF-8
43 locale = en_US.UTF-8
44
44
45 # cache regions, please don't change
45 # cache regions, please don't change
@@ -50,6 +50,10 b' beaker.cache.repo_object.max_items = 100'
50 beaker.cache.repo_object.expire = 300
50 beaker.cache.repo_object.expire = 300
51 beaker.cache.repo_object.enabled = true
51 beaker.cache.repo_object.enabled = true
52
52
53 # path to binaries for vcsserver, it should be set by the installer
54 # at installation time, e.g /home/user/vcsserver-1/profile/bin
55 core.binary_dir = ""
56
53
57
54 ################################
58 ################################
55 ### LOGGING CONFIGURATION ####
59 ### LOGGING CONFIGURATION ####
@@ -12,6 +12,12 b' in'
12
12
13 self: super: {
13 self: super: {
14
14
15 Beaker = super.Beaker.override (attrs: {
16 patches = [
17 ./patch-beaker-lock-func-debug.diff
18 ];
19 });
20
15 subvertpy = super.subvertpy.override (attrs: {
21 subvertpy = super.subvertpy.override (attrs: {
16 # TODO: johbo: Remove the "or" once we drop 16.03 support
22 # TODO: johbo: Remove the "or" once we drop 16.03 support
17 SVN_PREFIX = "${pkgs.subversion.dev or pkgs.subversion}";
23 SVN_PREFIX = "${pkgs.subversion.dev or pkgs.subversion}";
@@ -3,26 +3,26 b''
3
3
4 {
4 {
5 Beaker = super.buildPythonPackage {
5 Beaker = super.buildPythonPackage {
6 name = "Beaker-1.9.0";
6 name = "Beaker-1.9.1";
7 buildInputs = with self; [];
7 buildInputs = with self; [];
8 doCheck = false;
8 doCheck = false;
9 propagatedBuildInputs = with self; [funcsigs];
9 propagatedBuildInputs = with self; [funcsigs];
10 src = fetchurl {
10 src = fetchurl {
11 url = "https://pypi.python.org/packages/93/b2/12de6937b06e9615dbb3cb3a1c9af17f133f435bdef59f4ad42032b6eb49/Beaker-1.9.0.tar.gz";
11 url = "https://pypi.python.org/packages/ca/14/a626188d0d0c7b55dd7cf1902046c2743bd392a7078bb53073e13280eb1e/Beaker-1.9.1.tar.gz";
12 md5 = "38b3fcdfa24faf97c6cf66991eb54e9c";
12 md5 = "46fda0a164e2b0d24ccbda51a2310301";
13 };
13 };
14 meta = {
14 meta = {
15 license = [ pkgs.lib.licenses.bsdOriginal ];
15 license = [ pkgs.lib.licenses.bsdOriginal ];
16 };
16 };
17 };
17 };
18 Jinja2 = super.buildPythonPackage {
18 Jinja2 = super.buildPythonPackage {
19 name = "Jinja2-2.10";
19 name = "Jinja2-2.9.6";
20 buildInputs = with self; [];
20 buildInputs = with self; [];
21 doCheck = false;
21 doCheck = false;
22 propagatedBuildInputs = with self; [MarkupSafe];
22 propagatedBuildInputs = with self; [MarkupSafe];
23 src = fetchurl {
23 src = fetchurl {
24 url = "https://pypi.python.org/packages/56/e6/332789f295cf22308386cf5bbd1f4e00ed11484299c5d7383378cf48ba47/Jinja2-2.10.tar.gz";
24 url = "https://pypi.python.org/packages/90/61/f820ff0076a2599dd39406dcb858ecb239438c02ce706c8e91131ab9c7f1/Jinja2-2.9.6.tar.gz";
25 md5 = "61ef1117f945486472850819b8d1eb3d";
25 md5 = "6411537324b4dba0956aaa8109f3c77b";
26 };
26 };
27 meta = {
27 meta = {
28 license = [ pkgs.lib.licenses.bsdOriginal ];
28 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -237,13 +237,13 b''
237 };
237 };
238 };
238 };
239 greenlet = super.buildPythonPackage {
239 greenlet = super.buildPythonPackage {
240 name = "greenlet-0.4.12";
240 name = "greenlet-0.4.13";
241 buildInputs = with self; [];
241 buildInputs = with self; [];
242 doCheck = false;
242 doCheck = false;
243 propagatedBuildInputs = with self; [];
243 propagatedBuildInputs = with self; [];
244 src = fetchurl {
244 src = fetchurl {
245 url = "https://pypi.python.org/packages/be/76/82af375d98724054b7e273b5d9369346937324f9bcc20980b45b068ef0b0/greenlet-0.4.12.tar.gz";
245 url = "https://pypi.python.org/packages/13/de/ba92335e9e76040ca7274224942282a80d54f85e342a5e33c5277c7f87eb/greenlet-0.4.13.tar.gz";
246 md5 = "e8637647d58a26c4a1f51ca393e53c00";
246 md5 = "6e0b9dd5385f81d478451ec8ed1d62b3";
247 };
247 };
248 meta = {
248 meta = {
249 license = [ pkgs.lib.licenses.mit ];
249 license = [ pkgs.lib.licenses.mit ];
@@ -372,8 +372,8 b''
372 doCheck = false;
372 doCheck = false;
373 propagatedBuildInputs = with self; [];
373 propagatedBuildInputs = with self; [];
374 src = fetchurl {
374 src = fetchurl {
375 url = "https://pypi.python.org/packages/15/45/30273ee91feb60dabb8fbb2da7868520525f02cf910279b3047182feed80/mock-1.0.1.zip";
375 url = "https://pypi.python.org/packages/a2/52/7edcd94f0afb721a2d559a5b9aae8af4f8f2c79bc63fdbe8a8a6c9b23bbe/mock-1.0.1.tar.gz";
376 md5 = "869f08d003c289a97c1a6610faf5e913";
376 md5 = "c3971991738caa55ec7c356bbc154ee2";
377 };
377 };
378 meta = {
378 meta = {
379 license = [ pkgs.lib.licenses.bsdOriginal ];
379 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -406,13 +406,13 b''
406 };
406 };
407 };
407 };
408 pexpect = super.buildPythonPackage {
408 pexpect = super.buildPythonPackage {
409 name = "pexpect-4.3.0";
409 name = "pexpect-4.4.0";
410 buildInputs = with self; [];
410 buildInputs = with self; [];
411 doCheck = false;
411 doCheck = false;
412 propagatedBuildInputs = with self; [ptyprocess];
412 propagatedBuildInputs = with self; [ptyprocess];
413 src = fetchurl {
413 src = fetchurl {
414 url = "https://pypi.python.org/packages/f8/44/5466c30e49762bb92e442bbdf4472d6904608d211258eb3198a11f0309a4/pexpect-4.3.0.tar.gz";
414 url = "https://pypi.python.org/packages/fa/c3/60c0cbf96f242d0b47a82e9ca634dcd6dcb043832cf05e17540812e1c707/pexpect-4.4.0.tar.gz";
415 md5 = "047a486dcd26134b74f2e67046bb61a0";
415 md5 = "e9b07f0765df8245ac72201d757baaef";
416 };
416 };
417 meta = {
417 meta = {
418 license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ];
418 license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ];
@@ -653,7 +653,7 b''
653 };
653 };
654 };
654 };
655 rhodecode-vcsserver = super.buildPythonPackage {
655 rhodecode-vcsserver = super.buildPythonPackage {
656 name = "rhodecode-vcsserver-4.11.6";
656 name = "rhodecode-vcsserver-4.12.0";
657 buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage configobj];
657 buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage configobj];
658 doCheck = true;
658 doCheck = true;
659 propagatedBuildInputs = with self; [Beaker configobj decorator dulwich hgsubversion hg-evolve infrae.cache mercurial msgpack-python pyramid pyramid-jinja2 pyramid-mako repoze.lru simplejson subprocess32 subvertpy six translationstring WebOb wheel zope.deprecation zope.interface ipdb ipython gevent greenlet gunicorn waitress pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage];
659 propagatedBuildInputs = with self; [Beaker configobj decorator dulwich hgsubversion hg-evolve infrae.cache mercurial msgpack-python pyramid pyramid-jinja2 pyramid-mako repoze.lru simplejson subprocess32 subvertpy six translationstring WebOb wheel zope.deprecation zope.interface ipdb ipython gevent greenlet gunicorn waitress pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage];
@@ -663,13 +663,13 b''
663 };
663 };
664 };
664 };
665 scandir = super.buildPythonPackage {
665 scandir = super.buildPythonPackage {
666 name = "scandir-1.6";
666 name = "scandir-1.7";
667 buildInputs = with self; [];
667 buildInputs = with self; [];
668 doCheck = false;
668 doCheck = false;
669 propagatedBuildInputs = with self; [];
669 propagatedBuildInputs = with self; [];
670 src = fetchurl {
670 src = fetchurl {
671 url = "https://pypi.python.org/packages/77/3f/916f524f50ee65e3f465a280d2851bd63685250fddb3020c212b3977664d/scandir-1.6.tar.gz";
671 url = "https://pypi.python.org/packages/13/bb/e541b74230bbf7a20a3949a2ee6631be299378a784f5445aa5d0047c192b/scandir-1.7.tar.gz";
672 md5 = "0180ddb97c96cbb2d4f25d2ae11c64ac";
672 md5 = "037e5f24d1a0e78b17faca72dea9555f";
673 };
673 };
674 meta = {
674 meta = {
675 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "New BSD License"; } ];
675 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "New BSD License"; } ];
@@ -845,26 +845,26 b''
845 };
845 };
846 };
846 };
847 zope.deprecation = super.buildPythonPackage {
847 zope.deprecation = super.buildPythonPackage {
848 name = "zope.deprecation-4.1.2";
848 name = "zope.deprecation-4.3.0";
849 buildInputs = with self; [];
849 buildInputs = with self; [];
850 doCheck = false;
850 doCheck = false;
851 propagatedBuildInputs = with self; [setuptools];
851 propagatedBuildInputs = with self; [setuptools];
852 src = fetchurl {
852 src = fetchurl {
853 url = "https://pypi.python.org/packages/c1/d3/3919492d5e57d8dd01b36f30b34fc8404a30577392b1eb817c303499ad20/zope.deprecation-4.1.2.tar.gz";
853 url = "https://pypi.python.org/packages/a1/18/2dc5e6bfe64fdc3b79411b67464c55bb0b43b127051a20f7f492ab767758/zope.deprecation-4.3.0.tar.gz";
854 md5 = "e9a663ded58f4f9f7881beb56cae2782";
854 md5 = "2166b2cb7e0e96a21104e6f8f9b696bb";
855 };
855 };
856 meta = {
856 meta = {
857 license = [ pkgs.lib.licenses.zpt21 ];
857 license = [ pkgs.lib.licenses.zpt21 ];
858 };
858 };
859 };
859 };
860 zope.interface = super.buildPythonPackage {
860 zope.interface = super.buildPythonPackage {
861 name = "zope.interface-4.1.3";
861 name = "zope.interface-4.4.3";
862 buildInputs = with self; [];
862 buildInputs = with self; [];
863 doCheck = false;
863 doCheck = false;
864 propagatedBuildInputs = with self; [setuptools];
864 propagatedBuildInputs = with self; [setuptools];
865 src = fetchurl {
865 src = fetchurl {
866 url = "https://pypi.python.org/packages/9d/81/2509ca3c6f59080123c1a8a97125eb48414022618cec0e64eb1313727bfe/zope.interface-4.1.3.tar.gz";
866 url = "https://pypi.python.org/packages/bd/d2/25349ed41f9dcff7b3baf87bd88a4c82396cf6e02f1f42bb68657a3132af/zope.interface-4.4.3.tar.gz";
867 md5 = "9ae3d24c0c7415deb249dd1a132f0f79";
867 md5 = "8700a4f527c1203b34b10c2b4e7a6912";
868 };
868 };
869 meta = {
869 meta = {
870 license = [ pkgs.lib.licenses.zpt21 ];
870 license = [ pkgs.lib.licenses.zpt21 ];
@@ -1,7 +1,7 b''
1 ## core
1 ## core
2 setuptools==30.1.0
2 setuptools==30.1.0
3
3
4 Beaker==1.9.0
4 Beaker==1.9.1
5 configobj==5.0.6
5 configobj==5.0.6
6 decorator==4.1.2
6 decorator==4.1.2
7 dulwich==0.13.0
7 dulwich==0.13.0
@@ -11,6 +11,7 b' infrae.cache==1.0.1'
11 mercurial==4.4.2
11 mercurial==4.4.2
12 msgpack-python==0.4.8
12 msgpack-python==0.4.8
13 pyramid-jinja2==2.7
13 pyramid-jinja2==2.7
14 Jinja2==2.9.6
14 pyramid==1.9.1
15 pyramid==1.9.1
15 pyramid-mako==1.0.2
16 pyramid-mako==1.0.2
16 repoze.lru==0.7
17 repoze.lru==0.7
@@ -23,12 +24,12 b' six==1.11.0'
23 translationstring==1.3
24 translationstring==1.3
24 WebOb==1.7.4
25 WebOb==1.7.4
25 wheel==0.29.0
26 wheel==0.29.0
26 zope.deprecation==4.1.2
27 zope.deprecation==4.3.0
27 zope.interface==4.1.3
28 zope.interface==4.4.3
28
29
29 ## http servers
30 ## http servers
30 gevent==1.2.2
31 gevent==1.2.2
31 greenlet==0.4.12
32 greenlet==0.4.13
32 gunicorn==19.7.1
33 gunicorn==19.7.1
33 waitress==1.1.0
34 waitress==1.1.0
34
35
@@ -1,1 +1,1 b''
1 4.11.6 No newline at end of file
1 4.12.0 No newline at end of file
@@ -451,8 +451,9 b' class GitRemote(object):'
451 if self.check_url(url, wire):
451 if self.check_url(url, wire):
452 repo = self._factory.repo(wire)
452 repo = self._factory.repo(wire)
453 self.run_git_command(
453 self.run_git_command(
454 wire, ['push', url, '--mirror'], fail_on_stderr=False)
454 wire, ['push', url, '--mirror'], fail_on_stderr=False,
455
455 _copts=['-c', 'core.askpass=""'],
456 extra_env={'GIT_TERMINAL_PROMPT': '0'})
456
457
457 @reraise_safe_exceptions
458 @reraise_safe_exceptions
458 def get_remote_refs(self, wire, url):
459 def get_remote_refs(self, wire, url):
@@ -625,6 +626,10 b' class GitRemote(object):'
625 del opts['_safe']
626 del opts['_safe']
626 safe_call = True
627 safe_call = True
627
628
629 if '_copts' in opts:
630 _copts.extend(opts['_copts'] or [])
631 del opts['_copts']
632
628 gitenv = os.environ.copy()
633 gitenv = os.environ.copy()
629 gitenv.update(opts.pop('extra_env', {}))
634 gitenv.update(opts.pop('extra_env', {}))
630 # need to clean fix GIT_DIR !
635 # need to clean fix GIT_DIR !
@@ -650,6 +655,12 b' class GitRemote(object):'
650 else:
655 else:
651 raise exceptions.VcsException(tb_err)
656 raise exceptions.VcsException(tb_err)
652
657
658 @reraise_safe_exceptions
659 def install_hooks(self, wire, force=False):
660 from vcsserver.hook_utils import install_git_hooks
661 repo = self._factory.repo(wire)
662 return install_git_hooks(repo.path, repo.bare, force_create=force)
663
653
664
654 def str_to_dulwich(value):
665 def str_to_dulwich(value):
655 """
666 """
@@ -553,7 +553,13 b' class HgRemote(object):'
553 @reraise_safe_exceptions
553 @reraise_safe_exceptions
554 def pull(self, wire, url, commit_ids=None):
554 def pull(self, wire, url, commit_ids=None):
555 repo = self._factory.repo(wire)
555 repo = self._factory.repo(wire)
556 # Disable any prompts for this repo
557 repo.ui.setconfig('ui', 'interactive', 'off', '-y')
558
556 remote = peer(repo, {}, url)
559 remote = peer(repo, {}, url)
560 # Disable any prompts for this remote
561 remote.ui.setconfig('ui', 'interactive', 'off', '-y')
562
557 if commit_ids:
563 if commit_ids:
558 commit_ids = [bin(commit_id) for commit_id in commit_ids]
564 commit_ids = [bin(commit_id) for commit_id in commit_ids]
559
565
@@ -564,8 +570,15 b' class HgRemote(object):'
564 def sync_push(self, wire, url):
570 def sync_push(self, wire, url):
565 if self.check_url(url, wire['config']):
571 if self.check_url(url, wire['config']):
566 repo = self._factory.repo(wire)
572 repo = self._factory.repo(wire)
573
574 # Disable any prompts for this repo
575 repo.ui.setconfig('ui', 'interactive', 'off', '-y')
576
567 bookmarks = dict(repo._bookmarks).keys()
577 bookmarks = dict(repo._bookmarks).keys()
568 remote = peer(repo, {}, url)
578 remote = peer(repo, {}, url)
579 # Disable any prompts for this remote
580 remote.ui.setconfig('ui', 'interactive', 'off', '-y')
581
569 return exchange.push(
582 return exchange.push(
570 repo, remote, newbranch=True, bookmarks=bookmarks).cgresult
583 repo, remote, newbranch=True, bookmarks=bookmarks).cgresult
571
584
@@ -756,3 +769,8 b' class HgRemote(object):'
756 repo = self._factory.repo(wire)
769 repo = self._factory.repo(wire)
757 baseui = self._factory._create_config(wire['config'])
770 baseui = self._factory._create_config(wire['config'])
758 commands.bookmark(baseui, repo, bookmark, rev=revision, force=True)
771 commands.bookmark(baseui, repo, bookmark, rev=revision, force=True)
772
773 @reraise_safe_exceptions
774 def install_hooks(self, wire, force=False):
775 # we don't need any special hooks for Mercurial
776 pass
@@ -87,7 +87,7 b' def patch_subrepo_type_mapping():'
87 """
87 """
88 return True
88 return True
89
89
90 def dirty(self, ignoreupdate=False):
90 def dirty(self, ignoreupdate=False, missing=False):
91 """returns true if the dirstate of the subrepo is dirty or does not
91 """returns true if the dirstate of the subrepo is dirty or does not
92 match current stored state. If ignoreupdate is true, only check
92 match current stored state. If ignoreupdate is true, only check
93 whether the subrepo has uncommitted changes in its dirstate.
93 whether the subrepo has uncommitted changes in its dirstate.
@@ -20,10 +20,10 b''
20 import io
20 import io
21 import os
21 import os
22 import sys
22 import sys
23 import json
24 import logging
23 import logging
25 import collections
24 import collections
26 import importlib
25 import importlib
26 import base64
27
27
28 from httplib import HTTPConnection
28 from httplib import HTTPConnection
29
29
@@ -46,7 +46,11 b' class HooksHttpClient(object):'
46 def __call__(self, method, extras):
46 def __call__(self, method, extras):
47 connection = HTTPConnection(self.hooks_uri)
47 connection = HTTPConnection(self.hooks_uri)
48 body = self._serialize(method, extras)
48 body = self._serialize(method, extras)
49 connection.request('POST', '/', body)
49 try:
50 connection.request('POST', '/', body)
51 except Exception:
52 log.error('Connection failed on %s', connection)
53 raise
50 response = connection.getresponse()
54 response = connection.getresponse()
51 return json.loads(response.read())
55 return json.loads(response.read())
52
56
@@ -97,6 +101,17 b' class GitMessageWriter(RemoteMessageWrit'
97 self.stdout.write(message.encode('utf-8'))
101 self.stdout.write(message.encode('utf-8'))
98
102
99
103
104 class SvnMessageWriter(RemoteMessageWriter):
105 """Writer that knows how to send messages to svn clients."""
106
107 def __init__(self, stderr=None):
108 # SVN needs data sent to stderr for back-to-client messaging
109 self.stderr = stderr or sys.stderr
110
111 def write(self, message):
112 self.stderr.write(message.encode('utf-8'))
113
114
100 def _handle_exception(result):
115 def _handle_exception(result):
101 exception_class = result.get('exception')
116 exception_class = result.get('exception')
102 exception_traceback = result.get('exception_traceback')
117 exception_traceback = result.get('exception_traceback')
@@ -122,8 +137,9 b' def _get_hooks_client(extras):'
122
137
123
138
124 def _call_hook(hook_name, extras, writer):
139 def _call_hook(hook_name, extras, writer):
125 hooks = _get_hooks_client(extras)
140 hooks_client = _get_hooks_client(extras)
126 result = hooks(hook_name, extras)
141 log.debug('Hooks, using client:%s', hooks_client)
142 result = hooks_client(hook_name, extras)
127 log.debug('Hooks got result: %s', result)
143 log.debug('Hooks got result: %s', result)
128 writer.write(result['output'])
144 writer.write(result['output'])
129 _handle_exception(result)
145 _handle_exception(result)
@@ -465,3 +481,61 b' def git_post_receive(unused_repo_path, r'
465 pass
481 pass
466
482
467 return _call_hook('post_push', extras, GitMessageWriter())
483 return _call_hook('post_push', extras, GitMessageWriter())
484
485
486 def svn_pre_commit(repo_path, commit_data, env):
487 path, txn_id = commit_data
488 branches = []
489 tags = []
490
491 cmd = ['svnlook', 'pget',
492 '-t', txn_id,
493 '--revprop', path, 'rc-scm-extras']
494 stdout, stderr = subprocessio.run_command(
495 cmd, env=os.environ.copy())
496 extras = json.loads(base64.urlsafe_b64decode(stdout))
497
498 extras['commit_ids'] = []
499 extras['txn_id'] = txn_id
500 extras['new_refs'] = {
501 'branches': branches,
502 'bookmarks': [],
503 'tags': tags,
504 }
505 sys.stderr.write(str(extras))
506 return _call_hook('pre_push', extras, SvnMessageWriter())
507
508
509 def svn_post_commit(repo_path, commit_data, env):
510 """
511 commit_data is path, rev, txn_id
512 """
513 path, commit_id, txn_id = commit_data
514 branches = []
515 tags = []
516
517 cmd = ['svnlook', 'pget',
518 '-r', commit_id,
519 '--revprop', path, 'rc-scm-extras']
520 stdout, stderr = subprocessio.run_command(
521 cmd, env=os.environ.copy())
522
523 extras = json.loads(base64.urlsafe_b64decode(stdout))
524
525 extras['commit_ids'] = [commit_id]
526 extras['txn_id'] = txn_id
527 extras['new_refs'] = {
528 'branches': branches,
529 'bookmarks': [],
530 'tags': tags,
531 }
532
533 if 'repo_size' in extras['hooks']:
534 try:
535 _call_hook('repo_size', extras, SvnMessageWriter())
536 except:
537 pass
538
539 return _call_hook('post_push', extras, SvnMessageWriter())
540
541
@@ -15,6 +15,7 b''
15 # along with this program; if not, write to the Free Software Foundation,
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
18 import os
18 import base64
19 import base64
19 import locale
20 import locale
20 import logging
21 import logging
@@ -29,6 +30,7 b' from beaker.cache import CacheManager'
29 from beaker.util import parse_cache_config_options
30 from beaker.util import parse_cache_config_options
30 from pyramid.config import Configurator
31 from pyramid.config import Configurator
31 from pyramid.wsgi import wsgiapp
32 from pyramid.wsgi import wsgiapp
33 from pyramid.compat import configparser
32
34
33 from vcsserver import remote_wsgi, scm_app, settings, hgpatches
35 from vcsserver import remote_wsgi, scm_app, settings, hgpatches
34 from vcsserver.git_lfs.app import GIT_LFS_CONTENT_TYPE, GIT_LFS_PROTO_PAT
36 from vcsserver.git_lfs.app import GIT_LFS_CONTENT_TYPE, GIT_LFS_PROTO_PAT
@@ -90,6 +92,10 b' class VCS(object):'
90 svn_repo_cache = self.cache.get_cache_region(
92 svn_repo_cache = self.cache.get_cache_region(
91 'svn', region='repo_object')
93 'svn', region='repo_object')
92 svn_factory = SubversionFactory(svn_repo_cache)
94 svn_factory = SubversionFactory(svn_repo_cache)
95 # hg factory is used for svn url validation
96 hg_repo_cache = self.cache.get_cache_region(
97 'hg', region='repo_object')
98 hg_factory = MercurialFactory(hg_repo_cache)
93 self._svn_remote = SvnRemote(svn_factory, hg_factory=hg_factory)
99 self._svn_remote = SvnRemote(svn_factory, hg_factory=hg_factory)
94 else:
100 else:
95 log.info("Subversion client import failed")
101 log.info("Subversion client import failed")
@@ -188,6 +194,9 b' class HTTPApplication(object):'
188 git_path = app_settings.get('git_path', None)
194 git_path = app_settings.get('git_path', None)
189 if git_path:
195 if git_path:
190 settings.GIT_EXECUTABLE = git_path
196 settings.GIT_EXECUTABLE = git_path
197 binary_dir = app_settings.get('core.binary_dir', None)
198 if binary_dir:
199 settings.BINARY_DIR = binary_dir
191
200
192 def _configure(self):
201 def _configure(self):
193 self.config.add_renderer(
202 self.config.add_renderer(
@@ -276,11 +285,11 b' class HTTPApplication(object):'
276
285
277 def status_view(self, request):
286 def status_view(self, request):
278 import vcsserver
287 import vcsserver
279 return {'status': 'OK', 'vcsserver_version': vcsserver.__version__}
288 return {'status': 'OK', 'vcsserver_version': vcsserver.__version__,
289 'pid': os.getpid()}
280
290
281 def service_view(self, request):
291 def service_view(self, request):
282 import vcsserver
292 import vcsserver
283 import ConfigParser as configparser
284
293
285 payload = msgpack.unpackb(request.body, use_list=True)
294 payload = msgpack.unpackb(request.body, use_list=True)
286
295
@@ -17,3 +17,4 b''
17
17
18 WIRE_ENCODING = 'UTF-8'
18 WIRE_ENCODING = 'UTF-8'
19 GIT_EXECUTABLE = 'git'
19 GIT_EXECUTABLE = 'git'
20 BINARY_DIR = ''
@@ -32,7 +32,7 b' import svn.diff'
32 import svn.fs
32 import svn.fs
33 import svn.repos
33 import svn.repos
34
34
35 from vcsserver import svn_diff, exceptions, subprocessio
35 from vcsserver import svn_diff, exceptions, subprocessio, settings
36 from vcsserver.base import RepoFactory, raise_from_original
36 from vcsserver.base import RepoFactory, raise_from_original
37
37
38 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
@@ -414,6 +414,17 b' class SvnRemote(object):'
414 def is_large_file(self, wire, path):
414 def is_large_file(self, wire, path):
415 return False
415 return False
416
416
417 @reraise_safe_exceptions
418 def install_hooks(self, wire, force=False):
419 from vcsserver.hook_utils import install_svn_hooks
420 repo_path = wire['path']
421 binary_dir = settings.BINARY_DIR
422 executable = None
423 if binary_dir:
424 executable = os.path.join(binary_dir, 'python')
425 return install_svn_hooks(
426 repo_path, executable=executable, force_create=force)
427
417
428
418 class SvnDiffer(object):
429 class SvnDiffer(object):
419 """
430 """
@@ -576,6 +587,7 b' class SvnDiffer(object):'
576 return content.splitlines(True)
587 return content.splitlines(True)
577
588
578
589
590
579 class DiffChangeEditor(svn.delta.Editor):
591 class DiffChangeEditor(svn.delta.Editor):
580 """
592 """
581 Records changes between two given revisions
593 Records changes between two given revisions
@@ -55,3 +55,4 b' def get_available_port():'
55 mysocket.close()
55 mysocket.close()
56 del mysocket
56 del mysocket
57 return port
57 return port
58
@@ -69,3 +69,18 b' class ContextINI(object):'
69 def __exit__(self, exc_type, exc_val, exc_tb):
69 def __exit__(self, exc_type, exc_val, exc_tb):
70 if self.destroy:
70 if self.destroy:
71 os.remove(self.new_path)
71 os.remove(self.new_path)
72
73
74 def no_newline_id_generator(test_name):
75 """
76 Generates a test name without spaces or newlines characters. Used for
77 nicer output of progress of test
78 """
79 org_name = test_name
80 test_name = test_name\
81 .replace('\n', '_N') \
82 .replace('\r', '_N') \
83 .replace('\t', '_T') \
84 .replace(' ', '_S')
85
86 return test_name or 'test-with-empty-name'
@@ -14,6 +14,9 b''
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 import logging
18
19 log = logging.getLogger(__name__)
17
20
18
21
19 def safe_int(val, default=None):
22 def safe_int(val, default=None):
@@ -70,3 +73,10 b" def safe_str(unicode_, to_encoding=['utf"
70 return unicode_.encode(encoding)
73 return unicode_.encode(encoding)
71 except (ImportError, UnicodeEncodeError):
74 except (ImportError, UnicodeEncodeError):
72 return unicode_.encode(to_encoding[0], 'replace')
75 return unicode_.encode(to_encoding[0], 'replace')
76
77
78 class AttributeDict(dict):
79 def __getattr__(self, attr):
80 return self.get(attr, None)
81 __setattr__ = dict.__setitem__
82 __delattr__ = dict.__delitem__
General Comments 0
You need to be logged in to leave comments. Login now