##// END OF EJS Templates
git-lfs: settings for GIT repos to enable git-lfs and set store location...
marcink -
r1570:f2271c3d default
parent child Browse files
Show More
@@ -82,7 +82,7 b' class SettingsController(BaseController)'
82 82 rhodecode.CONFIG.get('labs_settings_active', 'true'))
83 83 c.navlist = navigation_list(request)
84 84
85 def _get_hg_ui_settings(self):
85 def _get_ui_settings(self):
86 86 ret = RhodeCodeUi.query().all()
87 87
88 88 if not ret:
@@ -94,7 +94,7 b' class SettingsController(BaseController)'
94 94 if k == '/':
95 95 k = 'root_path'
96 96
97 if k in ['push_ssl', 'publish']:
97 if k in ['push_ssl', 'publish', 'enabled']:
98 98 v = str2bool(v)
99 99
100 100 if k.find('.') != -1:
@@ -165,6 +165,7 b' class SettingsController(BaseController)'
165 165
166 166 model.create_or_update_global_svn_settings(form_result)
167 167 model.create_or_update_global_hg_settings(form_result)
168 model.create_or_update_global_git_settings(form_result)
168 169 model.create_or_update_global_pr_settings(form_result)
169 170 except Exception:
170 171 log.exception("Exception while updating settings")
@@ -668,7 +669,8 b' class SettingsController(BaseController)'
668 669
669 670 def _form_defaults(self):
670 671 defaults = SettingsModel().get_all_settings()
671 defaults.update(self._get_hg_ui_settings())
672 defaults.update(self._get_ui_settings())
673
672 674 defaults.update({
673 675 'new_svn_branch': '',
674 676 'new_svn_tag': '',
@@ -378,13 +378,19 b' class _BaseVcsSettingsForm(formencode.Sc'
378 378 hooks_changegroup_push_logger = v.StringBoolean(if_missing=False)
379 379 hooks_outgoing_pull_logger = v.StringBoolean(if_missing=False)
380 380
381 # PR/Code-review
382 rhodecode_pr_merge_enabled = v.StringBoolean(if_missing=False)
383 rhodecode_use_outdated_comments = v.StringBoolean(if_missing=False)
384
385 # hg
381 386 extensions_largefiles = v.StringBoolean(if_missing=False)
382 387 phases_publish = v.StringBoolean(if_missing=False)
383
384 rhodecode_pr_merge_enabled = v.StringBoolean(if_missing=False)
385 rhodecode_use_outdated_comments = v.StringBoolean(if_missing=False)
386 388 rhodecode_hg_use_rebase_for_merging = v.StringBoolean(if_missing=False)
387 389
390 # git
391 vcs_git_lfs_enabled = v.StringBoolean(if_missing=False)
392
393 # svn
388 394 vcs_svn_proxy_http_requests_enabled = v.StringBoolean(if_missing=False)
389 395 vcs_svn_proxy_http_server_url = v.UnicodeString(strip=True, if_missing=None)
390 396
@@ -398,8 +404,10 b' def ApplicationUiSettingsForm():'
398 404 )
399 405 largefiles_usercache = All(
400 406 v.ValidPath(),
401 v.UnicodeString(strip=True, min=2, not_empty=True)
402 )
407 v.UnicodeString(strip=True, min=2, not_empty=True))
408 vcs_git_lfs_store_location = All(
409 v.ValidPath(),
410 v.UnicodeString(strip=True, min=2, not_empty=True))
403 411 extensions_hgsubversion = v.StringBoolean(if_missing=False)
404 412 extensions_hggit = v.StringBoolean(if_missing=False)
405 413 new_svn_branch = v.ValidSvnPattern(section='vcs_svn_branch')
@@ -410,15 +410,21 b' class VcsSettingsModel(object):'
410 410 HOOKS_SETTINGS = (
411 411 ('hooks', 'changegroup.repo_size'),
412 412 ('hooks', 'changegroup.push_logger'),
413 ('hooks', 'outgoing.pull_logger'))
413 ('hooks', 'outgoing.pull_logger'),)
414 414 HG_SETTINGS = (
415 415 ('extensions', 'largefiles'),
416 ('phases', 'publish'))
416 ('phases', 'publish'),)
417 GIT_SETTINGS = (
418 ('vcs_git_lfs', 'enabled'),)
419
417 420 GLOBAL_HG_SETTINGS = (
418 421 ('extensions', 'largefiles'),
419 422 ('largefiles', 'usercache'),
420 423 ('phases', 'publish'),
421 424 ('extensions', 'hgsubversion'))
425 GLOBAL_GIT_SETTINGS = (
426 ('vcs_git_lfs', 'enabled'),
427 ('vcs_git_lfs', 'store_location'))
422 428 GLOBAL_SVN_SETTINGS = (
423 429 ('vcs_svn_proxy', 'http_requests_enabled'),
424 430 ('vcs_svn_proxy', 'http_server_url'))
@@ -431,7 +437,8 b' class VcsSettingsModel(object):'
431 437 def __init__(self, sa=None, repo=None):
432 438 self.global_settings = SettingsModel(sa=sa)
433 439 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
434 self._ui_settings = self.HG_SETTINGS + self.HOOKS_SETTINGS
440 self._ui_settings = (
441 self.HG_SETTINGS + self.GIT_SETTINGS + self.HOOKS_SETTINGS)
435 442 self._svn_sections = (self.SVN_BRANCH_SECTION, self.SVN_TAG_SECTION)
436 443
437 444 @property
@@ -485,6 +492,9 b' class VcsSettingsModel(object):'
485 492 if repo.repo_type == 'hg':
486 493 self.create_or_update_repo_hg_settings(data)
487 494
495 if repo.repo_type == 'git':
496 self.create_or_update_repo_git_settings(data)
497
488 498 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
489 499
490 500 @assert_repo_settings
@@ -534,9 +544,11 b' class VcsSettingsModel(object):'
534 544
535 545 @assert_repo_settings
536 546 def create_or_update_repo_hg_settings(self, data):
537 largefiles, phases = self.HG_SETTINGS
538 largefiles_key, phases_key = self._get_settings_keys(
539 self.HG_SETTINGS, data)
547 largefiles, phases = \
548 self.HG_SETTINGS
549 largefiles_key, phases_key = \
550 self._get_settings_keys(self.HG_SETTINGS, data)
551
540 552 self._create_or_update_ui(
541 553 self.repo_settings, *largefiles, value='',
542 554 active=data[largefiles_key])
@@ -548,7 +560,6 b' class VcsSettingsModel(object):'
548 560 = self.GLOBAL_HG_SETTINGS
549 561 largefiles_key, largefiles_store_key, phases_key, subversion_key \
550 562 = self._get_settings_keys(self.GLOBAL_HG_SETTINGS, data)
551
552 563 self._create_or_update_ui(
553 564 self.global_settings, *largefiles, value='',
554 565 active=data[largefiles_key])
@@ -560,6 +571,31 b' class VcsSettingsModel(object):'
560 571 self._create_or_update_ui(
561 572 self.global_settings, *hgsubversion, active=data[subversion_key])
562 573
574 def create_or_update_repo_git_settings(self, data):
575 # NOTE(marcink): # comma make unpack work properly
576 lfs_enabled, \
577 = self.GIT_SETTINGS
578
579 lfs_enabled_key, \
580 = self._get_settings_keys(self.GIT_SETTINGS, data)
581
582 self._create_or_update_ui(
583 self.repo_settings, *lfs_enabled, value=data[lfs_enabled_key],
584 active=data[lfs_enabled_key])
585
586 def create_or_update_global_git_settings(self, data):
587 lfs_enabled, lfs_store_location \
588 = self.GLOBAL_GIT_SETTINGS
589 lfs_enabled_key, lfs_store_location_key \
590 = self._get_settings_keys(self.GLOBAL_GIT_SETTINGS, data)
591
592 self._create_or_update_ui(
593 self.global_settings, *lfs_enabled, value=data[lfs_enabled_key],
594 active=data[lfs_enabled_key])
595 self._create_or_update_ui(
596 self.global_settings, *lfs_store_location,
597 value=data[lfs_store_location_key])
598
563 599 def create_or_update_global_svn_settings(self, data):
564 600 # branch/tags patterns
565 601 self._create_svn_settings(self.global_settings, data)
@@ -677,9 +713,12 b' class VcsSettingsModel(object):'
677 713 for section, key in self._ui_settings:
678 714 ui = settings.get_ui_by_section_and_key(section, key)
679 715 result_key = self._get_form_ui_key(section, key)
716
680 717 if ui:
681 718 if section in ('hooks', 'extensions'):
682 719 result[result_key] = ui.ui_active
720 elif result_key in ['vcs_git_lfs_enabled']:
721 result[result_key] = ui.ui_active
683 722 else:
684 723 result[result_key] = ui.ui_value
685 724
@@ -154,6 +154,39 b''
154 154
155 155 % endif
156 156
157 % if display_globals or repo_type in ['git']:
158 <div class="panel panel-default">
159 <div class="panel-heading">
160 <h3 class="panel-title">${_('Git Settings')}</h3>
161 </div>
162 <div class="panel-body">
163 <div class="checkbox">
164 ${h.checkbox('vcs_git_lfs_enabled' + suffix, 'True', **kwargs)}
165 <label for="vcs_git_lfs_enabled${suffix}">${_('Enable lfs extension')}</label>
166 </div>
167 <div class="label">
168 % if display_globals:
169 <span class="help-block">${_('Enable lfs extensions for all repositories.')}</span>
170 % else:
171 <span class="help-block">${_('Enable lfs extensions for this repository.')}</span>
172 % endif
173 </div>
174
175 % if display_globals:
176 <div class="field">
177 <div class="input">
178 ${h.text('vcs_git_lfs_store_location' + suffix, size=59)}
179 </div>
180 </div>
181 <div class="label">
182 <span class="help-block">${_('Filesystem location where Git lfs objects should be stored.')}</span>
183 </div>
184 % endif
185 </div>
186 </div>
187 % endif
188
189
157 190 % if display_globals:
158 191 <div class="panel panel-default">
159 192 <div class="panel-heading">
@@ -20,7 +20,10 b''
20 20
21 21 import pytest
22 22 import urlparse
23 import mock
24 import simplejson as json
23 25
26 from rhodecode.lib.vcs.backends.base import Config
24 27 from rhodecode.tests.lib.middleware import mock_scm_app
25 28 import rhodecode.lib.middleware.simplegit as simplegit
26 29
@@ -107,22 +110,24 b' def test_get_repository_name(url, expect'
107 110 get_environ(url, request_method))
108 111
109 112
110 def test_get_config(pylonsapp):
113 def test_get_config(pylonsapp, user_util):
114 repo = user_util.create_repo(repo_type='git')
111 115 app = simplegit.SimpleGit(application=None,
112 116 config={'auth_ret_code': '', 'base_path': ''},
113 117 registry=None)
114 118 extras = {'foo': 'FOO', 'bar': 'BAR'}
115 119
116 120 # We copy the extras as the method below will change the contents.
117 config = app._create_config(dict(extras), repo_name='test-repo')
121 git_config = app._create_config(dict(extras), repo_name=repo.repo_name)
122
118 123 expected_config = dict(extras)
119 124 expected_config.update({
120 125 'git_update_server_info': False,
121 'git_lfs_enabled': True,
122 'git_lfs_store_path': simplegit.default_lfs_store()
126 'git_lfs_enabled': False,
127 'git_lfs_store_path': git_config['git_lfs_store_path']
123 128 })
124 129
125 assert config == expected_config
130 assert git_config == expected_config
126 131
127 132
128 133 def test_create_wsgi_app_uses_scm_app_from_simplevcs(pylonsapp):
@@ -78,30 +78,42 b' def test_get_repository_name(url, expect'
78 78 assert expected_repo_name == app._get_repository_name(get_environ(url))
79 79
80 80
81 def test_get_config():
81 def test_get_config(pylonsapp, user_util):
82 repo = user_util.create_repo(repo_type='git')
82 83 app = simplehg.SimpleHg(application=None,
83 84 config={'auth_ret_code': '', 'base_path': ''},
84 85 registry=None)
85 86 extras = {'foo': 'FOO', 'bar': 'BAR'}
86 87
87 mock_config = Config()
88 mock_config.set('a1', 'b1', 'c1')
89 mock_config.set('a2', 'b2', 'c2')
90 # We mock the call to make_db_config, otherwise we need to wait for the
91 # pylonsaspp
92 with mock.patch('rhodecode.lib.utils.make_db_config',
93 return_value=mock_config) as make_db_config_mock:
94 hg_config = app._create_config(extras, repo_name='test-repo')
88 hg_config = app._create_config(extras, repo_name=repo.repo_name)
89
90 config = simplehg.utils.make_db_config(repo=repo.repo_name)
91 config.set('rhodecode', 'RC_SCM_DATA', json.dumps(extras))
92 hg_config_org = config
95 93
96 make_db_config_mock.assert_called_once_with(repo='test-repo')
97 assert isinstance(hg_config, list)
98
99 # Remove the entries from the mock_config so to get only the extras
100 hg_config.remove(('a1', 'b1', 'c1'))
101 hg_config.remove(('a2', 'b2', 'c2'))
102
103 assert hg_config[0][:2] == ('rhodecode', 'RC_SCM_DATA')
104 assert json.loads(hg_config[0][-1]) == extras
94 expected_config = [
95 ('vcs_svn_tag', 'ff89f8c714d135d865f44b90e5413b88de19a55f', '/tags/*'),
96 ('web', 'push_ssl', 'False'),
97 ('web', 'allow_push', '*'),
98 ('web', 'allow_archive', 'gz zip bz2'),
99 ('web', 'baseurl', '/'),
100 ('vcs_git_lfs', 'store_location', hg_config_org.get('vcs_git_lfs', 'store_location')),
101 ('vcs_svn_branch', '9aac1a38c3b8a0cdc4ae0f960a5f83332bc4fa5e', '/branches/*'),
102 ('vcs_svn_branch', 'c7e6a611c87da06529fd0dd733308481d67c71a8', '/trunk'),
103 ('largefiles', 'usercache', hg_config_org.get('largefiles', 'usercache')),
104 ('hooks', 'preoutgoing.pre_pull', 'python:vcsserver.hooks.pre_pull'),
105 ('hooks', 'prechangegroup.pre_push', 'python:vcsserver.hooks.pre_push'),
106 ('hooks', 'outgoing.pull_logger', 'python:vcsserver.hooks.log_pull_action'),
107 ('hooks', 'pretxnchangegroup.pre_push', 'python:vcsserver.hooks.pre_push'),
108 ('hooks', 'changegroup.push_logger', 'python:vcsserver.hooks.log_push_action'),
109 ('hooks', 'changegroup.repo_size', 'python:vcsserver.hooks.repo_size'),
110 ('phases', 'publish', 'True'),
111 ('extensions', 'largefiles', ''),
112 ('paths', '/', hg_config_org.get('paths', '/')),
113 ('rhodecode', 'RC_SCM_DATA', '{"foo": "FOO", "bar": "BAR"}')
114 ]
115 for entry in expected_config:
116 assert entry in hg_config
105 117
106 118
107 119 def test_create_wsgi_app_uses_scm_app_from_simplevcs():
@@ -176,7 +176,7 b' class TestVcsSettingsModel(object):'
176 176 settings_mock.get_setting_by_name.return_value = result_mock
177 177 result = model._collect_all_settings(global_=global_)
178 178
179 ui_settings = model.HG_SETTINGS + model.HOOKS_SETTINGS
179 ui_settings = model.HG_SETTINGS + model.GIT_SETTINGS + model.HOOKS_SETTINGS
180 180 self._assert_get_settings_calls(
181 181 settings_mock, ui_settings, model.GENERAL_SETTINGS)
182 182 self._assert_collect_all_settings_result(
@@ -230,7 +230,13 b' class TestVcsSettingsModel(object):'
230 230 expected_result = {}
231 231 for section, key in ui_settings:
232 232 key = '{}_{}'.format(section, key.replace('.', '_'))
233 value = True if section in ('extensions', 'hooks') else 'ui_value'
233
234 if section in ('extensions', 'hooks'):
235 value = True
236 elif key in ['vcs_git_lfs_enabled']:
237 value = True
238 else:
239 value = 'ui_value'
234 240 expected_result[key] = value
235 241
236 242 for name in general_settings:
@@ -599,6 +605,25 b' class TestCreateOrUpdateGlobalHgSettings'
599 605 assert exc_info.value.message == expected_message
600 606
601 607
608 class TestCreateOrUpdateGlobalGitSettings(object):
609 FORM_DATA = {
610 'vcs_git_lfs_enabled': False,
611 'vcs_git_lfs_store_location': '/example/lfs-store',
612 }
613
614 def test_creates_repo_hg_settings_when_data_is_correct(self):
615 model = VcsSettingsModel()
616 with mock.patch.object(model, '_create_or_update_ui') as create_mock:
617 model.create_or_update_global_git_settings(self.FORM_DATA)
618 expected_calls = [
619 mock.call(model.global_settings, 'vcs_git_lfs', 'enabled',
620 active=False, value=False),
621 mock.call(model.global_settings, 'vcs_git_lfs', 'store_location',
622 value='/example/lfs-store'),
623 ]
624 assert expected_calls == create_mock.call_args_list
625
626
602 627 class TestDeleteRepoSvnPattern(object):
603 628 def test_success_when_repo_is_set(self, backend_svn):
604 629 repo_name = backend_svn.repo_name
@@ -933,6 +958,8 b' class TestCreateOrUpdateRepoSettings(obj'
933 958 'hooks_outgoing_pull_logger': False,
934 959 'extensions_largefiles': False,
935 960 'largefiles_usercache': '/example/largefiles-store',
961 'vcs_git_lfs_enabled': False,
962 'vcs_git_lfs_store_location': '/',
936 963 'phases_publish': 'False',
937 964 'rhodecode_pr_merge_enabled': False,
938 965 'rhodecode_use_outdated_comments': False,
General Comments 0
You need to be logged in to leave comments. Login now