Show More
@@ -0,0 +1,40 b'' | |||||
|
1 | # Copyright (C) 2010-2023 RhodeCode GmbH | |||
|
2 | # | |||
|
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 | |||
|
5 | # (only), as published by the Free Software Foundation. | |||
|
6 | # | |||
|
7 | # This program is distributed in the hope that it will be useful, | |||
|
8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
10 | # GNU General Public License for more details. | |||
|
11 | # | |||
|
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/>. | |||
|
14 | # | |||
|
15 | # This program is dual-licensed. If you wish to learn more about the | |||
|
16 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
17 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
18 | import os | |||
|
19 | ||||
|
20 | ||||
|
21 | def get_config(ini_path, **kwargs): | |||
|
22 | import configparser | |||
|
23 | parser = configparser.ConfigParser(**kwargs) | |||
|
24 | parser.read(ini_path) | |||
|
25 | return parser | |||
|
26 | ||||
|
27 | ||||
|
28 | def get_app_config_lightweight(ini_path): | |||
|
29 | parser = get_config(ini_path) | |||
|
30 | parser.set('app:main', 'here', os.getcwd()) | |||
|
31 | parser.set('app:main', '__file__', ini_path) | |||
|
32 | return dict(parser.items('app:main')) | |||
|
33 | ||||
|
34 | ||||
|
35 | def get_app_config(ini_path): | |||
|
36 | """ | |||
|
37 | This loads the app context and provides a heavy type iniliaziation of config | |||
|
38 | """ | |||
|
39 | from paste.deploy.loadwsgi import appconfig | |||
|
40 | return appconfig(f'config:{ini_path}', relative_to=os.getcwd()) |
@@ -28,6 +28,7 b' from vcsserver.type_utils import str2boo' | |||||
28 |
|
28 | |||
29 | log = logging.getLogger(__name__) |
|
29 | log = logging.getLogger(__name__) | |
30 |
|
30 | |||
|
31 | ||||
31 | # skip keys, that are set here, so we don't double process those |
|
32 | # skip keys, that are set here, so we don't double process those | |
32 | set_keys = { |
|
33 | set_keys = { | |
33 | '__file__': '' |
|
34 | '__file__': '' | |
@@ -51,6 +52,10 b' class SettingsMaker:' | |||||
51 | return int(input_val) |
|
52 | return int(input_val) | |
52 |
|
53 | |||
53 | @classmethod |
|
54 | @classmethod | |
|
55 | def _float_func(cls, input_val): | |||
|
56 | return float(input_val) | |||
|
57 | ||||
|
58 | @classmethod | |||
54 | def _list_func(cls, input_val, sep=','): |
|
59 | def _list_func(cls, input_val, sep=','): | |
55 | return aslist(input_val, sep=sep) |
|
60 | return aslist(input_val, sep=sep) | |
56 |
|
61 | |||
@@ -61,8 +66,18 b' class SettingsMaker:' | |||||
61 | return input_val |
|
66 | return input_val | |
62 |
|
67 | |||
63 | @classmethod |
|
68 | @classmethod | |
64 |
def _ |
|
69 | def _string_no_quote_func(cls, input_val, lower=True): | |
65 | return float(input_val) |
|
70 | """ | |
|
71 | Special case string function that detects if value is set to empty quote string | |||
|
72 | e.g. | |||
|
73 | ||||
|
74 | core.binary_dir = "" | |||
|
75 | """ | |||
|
76 | ||||
|
77 | input_val = cls._string_func(input_val, lower=lower) | |||
|
78 | if input_val in ['""', "''"]: | |||
|
79 | return '' | |||
|
80 | return input_val | |||
66 |
|
81 | |||
67 | @classmethod |
|
82 | @classmethod | |
68 | def _dir_func(cls, input_val, ensure_dir=False, mode=0o755): |
|
83 | def _dir_func(cls, input_val, ensure_dir=False, mode=0o755): | |
@@ -148,10 +163,12 b' class SettingsMaker:' | |||||
148 | parser_func = { |
|
163 | parser_func = { | |
149 | 'bool': self._bool_func, |
|
164 | 'bool': self._bool_func, | |
150 | 'int': self._int_func, |
|
165 | 'int': self._int_func, | |
|
166 | 'float': self._float_func, | |||
151 | 'list': self._list_func, |
|
167 | 'list': self._list_func, | |
152 | 'list:newline': functools.partial(self._list_func, sep='/n'), |
|
168 | 'list:newline': functools.partial(self._list_func, sep='/n'), | |
153 | 'list:spacesep': functools.partial(self._list_func, sep=' '), |
|
169 | 'list:spacesep': functools.partial(self._list_func, sep=' '), | |
154 | 'string': functools.partial(self._string_func, lower=lower), |
|
170 | 'string': functools.partial(self._string_func, lower=lower), | |
|
171 | 'string:noquote': functools.partial(self._string_no_quote_func, lower=lower), | |||
155 | 'dir': self._dir_func, |
|
172 | 'dir': self._dir_func, | |
156 | 'dir:ensured': functools.partial(self._dir_func, ensure_dir=True), |
|
173 | 'dir:ensured': functools.partial(self._dir_func, ensure_dir=True), | |
157 | 'file': self._file_path_func, |
|
174 | 'file': self._file_path_func, |
@@ -142,9 +142,9 b' def install_svn_hooks(repo_path, executa' | |||||
142 |
|
142 | |||
143 | env_expand = str([ |
|
143 | env_expand = str([ | |
144 | ('RC_CORE_BINARY_DIR', vcsserver.settings.BINARY_DIR), |
|
144 | ('RC_CORE_BINARY_DIR', vcsserver.settings.BINARY_DIR), | |
145 | ('RC_GIT_EXECUTABLE', vcsserver.settings.GIT_EXECUTABLE), |
|
145 | ('RC_GIT_EXECUTABLE', vcsserver.settings.GIT_EXECUTABLE()), | |
146 | ('RC_SVN_EXECUTABLE', vcsserver.settings.SVN_EXECUTABLE), |
|
146 | ('RC_SVN_EXECUTABLE', vcsserver.settings.SVN_EXECUTABLE()), | |
147 | ('RC_SVNLOOK_EXECUTABLE', vcsserver.settings.SVNLOOK_EXECUTABLE), |
|
147 | ('RC_SVNLOOK_EXECUTABLE', vcsserver.settings.SVNLOOK_EXECUTABLE()), | |
148 |
|
148 | |||
149 | ]) |
|
149 | ]) | |
150 | try: |
|
150 | try: |
@@ -31,7 +31,6 b' from celery import Celery' | |||||
31 | import mercurial.scmutil |
|
31 | import mercurial.scmutil | |
32 | import mercurial.node |
|
32 | import mercurial.node | |
33 |
|
33 | |||
34 | import vcsserver.settings |
|
|||
35 | from vcsserver.lib.rc_json import json |
|
34 | from vcsserver.lib.rc_json import json | |
36 | from vcsserver import exceptions, subprocessio, settings |
|
35 | from vcsserver import exceptions, subprocessio, settings | |
37 | from vcsserver.str_utils import ascii_str, safe_str |
|
36 | from vcsserver.str_utils import ascii_str, safe_str | |
@@ -294,20 +293,23 b' def _get_hg_env(old_rev, new_rev, txnid,' | |||||
294 | return [(k, v) for k, v in env.items()] |
|
293 | return [(k, v) for k, v in env.items()] | |
295 |
|
294 | |||
296 |
|
295 | |||
297 | def _fix_hooks_executables(): |
|
296 | def _fix_hooks_executables(ini_path=''): | |
298 | """ |
|
297 | """ | |
299 | This is a trick to set proper settings.EXECUTABLE paths for certain execution patterns |
|
298 | This is a trick to set proper settings.EXECUTABLE paths for certain execution patterns | |
300 | especially for subversion where hooks strip entire env, and calling just 'svn' command will most likely fail |
|
299 | especially for subversion where hooks strip entire env, and calling just 'svn' command will most likely fail | |
301 | because svn is not on PATH |
|
300 | because svn is not on PATH | |
302 | """ |
|
301 | """ | |
303 | vcsserver.settings.BINARY_DIR = ( |
|
302 | from vcsserver.http_main import sanitize_settings_and_apply_defaults | |
304 | os.environ.get('RC_BINARY_DIR') or vcsserver.settings.BINARY_DIR) |
|
303 | from vcsserver.lib.config_utils import get_app_config_lightweight | |
305 | vcsserver.settings.GIT_EXECUTABLE = ( |
|
304 | ||
306 | os.environ.get('RC_GIT_EXECUTABLE') or vcsserver.settings.GIT_EXECUTABLE) |
|
305 | core_binary_dir = settings.BINARY_DIR or '/usr/local/bin/rhodecode_bin/vcs_bin' | |
307 | vcsserver.settings.SVN_EXECUTABLE = ( |
|
306 | if ini_path: | |
308 | os.environ.get('RC_SVN_EXECUTABLE') or vcsserver.settings.SVN_EXECUTABLE) |
|
307 | ||
309 | vcsserver.settings.SVNLOOK_EXECUTABLE = ( |
|
308 | ini_settings = get_app_config_lightweight(ini_path) | |
310 | os.environ.get('RC_SVNLOOK_EXECUTABLE') or vcsserver.settings.SVNLOOK_EXECUTABLE) |
|
309 | ini_settings = sanitize_settings_and_apply_defaults({'__file__': ini_path}, ini_settings) | |
|
310 | core_binary_dir = ini_settings['core.binary_dir'] | |||
|
311 | ||||
|
312 | settings.BINARY_DIR = core_binary_dir | |||
311 |
|
313 | |||
312 |
|
314 | |||
313 | def repo_size(ui, repo, **kwargs): |
|
315 | def repo_size(ui, repo, **kwargs): | |
@@ -568,10 +570,12 b' def git_pre_receive(unused_repo_path, re' | |||||
568 | rev_data = _parse_git_ref_lines(revision_lines) |
|
570 | rev_data = _parse_git_ref_lines(revision_lines) | |
569 | if 'push' not in extras['hooks']: |
|
571 | if 'push' not in extras['hooks']: | |
570 | return 0 |
|
572 | return 0 | |
|
573 | _fix_hooks_executables() | |||
|
574 | ||||
571 | empty_commit_id = '0' * 40 |
|
575 | empty_commit_id = '0' * 40 | |
572 |
|
576 | |||
573 | detect_force_push = extras.get('detect_force_push') |
|
577 | detect_force_push = extras.get('detect_force_push') | |
574 | _fix_hooks_executables() |
|
578 | ||
575 | for push_ref in rev_data: |
|
579 | for push_ref in rev_data: | |
576 | # store our git-env which holds the temp store |
|
580 | # store our git-env which holds the temp store | |
577 | push_ref['git_env'] = _get_git_env() |
|
581 | push_ref['git_env'] = _get_git_env() | |
@@ -586,7 +590,7 b' def git_pre_receive(unused_repo_path, re' | |||||
586 | if type_ == 'heads' and not (new_branch or delete_branch): |
|
590 | if type_ == 'heads' and not (new_branch or delete_branch): | |
587 | old_rev = push_ref['old_rev'] |
|
591 | old_rev = push_ref['old_rev'] | |
588 | new_rev = push_ref['new_rev'] |
|
592 | new_rev = push_ref['new_rev'] | |
589 | cmd = [settings.GIT_EXECUTABLE, 'rev-list', old_rev, f'^{new_rev}'] |
|
593 | cmd = [settings.GIT_EXECUTABLE(), 'rev-list', old_rev, f'^{new_rev}'] | |
590 | stdout, stderr = subprocessio.run_command( |
|
594 | stdout, stderr = subprocessio.run_command( | |
591 | cmd, env=os.environ.copy()) |
|
595 | cmd, env=os.environ.copy()) | |
592 | # means we're having some non-reachable objects, this forced push was used |
|
596 | # means we're having some non-reachable objects, this forced push was used | |
@@ -611,6 +615,7 b' def git_post_receive(unused_repo_path, r' | |||||
611 | extras = json.loads(env['RC_SCM_DATA']) |
|
615 | extras = json.loads(env['RC_SCM_DATA']) | |
612 | if 'push' not in extras['hooks']: |
|
616 | if 'push' not in extras['hooks']: | |
613 | return 0 |
|
617 | return 0 | |
|
618 | ||||
614 | _fix_hooks_executables() |
|
619 | _fix_hooks_executables() | |
615 |
|
620 | |||
616 | rev_data = _parse_git_ref_lines(revision_lines) |
|
621 | rev_data = _parse_git_ref_lines(revision_lines) | |
@@ -645,14 +650,14 b' def git_post_receive(unused_repo_path, r' | |||||
645 | repo.set_head(need_head_set) |
|
650 | repo.set_head(need_head_set) | |
646 | print(f"Setting default branch to {push_ref_name}") |
|
651 | print(f"Setting default branch to {push_ref_name}") | |
647 |
|
652 | |||
648 | cmd = [settings.GIT_EXECUTABLE, 'for-each-ref', '--format=%(refname)', 'refs/heads/*'] |
|
653 | cmd = [settings.GIT_EXECUTABLE(), 'for-each-ref', '--format=%(refname)', 'refs/heads/*'] | |
649 | stdout, stderr = subprocessio.run_command( |
|
654 | stdout, stderr = subprocessio.run_command( | |
650 | cmd, env=os.environ.copy()) |
|
655 | cmd, env=os.environ.copy()) | |
651 | heads = safe_str(stdout) |
|
656 | heads = safe_str(stdout) | |
652 | heads = heads.replace(push_ref['ref'], '') |
|
657 | heads = heads.replace(push_ref['ref'], '') | |
653 | heads = ' '.join(head for head |
|
658 | heads = ' '.join(head for head | |
654 | in heads.splitlines() if head) or '.' |
|
659 | in heads.splitlines() if head) or '.' | |
655 | cmd = [settings.GIT_EXECUTABLE, 'log', '--reverse', |
|
660 | cmd = [settings.GIT_EXECUTABLE(), 'log', '--reverse', | |
656 | '--pretty=format:%H', '--', push_ref['new_rev'], |
|
661 | '--pretty=format:%H', '--', push_ref['new_rev'], | |
657 | '--not', heads] |
|
662 | '--not', heads] | |
658 | stdout, stderr = subprocessio.run_command( |
|
663 | stdout, stderr = subprocessio.run_command( | |
@@ -666,7 +671,7 b' def git_post_receive(unused_repo_path, r' | |||||
666 | if push_ref['name'] not in branches: |
|
671 | if push_ref['name'] not in branches: | |
667 | branches.append(push_ref['name']) |
|
672 | branches.append(push_ref['name']) | |
668 |
|
673 | |||
669 | cmd = [settings.GIT_EXECUTABLE, 'log', |
|
674 | cmd = [settings.GIT_EXECUTABLE(), 'log', | |
670 | f'{push_ref["old_rev"]}..{push_ref["new_rev"]}', |
|
675 | f'{push_ref["old_rev"]}..{push_ref["new_rev"]}', | |
671 | '--reverse', '--pretty=format:%H'] |
|
676 | '--reverse', '--pretty=format:%H'] | |
672 | stdout, stderr = subprocessio.run_command( |
|
677 | stdout, stderr = subprocessio.run_command( | |
@@ -716,9 +721,11 b' def git_post_receive(unused_repo_path, r' | |||||
716 |
|
721 | |||
717 |
|
722 | |||
718 | def _get_extras_from_txn_id(path, txn_id): |
|
723 | def _get_extras_from_txn_id(path, txn_id): | |
|
724 | _fix_hooks_executables() | |||
|
725 | ||||
719 | extras = {} |
|
726 | extras = {} | |
720 | try: |
|
727 | try: | |
721 | cmd = [settings.SVNLOOK_EXECUTABLE, 'pget', |
|
728 | cmd = [settings.SVNLOOK_EXECUTABLE(), 'pget', | |
722 | '-t', txn_id, |
|
729 | '-t', txn_id, | |
723 | '--revprop', path, 'rc-scm-extras'] |
|
730 | '--revprop', path, 'rc-scm-extras'] | |
724 | stdout, stderr = subprocessio.run_command( |
|
731 | stdout, stderr = subprocessio.run_command( | |
@@ -731,9 +738,11 b' def _get_extras_from_txn_id(path, txn_id' | |||||
731 |
|
738 | |||
732 |
|
739 | |||
733 | def _get_extras_from_commit_id(commit_id, path): |
|
740 | def _get_extras_from_commit_id(commit_id, path): | |
|
741 | _fix_hooks_executables() | |||
|
742 | ||||
734 | extras = {} |
|
743 | extras = {} | |
735 | try: |
|
744 | try: | |
736 | cmd = [settings.SVNLOOK_EXECUTABLE, 'pget', |
|
745 | cmd = [settings.SVNLOOK_EXECUTABLE(), 'pget', | |
737 | '-r', commit_id, |
|
746 | '-r', commit_id, | |
738 | '--revprop', path, 'rc-scm-extras'] |
|
747 | '--revprop', path, 'rc-scm-extras'] | |
739 | stdout, stderr = subprocessio.run_command( |
|
748 | stdout, stderr = subprocessio.run_command( | |
@@ -746,11 +755,11 b' def _get_extras_from_commit_id(commit_id' | |||||
746 |
|
755 | |||
747 |
|
756 | |||
748 | def svn_pre_commit(repo_path, commit_data, env): |
|
757 | def svn_pre_commit(repo_path, commit_data, env): | |
|
758 | ||||
749 | path, txn_id = commit_data |
|
759 | path, txn_id = commit_data | |
750 | branches = [] |
|
760 | branches = [] | |
751 | tags = [] |
|
761 | tags = [] | |
752 |
|
762 | |||
753 | _fix_hooks_executables() |
|
|||
754 | if env.get('RC_SCM_DATA'): |
|
763 | if env.get('RC_SCM_DATA'): | |
755 | extras = json.loads(env['RC_SCM_DATA']) |
|
764 | extras = json.loads(env['RC_SCM_DATA']) | |
756 | else: |
|
765 | else: | |
@@ -790,7 +799,6 b' def svn_post_commit(repo_path, commit_da' | |||||
790 | branches = [] |
|
799 | branches = [] | |
791 | tags = [] |
|
800 | tags = [] | |
792 |
|
801 | |||
793 | _fix_hooks_executables() |
|
|||
794 | if env.get('RC_SCM_DATA'): |
|
802 | if env.get('RC_SCM_DATA'): | |
795 | extras = json.loads(env['RC_SCM_DATA']) |
|
803 | extras = json.loads(env['RC_SCM_DATA']) | |
796 | else: |
|
804 | else: |
@@ -263,11 +263,6 b' class HTTPApplication:' | |||||
263 |
|
263 | |||
264 | settings.BINARY_DIR = binary_dir |
|
264 | settings.BINARY_DIR = binary_dir | |
265 |
|
265 | |||
266 | # from core.binary dir we set executable paths |
|
|||
267 | settings.GIT_EXECUTABLE = os.path.join(binary_dir, settings.GIT_EXECUTABLE) |
|
|||
268 | settings.SVN_EXECUTABLE = os.path.join(binary_dir, settings.SVN_EXECUTABLE) |
|
|||
269 | settings.SVNLOOK_EXECUTABLE = os.path.join(binary_dir, settings.SVNLOOK_EXECUTABLE) |
|
|||
270 |
|
||||
271 | # Store the settings to make them available to other modules. |
|
266 | # Store the settings to make them available to other modules. | |
272 | vcsserver.PYRAMID_SETTINGS = settings_merged |
|
267 | vcsserver.PYRAMID_SETTINGS = settings_merged | |
273 | vcsserver.CONFIG = settings_merged |
|
268 | vcsserver.CONFIG = settings_merged | |
@@ -716,7 +711,9 b' def sanitize_settings_and_apply_defaults' | |||||
716 | settings_maker.make_setting('pyramid.default_locale_name', 'en') |
|
711 | settings_maker.make_setting('pyramid.default_locale_name', 'en') | |
717 | settings_maker.make_setting('locale', 'en_US.UTF-8') |
|
712 | settings_maker.make_setting('locale', 'en_US.UTF-8') | |
718 |
|
713 | |||
719 | settings_maker.make_setting('core.binary_dir', '/usr/local/bin/rhodecode_bin/vcs_bin') |
|
714 | settings_maker.make_setting( | |
|
715 | 'core.binary_dir', '/usr/local/bin/rhodecode_bin/vcs_bin', | |||
|
716 | default_when_empty=True, parser='string:noquote') | |||
720 |
|
717 | |||
721 | temp_store = tempfile.gettempdir() |
|
718 | temp_store = tempfile.gettempdir() | |
722 | default_cache_dir = os.path.join(temp_store, 'rc_cache') |
|
719 | default_cache_dir = os.path.join(temp_store, 'rc_cache') |
@@ -40,7 +40,7 b' from dulwich.repo import Repo as Dulwich' | |||||
40 |
|
40 | |||
41 | import rhodecode |
|
41 | import rhodecode | |
42 | from vcsserver import exceptions, settings, subprocessio |
|
42 | from vcsserver import exceptions, settings, subprocessio | |
43 | from vcsserver.str_utils import safe_str, safe_int, safe_bytes, ascii_bytes, convert_to_str |
|
43 | from vcsserver.str_utils import safe_str, safe_int, safe_bytes, ascii_bytes, convert_to_str, splitnewlines | |
44 | from vcsserver.base import RepoFactory, obfuscate_qs, ArchiveNode, store_archive_in_cache, BytesEnvelope, BinaryEnvelope |
|
44 | from vcsserver.base import RepoFactory, obfuscate_qs, ArchiveNode, store_archive_in_cache, BytesEnvelope, BinaryEnvelope | |
45 | from vcsserver.hgcompat import ( |
|
45 | from vcsserver.hgcompat import ( | |
46 | hg_url as url_parser, httpbasicauthhandler, httpdigestauthhandler) |
|
46 | hg_url as url_parser, httpbasicauthhandler, httpdigestauthhandler) | |
@@ -1347,7 +1347,8 b' class GitRemote(RemoteBase):' | |||||
1347 | with repo_init as repo: |
|
1347 | with repo_init as repo: | |
1348 | commit = repo[commit_id] |
|
1348 | commit = repo[commit_id] | |
1349 | blame_obj = repo.blame(path, newest_commit=commit_id) |
|
1349 | blame_obj = repo.blame(path, newest_commit=commit_id) | |
1350 |
f |
|
1350 | file_content = commit.tree[path].data | |
|
1351 | for i, line in enumerate(splitnewlines(file_content)): | |||
1351 | line_no = i + 1 |
|
1352 | line_no = i + 1 | |
1352 | hunk = blame_obj.for_line(line_no) |
|
1353 | hunk = blame_obj.for_line(line_no) | |
1353 | blame_commit_id = hunk.final_commit_id.hex |
|
1354 | blame_commit_id = hunk.final_commit_id.hex | |
@@ -1423,7 +1424,7 b' class GitRemote(RemoteBase):' | |||||
1423 | gitenv['GIT_CONFIG_NOGLOBAL'] = '1' |
|
1424 | gitenv['GIT_CONFIG_NOGLOBAL'] = '1' | |
1424 | gitenv['GIT_DISCOVERY_ACROSS_FILESYSTEM'] = '1' |
|
1425 | gitenv['GIT_DISCOVERY_ACROSS_FILESYSTEM'] = '1' | |
1425 |
|
1426 | |||
1426 | cmd = [settings.GIT_EXECUTABLE] + _copts + cmd |
|
1427 | cmd = [settings.GIT_EXECUTABLE()] + _copts + cmd | |
1427 | _opts = {'env': gitenv, 'shell': False} |
|
1428 | _opts = {'env': gitenv, 'shell': False} | |
1428 |
|
1429 | |||
1429 | proc = None |
|
1430 | proc = None |
@@ -214,7 +214,7 b' def create_git_wsgi_app(repo_path, repo_' | |||||
214 |
|
214 | |||
215 | :param config: is a dictionary holding the extras. |
|
215 | :param config: is a dictionary holding the extras. | |
216 | """ |
|
216 | """ | |
217 | git_path = settings.GIT_EXECUTABLE |
|
217 | git_path = settings.GIT_EXECUTABLE() | |
218 | update_server_info = config.pop('git_update_server_info') |
|
218 | update_server_info = config.pop('git_update_server_info') | |
219 | app = GitHandler( |
|
219 | app = GitHandler( | |
220 | repo_path, repo_name, git_path, update_server_info, config) |
|
220 | repo_path, repo_name, git_path, update_server_info, config) | |
@@ -244,7 +244,7 b' class GitLFSHandler:' | |||||
244 |
|
244 | |||
245 |
|
245 | |||
246 | def create_git_lfs_wsgi_app(repo_path, repo_name, config): |
|
246 | def create_git_lfs_wsgi_app(repo_path, repo_name, config): | |
247 | git_path = settings.GIT_EXECUTABLE |
|
247 | git_path = settings.GIT_EXECUTABLE() | |
248 | update_server_info = config.pop('git_update_server_info') |
|
248 | update_server_info = config.pop('git_update_server_info') | |
249 | git_lfs_enabled = config.pop('git_lfs_enabled') |
|
249 | git_lfs_enabled = config.pop('git_lfs_enabled') | |
250 | git_lfs_store_path = config.pop('git_lfs_store_path') |
|
250 | git_lfs_store_path = config.pop('git_lfs_store_path') |
@@ -14,9 +14,18 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 os | |||
17 |
|
18 | |||
18 | WIRE_ENCODING = 'UTF-8' |
|
19 | WIRE_ENCODING = 'UTF-8' | |
19 | GIT_EXECUTABLE = 'git' |
|
20 | ||
20 | SVN_EXECUTABLE = 'svn' |
|
21 | # Path where we can find binary dir | |
21 | SVNLOOK_EXECUTABLE = 'svnlook' |
|
|||
22 | BINARY_DIR = '' |
|
22 | BINARY_DIR = '' | |
|
23 | ||||
|
24 | def GIT_EXECUTABLE() -> str: | |||
|
25 | return os.environ.get('RC_GIT_EXECUTABLE') or os.path.join(BINARY_DIR, 'git') | |||
|
26 | ||||
|
27 | def SVN_EXECUTABLE() -> str: | |||
|
28 | return os.environ.get('RC_SVN_EXECUTABLE') or os.path.join(BINARY_DIR, 'svn') | |||
|
29 | ||||
|
30 | def SVNLOOK_EXECUTABLE() -> str: | |||
|
31 | return os.environ.get('RC_SVNLOOK_EXECUTABLE') or os.path.join(BINARY_DIR, 'svnlook') |
@@ -142,3 +142,17 b' def convert_to_str(data):' | |||||
142 | return list(convert_to_str(item) for item in data) |
|
142 | return list(convert_to_str(item) for item in data) | |
143 | else: |
|
143 | else: | |
144 | return data |
|
144 | return data | |
|
145 | ||||
|
146 | ||||
|
147 | def splitnewlines(text: bytes): | |||
|
148 | """ | |||
|
149 | like splitlines, but only split on newlines. | |||
|
150 | """ | |||
|
151 | ||||
|
152 | lines = [_l + b'\n' for _l in text.split(b'\n')] | |||
|
153 | if lines: | |||
|
154 | if lines[-1] == b'\n': | |||
|
155 | lines.pop() | |||
|
156 | else: | |||
|
157 | lines[-1] = lines[-1][:-1] | |||
|
158 | return lines No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now