Mercurial > kallithea
comparison rhodecode/lib/utils.py @ 2776:63e58ef80ef1
Merge beta branch into stable
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sun, 02 Sep 2012 21:19:54 +0200 |
parents | a437a986d399 dd240b2b7a12 |
children | 9ae95fdeca18 |
comparison
equal
deleted
inserted
replaced
2301:9d097c2592d3 | 2776:63e58ef80ef1 |
---|---|
49 | 49 |
50 from rhodecode.lib.caching_query import FromCache | 50 from rhodecode.lib.caching_query import FromCache |
51 | 51 |
52 from rhodecode.model import meta | 52 from rhodecode.model import meta |
53 from rhodecode.model.db import Repository, User, RhodeCodeUi, \ | 53 from rhodecode.model.db import Repository, User, RhodeCodeUi, \ |
54 UserLog, RepoGroup, RhodeCodeSetting, UserRepoGroupToPerm,\ | 54 UserLog, RepoGroup, RhodeCodeSetting, CacheInvalidation |
55 CacheInvalidation | |
56 from rhodecode.model.meta import Session | 55 from rhodecode.model.meta import Session |
57 from rhodecode.model.repos_group import ReposGroupModel | 56 from rhodecode.model.repos_group import ReposGroupModel |
58 from rhodecode.lib.utils2 import safe_str, safe_unicode | 57 from rhodecode.lib.utils2 import safe_str, safe_unicode |
59 from rhodecode.lib.vcs.utils.fakemod import create_module | 58 from rhodecode.lib.vcs.utils.fakemod import create_module |
60 | 59 |
127 :param sa: optional sqlalchemy session | 126 :param sa: optional sqlalchemy session |
128 | 127 |
129 """ | 128 """ |
130 | 129 |
131 if not sa: | 130 if not sa: |
132 sa = meta.Session | 131 sa = meta.Session() |
133 | 132 |
134 try: | 133 try: |
135 if hasattr(user, 'user_id'): | 134 if hasattr(user, 'user_id'): |
136 user_obj = user | 135 user_obj = user |
137 elif isinstance(user, basestring): | 136 elif isinstance(user, basestring): |
144 repo_name = repo_obj.repo_name | 143 repo_name = repo_obj.repo_name |
145 elif isinstance(repo, basestring): | 144 elif isinstance(repo, basestring): |
146 repo_name = repo.lstrip('/') | 145 repo_name = repo.lstrip('/') |
147 repo_obj = Repository.get_by_repo_name(repo_name) | 146 repo_obj = Repository.get_by_repo_name(repo_name) |
148 else: | 147 else: |
149 raise Exception('You have to provide repository to action logger') | 148 repo_obj = None |
149 repo_name = '' | |
150 | 150 |
151 user_log = UserLog() | 151 user_log = UserLog() |
152 user_log.user_id = user_obj.user_id | 152 user_log.user_id = user_obj.user_id |
153 user_log.action = safe_unicode(action) | 153 user_log.action = safe_unicode(action) |
154 | 154 |
155 user_log.repository_id = repo_obj.repo_id | 155 user_log.repository = repo_obj |
156 user_log.repository_name = repo_name | 156 user_log.repository_name = repo_name |
157 | 157 |
158 user_log.action_date = datetime.datetime.now() | 158 user_log.action_date = datetime.datetime.now() |
159 user_log.user_ip = ipaddr | 159 user_log.user_ip = ipaddr |
160 sa.add(user_log) | 160 sa.add(user_log) |
201 yield inner_scm | 201 yield inner_scm |
202 | 202 |
203 return _get_repos(path) | 203 return _get_repos(path) |
204 | 204 |
205 | 205 |
206 def is_valid_repo(repo_name, base_path): | 206 def is_valid_repo(repo_name, base_path, scm=None): |
207 """ | 207 """ |
208 Returns True if given path is a valid repository False otherwise | 208 Returns True if given path is a valid repository False otherwise. |
209 If scm param is given also compare if given scm is the same as expected | |
210 from scm parameter | |
209 | 211 |
210 :param repo_name: | 212 :param repo_name: |
211 :param base_path: | 213 :param base_path: |
214 :param scm: | |
212 | 215 |
213 :return True: if given path is a valid repository | 216 :return True: if given path is a valid repository |
214 """ | 217 """ |
215 full_path = os.path.join(safe_str(base_path), safe_str(repo_name)) | 218 full_path = os.path.join(safe_str(base_path), safe_str(repo_name)) |
216 | 219 |
217 try: | 220 try: |
218 get_scm(full_path) | 221 scm_ = get_scm(full_path) |
222 if scm: | |
223 return scm_[0] == scm | |
219 return True | 224 return True |
220 except VCSError: | 225 except VCSError: |
221 return False | 226 return False |
222 | 227 |
223 | 228 |
231 full_path = os.path.join(safe_str(base_path), safe_str(repos_group_name)) | 236 full_path = os.path.join(safe_str(base_path), safe_str(repos_group_name)) |
232 | 237 |
233 # check if it's not a repo | 238 # check if it's not a repo |
234 if is_valid_repo(repos_group_name, base_path): | 239 if is_valid_repo(repos_group_name, base_path): |
235 return False | 240 return False |
241 | |
242 try: | |
243 # we need to check bare git repos at higher level | |
244 # since we might match branches/hooks/info/objects or possible | |
245 # other things inside bare git repo | |
246 get_scm(os.path.dirname(full_path)) | |
247 return False | |
248 except VCSError: | |
249 pass | |
236 | 250 |
237 # check if it's a valid path | 251 # check if it's a valid path |
238 if os.path.isdir(full_path): | 252 if os.path.isdir(full_path): |
239 return True | 253 return True |
240 | 254 |
264 'paths', 'profiling', | 278 'paths', 'profiling', |
265 'server', 'trusted', | 279 'server', 'trusted', |
266 'ui', 'web', ] | 280 'ui', 'web', ] |
267 | 281 |
268 | 282 |
269 def make_ui(read_from='file', path=None, checkpaths=True): | 283 def make_ui(read_from='file', path=None, checkpaths=True, clear_session=True): |
270 """ | 284 """ |
271 A function that will read python rc files or database | 285 A function that will read python rc files or database |
272 and make an mercurial ui object from read options | 286 and make an mercurial ui object from read options |
273 | 287 |
274 :param path: path to mercurial config file | 288 :param path: path to mercurial config file |
294 for k, v in cfg.items(section): | 308 for k, v in cfg.items(section): |
295 log.debug('settings ui from file[%s]%s:%s' % (section, k, v)) | 309 log.debug('settings ui from file[%s]%s:%s' % (section, k, v)) |
296 baseui.setconfig(section, k, v) | 310 baseui.setconfig(section, k, v) |
297 | 311 |
298 elif read_from == 'db': | 312 elif read_from == 'db': |
299 sa = meta.Session | 313 sa = meta.Session() |
300 ret = sa.query(RhodeCodeUi)\ | 314 ret = sa.query(RhodeCodeUi)\ |
301 .options(FromCache("sql_cache_short", "get_hg_ui_settings"))\ | 315 .options(FromCache("sql_cache_short", "get_hg_ui_settings"))\ |
302 .all() | 316 .all() |
303 | 317 |
304 hg_ui = ret | 318 hg_ui = ret |
305 for ui_ in hg_ui: | 319 for ui_ in hg_ui: |
306 if ui_.ui_active: | 320 if ui_.ui_active: |
307 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section, | 321 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section, |
308 ui_.ui_key, ui_.ui_value) | 322 ui_.ui_key, ui_.ui_value) |
309 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value) | 323 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value) |
310 | 324 if ui_.ui_key == 'push_ssl': |
311 meta.Session.remove() | 325 # force set push_ssl requirement to False, rhodecode |
326 # handles that | |
327 baseui.setconfig(ui_.ui_section, ui_.ui_key, False) | |
328 if clear_session: | |
329 meta.Session.remove() | |
312 return baseui | 330 return baseui |
313 | 331 |
314 | 332 |
315 def set_rhodecode_config(config): | 333 def set_rhodecode_config(config): |
316 """ | 334 """ |
335 if cache_key.startswith('get_repo_cached_'): | 353 if cache_key.startswith('get_repo_cached_'): |
336 name = cache_key.split('get_repo_cached_')[-1] | 354 name = cache_key.split('get_repo_cached_')[-1] |
337 ScmModel().mark_for_invalidation(name) | 355 ScmModel().mark_for_invalidation(name) |
338 | 356 |
339 | 357 |
340 class EmptyChangeset(BaseChangeset): | |
341 """ | |
342 An dummy empty changeset. It's possible to pass hash when creating | |
343 an EmptyChangeset | |
344 """ | |
345 | |
346 def __init__(self, cs='0' * 40, repo=None, requested_revision=None, | |
347 alias=None): | |
348 self._empty_cs = cs | |
349 self.revision = -1 | |
350 self.message = '' | |
351 self.author = '' | |
352 self.date = '' | |
353 self.repository = repo | |
354 self.requested_revision = requested_revision | |
355 self.alias = alias | |
356 | |
357 @LazyProperty | |
358 def raw_id(self): | |
359 """ | |
360 Returns raw string identifying this changeset, useful for web | |
361 representation. | |
362 """ | |
363 | |
364 return self._empty_cs | |
365 | |
366 @LazyProperty | |
367 def branch(self): | |
368 return get_backend(self.alias).DEFAULT_BRANCH_NAME | |
369 | |
370 @LazyProperty | |
371 def short_id(self): | |
372 return self.raw_id[:12] | |
373 | |
374 def get_file_changeset(self, path): | |
375 return self | |
376 | |
377 def get_file_content(self, path): | |
378 return u'' | |
379 | |
380 def get_file_size(self, path): | |
381 return 0 | |
382 | |
383 | |
384 def map_groups(path): | 358 def map_groups(path): |
385 """ | 359 """ |
386 Given a full path to a repository, create all nested groups that this | 360 Given a full path to a repository, create all nested groups that this |
387 repo is inside. This function creates parent-child relationships between | 361 repo is inside. This function creates parent-child relationships between |
388 groups and creates default perms for all new groups. | 362 groups and creates default perms for all new groups. |
389 | 363 |
390 :param paths: full path to repository | 364 :param paths: full path to repository |
391 """ | 365 """ |
392 sa = meta.Session | 366 sa = meta.Session() |
393 groups = path.split(Repository.url_sep()) | 367 groups = path.split(Repository.url_sep()) |
394 parent = None | 368 parent = None |
395 group = None | 369 group = None |
396 | 370 |
397 # last element is repo in nested groups structure | 371 # last element is repo in nested groups structure |
416 sa.flush() | 390 sa.flush() |
417 parent = group | 391 parent = group |
418 return group | 392 return group |
419 | 393 |
420 | 394 |
421 def repo2db_mapper(initial_repo_list, remove_obsolete=False): | 395 def repo2db_mapper(initial_repo_list, remove_obsolete=False, |
396 install_git_hook=False): | |
422 """ | 397 """ |
423 maps all repos given in initial_repo_list, non existing repositories | 398 maps all repos given in initial_repo_list, non existing repositories |
424 are created, if remove_obsolete is True it also check for db entries | 399 are created, if remove_obsolete is True it also check for db entries |
425 that are not in initial_repo_list and removes them. | 400 that are not in initial_repo_list and removes them. |
426 | 401 |
427 :param initial_repo_list: list of repositories found by scanning methods | 402 :param initial_repo_list: list of repositories found by scanning methods |
428 :param remove_obsolete: check for obsolete entries in database | 403 :param remove_obsolete: check for obsolete entries in database |
404 :param install_git_hook: if this is True, also check and install githook | |
405 for a repo if missing | |
429 """ | 406 """ |
430 from rhodecode.model.repo import RepoModel | 407 from rhodecode.model.repo import RepoModel |
431 sa = meta.Session | 408 from rhodecode.model.scm import ScmModel |
409 sa = meta.Session() | |
432 rm = RepoModel() | 410 rm = RepoModel() |
433 user = sa.query(User).filter(User.admin == True).first() | 411 user = sa.query(User).filter(User.admin == True).first() |
434 if user is None: | 412 if user is None: |
435 raise Exception('Missing administrative account !') | 413 raise Exception('Missing administrative account !') |
436 added = [] | 414 added = [] |
437 | 415 |
438 for name, repo in initial_repo_list.items(): | 416 for name, repo in initial_repo_list.items(): |
439 group = map_groups(name) | 417 group = map_groups(name) |
440 if not rm.get_by_repo_name(name, cache=False): | 418 db_repo = rm.get_by_repo_name(name) |
441 log.info('repository %s not found creating default' % name) | 419 # found repo that is on filesystem not in RhodeCode database |
420 if not db_repo: | |
421 log.info('repository %s not found creating now' % name) | |
442 added.append(name) | 422 added.append(name) |
443 form_data = { | 423 desc = (repo.description |
444 'repo_name': name, | 424 if repo.description != 'unknown' |
445 'repo_name_full': name, | 425 else '%s repository' % name) |
446 'repo_type': repo.alias, | 426 new_repo = rm.create_repo( |
447 'description': repo.description \ | 427 repo_name=name, |
448 if repo.description != 'unknown' else '%s repository' % name, | 428 repo_type=repo.alias, |
449 'private': False, | 429 description=desc, |
450 'group_id': getattr(group, 'group_id', None) | 430 repos_group=getattr(group, 'group_id', None), |
451 } | 431 owner=user, |
452 rm.create(form_data, user, just_db=True) | 432 just_db=True |
433 ) | |
434 # we added that repo just now, and make sure it has githook | |
435 # installed | |
436 if new_repo.repo_type == 'git': | |
437 ScmModel().install_git_hook(new_repo.scm_instance) | |
438 elif install_git_hook: | |
439 if db_repo.repo_type == 'git': | |
440 ScmModel().install_git_hook(db_repo.scm_instance) | |
453 sa.commit() | 441 sa.commit() |
454 removed = [] | 442 removed = [] |
455 if remove_obsolete: | 443 if remove_obsolete: |
456 # remove from database those repositories that are not in the filesystem | 444 # remove from database those repositories that are not in the filesystem |
457 for repo in sa.query(Repository).all(): | 445 for repo in sa.query(Repository).all(): |
458 if repo.repo_name not in initial_repo_list.keys(): | 446 if repo.repo_name not in initial_repo_list.keys(): |
459 log.debug("Removing non existing repository found in db %s" % | 447 log.debug("Removing non existing repository found in db `%s`" % |
460 repo.repo_name) | 448 repo.repo_name) |
461 removed.append(repo.repo_name) | 449 try: |
462 sa.delete(repo) | 450 sa.delete(repo) |
463 sa.commit() | 451 sa.commit() |
452 removed.append(repo.repo_name) | |
453 except: | |
454 #don't hold further removals on error | |
455 log.error(traceback.format_exc()) | |
456 sa.rollback() | |
464 | 457 |
465 # clear cache keys | 458 # clear cache keys |
466 log.debug("Clearing cache keys now...") | 459 log.debug("Clearing cache keys now...") |
467 CacheInvalidation.clear_cache() | 460 CacheInvalidation.clear_cache() |
468 sa.commit() | 461 sa.commit() |
555 """ | 548 """ |
556 Makes a fresh database and | 549 Makes a fresh database and |
557 install test repository into tmp dir | 550 install test repository into tmp dir |
558 """ | 551 """ |
559 from rhodecode.lib.db_manage import DbManage | 552 from rhodecode.lib.db_manage import DbManage |
560 from rhodecode.tests import HG_REPO, TESTS_TMP_PATH | 553 from rhodecode.tests import HG_REPO, GIT_REPO, TESTS_TMP_PATH |
561 | 554 |
562 # PART ONE create db | 555 # PART ONE create db |
563 dbconf = config['sqlalchemy.db1.url'] | 556 dbconf = config['sqlalchemy.db1.url'] |
564 log.debug('making test db %s' % dbconf) | 557 log.debug('making test db %s' % dbconf) |
565 | 558 |
574 dbmanage.create_settings(dbmanage.config_prompt(repos_test_path)) | 567 dbmanage.create_settings(dbmanage.config_prompt(repos_test_path)) |
575 dbmanage.create_default_user() | 568 dbmanage.create_default_user() |
576 dbmanage.admin_prompt() | 569 dbmanage.admin_prompt() |
577 dbmanage.create_permissions() | 570 dbmanage.create_permissions() |
578 dbmanage.populate_default_permissions() | 571 dbmanage.populate_default_permissions() |
579 Session.commit() | 572 Session().commit() |
580 # PART TWO make test repo | 573 # PART TWO make test repo |
581 log.debug('making test vcs repositories') | 574 log.debug('making test vcs repositories') |
582 | 575 |
583 idx_path = config['app_conf']['index_dir'] | 576 idx_path = config['app_conf']['index_dir'] |
584 data_path = config['app_conf']['cache_dir'] | 577 data_path = config['app_conf']['cache_dir'] |
590 | 583 |
591 if data_path and os.path.exists(data_path): | 584 if data_path and os.path.exists(data_path): |
592 log.debug('remove %s' % data_path) | 585 log.debug('remove %s' % data_path) |
593 shutil.rmtree(data_path) | 586 shutil.rmtree(data_path) |
594 | 587 |
595 #CREATE DEFAULT HG REPOSITORY | 588 #CREATE DEFAULT TEST REPOS |
596 cur_dir = dn(dn(abspath(__file__))) | 589 cur_dir = dn(dn(abspath(__file__))) |
597 tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test_hg.tar.gz")) | 590 tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test_hg.tar.gz")) |
598 tar.extractall(jn(TESTS_TMP_PATH, HG_REPO)) | 591 tar.extractall(jn(TESTS_TMP_PATH, HG_REPO)) |
599 tar.close() | 592 tar.close() |
593 | |
594 cur_dir = dn(dn(abspath(__file__))) | |
595 tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test_git.tar.gz")) | |
596 tar.extractall(jn(TESTS_TMP_PATH, GIT_REPO)) | |
597 tar.close() | |
598 | |
599 #LOAD VCS test stuff | |
600 from rhodecode.tests.vcs import setup_package | |
601 setup_package() | |
600 | 602 |
601 | 603 |
602 #============================================================================== | 604 #============================================================================== |
603 # PASTER COMMANDS | 605 # PASTER COMMANDS |
604 #============================================================================== | 606 #============================================================================== |