##// END OF EJS Templates
dohh !! fixed EmptyCHangeset for new vcs
marcink -
r520:eda96fb8 default
parent child Browse files
Show More
@@ -1,438 +1,440
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # Utilities for hg app
3 # Utilities for hg app
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 # This program is free software; you can redistribute it and/or
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; version 2
7 # as published by the Free Software Foundation; version 2
8 # of the License or (at your opinion) any later version of the license.
8 # of the License or (at your opinion) any later version of the license.
9 #
9 #
10 # This program is distributed in the hope that it will be useful,
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
13 # GNU General Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # MA 02110-1301, USA.
18 # MA 02110-1301, USA.
19
19
20 """
20 """
21 Created on April 18, 2010
21 Created on April 18, 2010
22 Utilities for hg app
22 Utilities for hg app
23 @author: marcink
23 @author: marcink
24 """
24 """
25 from beaker.cache import cache_region
25 from beaker.cache import cache_region
26 from mercurial import ui, config, hg
26 from mercurial import ui, config, hg
27 from mercurial.error import RepoError
27 from mercurial.error import RepoError
28 from pylons_app.model import meta
28 from pylons_app.model import meta
29 from pylons_app.model.db import Repository, User, HgAppUi, HgAppSettings
29 from pylons_app.model.db import Repository, User, HgAppUi, HgAppSettings
30 from vcs.backends.base import BaseChangeset
30 from vcs.backends.base import BaseChangeset
31 from vcs.utils.lazy import LazyProperty
31 from vcs.utils.lazy import LazyProperty
32 import logging
32 import logging
33 import os
33 import os
34
34
35 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
36
36
37
37
38 def get_repo_slug(request):
38 def get_repo_slug(request):
39 return request.environ['pylons.routes_dict'].get('repo_name')
39 return request.environ['pylons.routes_dict'].get('repo_name')
40
40
41 def is_mercurial(environ):
41 def is_mercurial(environ):
42 """
42 """
43 Returns True if request's target is mercurial server - header
43 Returns True if request's target is mercurial server - header
44 ``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
44 ``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
45 """
45 """
46 http_accept = environ.get('HTTP_ACCEPT')
46 http_accept = environ.get('HTTP_ACCEPT')
47 if http_accept and http_accept.startswith('application/mercurial'):
47 if http_accept and http_accept.startswith('application/mercurial'):
48 return True
48 return True
49 return False
49 return False
50
50
51 def check_repo_dir(paths):
51 def check_repo_dir(paths):
52 repos_path = paths[0][1].split('/')
52 repos_path = paths[0][1].split('/')
53 if repos_path[-1] in ['*', '**']:
53 if repos_path[-1] in ['*', '**']:
54 repos_path = repos_path[:-1]
54 repos_path = repos_path[:-1]
55 if repos_path[0] != '/':
55 if repos_path[0] != '/':
56 repos_path[0] = '/'
56 repos_path[0] = '/'
57 if not os.path.isdir(os.path.join(*repos_path)):
57 if not os.path.isdir(os.path.join(*repos_path)):
58 raise Exception('Not a valid repository in %s' % paths[0][1])
58 raise Exception('Not a valid repository in %s' % paths[0][1])
59
59
60 def check_repo_fast(repo_name, base_path):
60 def check_repo_fast(repo_name, base_path):
61 if os.path.isdir(os.path.join(base_path, repo_name)):return False
61 if os.path.isdir(os.path.join(base_path, repo_name)):return False
62 return True
62 return True
63
63
64 def check_repo(repo_name, base_path, verify=True):
64 def check_repo(repo_name, base_path, verify=True):
65
65
66 repo_path = os.path.join(base_path, repo_name)
66 repo_path = os.path.join(base_path, repo_name)
67
67
68 try:
68 try:
69 if not check_repo_fast(repo_name, base_path):
69 if not check_repo_fast(repo_name, base_path):
70 return False
70 return False
71 r = hg.repository(ui.ui(), repo_path)
71 r = hg.repository(ui.ui(), repo_path)
72 if verify:
72 if verify:
73 hg.verify(r)
73 hg.verify(r)
74 #here we hnow that repo exists it was verified
74 #here we hnow that repo exists it was verified
75 log.info('%s repo is already created', repo_name)
75 log.info('%s repo is already created', repo_name)
76 return False
76 return False
77 except RepoError:
77 except RepoError:
78 #it means that there is no valid repo there...
78 #it means that there is no valid repo there...
79 log.info('%s repo is free for creation', repo_name)
79 log.info('%s repo is free for creation', repo_name)
80 return True
80 return True
81
81
82 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
82 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
83 while True:
83 while True:
84 ok = raw_input(prompt)
84 ok = raw_input(prompt)
85 if ok in ('y', 'ye', 'yes'): return True
85 if ok in ('y', 'ye', 'yes'): return True
86 if ok in ('n', 'no', 'nop', 'nope'): return False
86 if ok in ('n', 'no', 'nop', 'nope'): return False
87 retries = retries - 1
87 retries = retries - 1
88 if retries < 0: raise IOError
88 if retries < 0: raise IOError
89 print complaint
89 print complaint
90
90
91 @cache_region('super_short_term', 'cached_hg_ui')
91 @cache_region('super_short_term', 'cached_hg_ui')
92 def get_hg_ui_cached():
92 def get_hg_ui_cached():
93 try:
93 try:
94 sa = meta.Session
94 sa = meta.Session
95 ret = sa.query(HgAppUi).all()
95 ret = sa.query(HgAppUi).all()
96 finally:
96 finally:
97 meta.Session.remove()
97 meta.Session.remove()
98 return ret
98 return ret
99
99
100
100
101 def get_hg_settings():
101 def get_hg_settings():
102 try:
102 try:
103 sa = meta.Session
103 sa = meta.Session
104 ret = sa.query(HgAppSettings).all()
104 ret = sa.query(HgAppSettings).all()
105 finally:
105 finally:
106 meta.Session.remove()
106 meta.Session.remove()
107
107
108 if not ret:
108 if not ret:
109 raise Exception('Could not get application settings !')
109 raise Exception('Could not get application settings !')
110 settings = {}
110 settings = {}
111 for each in ret:
111 for each in ret:
112 settings['hg_app_' + each.app_settings_name] = each.app_settings_value
112 settings['hg_app_' + each.app_settings_name] = each.app_settings_value
113
113
114 return settings
114 return settings
115
115
116 def get_hg_ui_settings():
116 def get_hg_ui_settings():
117 try:
117 try:
118 sa = meta.Session
118 sa = meta.Session
119 ret = sa.query(HgAppUi).all()
119 ret = sa.query(HgAppUi).all()
120 finally:
120 finally:
121 meta.Session.remove()
121 meta.Session.remove()
122
122
123 if not ret:
123 if not ret:
124 raise Exception('Could not get application ui settings !')
124 raise Exception('Could not get application ui settings !')
125 settings = {}
125 settings = {}
126 for each in ret:
126 for each in ret:
127 k = each.ui_key
127 k = each.ui_key
128 v = each.ui_value
128 v = each.ui_value
129 if k == '/':
129 if k == '/':
130 k = 'root_path'
130 k = 'root_path'
131
131
132 if k.find('.') != -1:
132 if k.find('.') != -1:
133 k = k.replace('.', '_')
133 k = k.replace('.', '_')
134
134
135 if each.ui_section == 'hooks':
135 if each.ui_section == 'hooks':
136 v = each.ui_active
136 v = each.ui_active
137
137
138 settings[each.ui_section + '_' + k] = v
138 settings[each.ui_section + '_' + k] = v
139
139
140 return settings
140 return settings
141
141
142 #propagated from mercurial documentation
142 #propagated from mercurial documentation
143 ui_sections = ['alias', 'auth',
143 ui_sections = ['alias', 'auth',
144 'decode/encode', 'defaults',
144 'decode/encode', 'defaults',
145 'diff', 'email',
145 'diff', 'email',
146 'extensions', 'format',
146 'extensions', 'format',
147 'merge-patterns', 'merge-tools',
147 'merge-patterns', 'merge-tools',
148 'hooks', 'http_proxy',
148 'hooks', 'http_proxy',
149 'smtp', 'patch',
149 'smtp', 'patch',
150 'paths', 'profiling',
150 'paths', 'profiling',
151 'server', 'trusted',
151 'server', 'trusted',
152 'ui', 'web', ]
152 'ui', 'web', ]
153
153
154 def make_ui(read_from='file', path=None, checkpaths=True):
154 def make_ui(read_from='file', path=None, checkpaths=True):
155 """
155 """
156 A function that will read python rc files or database
156 A function that will read python rc files or database
157 and make an mercurial ui object from read options
157 and make an mercurial ui object from read options
158
158
159 @param path: path to mercurial config file
159 @param path: path to mercurial config file
160 @param checkpaths: check the path
160 @param checkpaths: check the path
161 @param read_from: read from 'file' or 'db'
161 @param read_from: read from 'file' or 'db'
162 """
162 """
163
163
164 baseui = ui.ui()
164 baseui = ui.ui()
165
165
166 if read_from == 'file':
166 if read_from == 'file':
167 if not os.path.isfile(path):
167 if not os.path.isfile(path):
168 log.warning('Unable to read config file %s' % path)
168 log.warning('Unable to read config file %s' % path)
169 return False
169 return False
170 log.debug('reading hgrc from %s', path)
170 log.debug('reading hgrc from %s', path)
171 cfg = config.config()
171 cfg = config.config()
172 cfg.read(path)
172 cfg.read(path)
173 for section in ui_sections:
173 for section in ui_sections:
174 for k, v in cfg.items(section):
174 for k, v in cfg.items(section):
175 baseui.setconfig(section, k, v)
175 baseui.setconfig(section, k, v)
176 log.debug('settings ui from file[%s]%s:%s', section, k, v)
176 log.debug('settings ui from file[%s]%s:%s', section, k, v)
177 if checkpaths:check_repo_dir(cfg.items('paths'))
177 if checkpaths:check_repo_dir(cfg.items('paths'))
178
178
179
179
180 elif read_from == 'db':
180 elif read_from == 'db':
181 hg_ui = get_hg_ui_cached()
181 hg_ui = get_hg_ui_cached()
182 for ui_ in hg_ui:
182 for ui_ in hg_ui:
183 if ui_.ui_active:
183 if ui_.ui_active:
184 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section, ui_.ui_key, ui_.ui_value)
184 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section, ui_.ui_key, ui_.ui_value)
185 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
185 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
186
186
187
187
188 return baseui
188 return baseui
189
189
190
190
191 def set_hg_app_config(config):
191 def set_hg_app_config(config):
192 hgsettings = get_hg_settings()
192 hgsettings = get_hg_settings()
193
193
194 for k, v in hgsettings.items():
194 for k, v in hgsettings.items():
195 config[k] = v
195 config[k] = v
196
196
197 def invalidate_cache(name, *args):
197 def invalidate_cache(name, *args):
198 """Invalidates given name cache"""
198 """Invalidates given name cache"""
199
199
200 from beaker.cache import region_invalidate
200 from beaker.cache import region_invalidate
201 log.info('INVALIDATING CACHE FOR %s', name)
201 log.info('INVALIDATING CACHE FOR %s', name)
202
202
203 """propagate our arguments to make sure invalidation works. First
203 """propagate our arguments to make sure invalidation works. First
204 argument has to be the name of cached func name give to cache decorator
204 argument has to be the name of cached func name give to cache decorator
205 without that the invalidation would not work"""
205 without that the invalidation would not work"""
206 tmp = [name]
206 tmp = [name]
207 tmp.extend(args)
207 tmp.extend(args)
208 args = tuple(tmp)
208 args = tuple(tmp)
209
209
210 if name == 'cached_repo_list':
210 if name == 'cached_repo_list':
211 from pylons_app.model.hg_model import _get_repos_cached
211 from pylons_app.model.hg_model import _get_repos_cached
212 region_invalidate(_get_repos_cached, None, *args)
212 region_invalidate(_get_repos_cached, None, *args)
213
213
214 if name == 'full_changelog':
214 if name == 'full_changelog':
215 from pylons_app.model.hg_model import _full_changelog_cached
215 from pylons_app.model.hg_model import _full_changelog_cached
216 region_invalidate(_full_changelog_cached, None, *args)
216 region_invalidate(_full_changelog_cached, None, *args)
217
217
218 class EmptyChangeset(BaseChangeset):
218 class EmptyChangeset(BaseChangeset):
219
219
220 revision = -1
220 revision = -1
221 message = ''
221 message = ''
222 author = ''
222 author = ''
223
223
224 @LazyProperty
224 @LazyProperty
225 def raw_id(self):
225 def raw_id(self):
226 """
226 """
227 Returns raw string identifing this changeset, useful for web
227 Returns raw string identifing this changeset, useful for web
228 representation.
228 representation.
229 """
229 """
230 return '0' * 12
230 return '0' * 40
231
231
232 def short_id(self):
233 self.raw_id[:12]
232
234
233 def repo2db_mapper(initial_repo_list, remove_obsolete=False):
235 def repo2db_mapper(initial_repo_list, remove_obsolete=False):
234 """
236 """
235 maps all found repositories into db
237 maps all found repositories into db
236 """
238 """
237 from pylons_app.model.repo_model import RepoModel
239 from pylons_app.model.repo_model import RepoModel
238
240
239 sa = meta.Session
241 sa = meta.Session
240 user = sa.query(User).filter(User.admin == True).first()
242 user = sa.query(User).filter(User.admin == True).first()
241
243
242 rm = RepoModel()
244 rm = RepoModel()
243
245
244 for name, repo in initial_repo_list.items():
246 for name, repo in initial_repo_list.items():
245 if not sa.query(Repository).filter(Repository.repo_name == name).scalar():
247 if not sa.query(Repository).filter(Repository.repo_name == name).scalar():
246 log.info('repository %s not found creating default', name)
248 log.info('repository %s not found creating default', name)
247
249
248 form_data = {
250 form_data = {
249 'repo_name':name,
251 'repo_name':name,
250 'description':repo.description if repo.description != 'unknown' else \
252 'description':repo.description if repo.description != 'unknown' else \
251 'auto description for %s' % name,
253 'auto description for %s' % name,
252 'private':False
254 'private':False
253 }
255 }
254 rm.create(form_data, user, just_db=True)
256 rm.create(form_data, user, just_db=True)
255
257
256
258
257 if remove_obsolete:
259 if remove_obsolete:
258 #remove from database those repositories that are not in the filesystem
260 #remove from database those repositories that are not in the filesystem
259 for repo in sa.query(Repository).all():
261 for repo in sa.query(Repository).all():
260 if repo.repo_name not in initial_repo_list.keys():
262 if repo.repo_name not in initial_repo_list.keys():
261 sa.delete(repo)
263 sa.delete(repo)
262 sa.commit()
264 sa.commit()
263
265
264
266
265 meta.Session.remove()
267 meta.Session.remove()
266
268
267 from UserDict import DictMixin
269 from UserDict import DictMixin
268
270
269 class OrderedDict(dict, DictMixin):
271 class OrderedDict(dict, DictMixin):
270
272
271 def __init__(self, *args, **kwds):
273 def __init__(self, *args, **kwds):
272 if len(args) > 1:
274 if len(args) > 1:
273 raise TypeError('expected at most 1 arguments, got %d' % len(args))
275 raise TypeError('expected at most 1 arguments, got %d' % len(args))
274 try:
276 try:
275 self.__end
277 self.__end
276 except AttributeError:
278 except AttributeError:
277 self.clear()
279 self.clear()
278 self.update(*args, **kwds)
280 self.update(*args, **kwds)
279
281
280 def clear(self):
282 def clear(self):
281 self.__end = end = []
283 self.__end = end = []
282 end += [None, end, end] # sentinel node for doubly linked list
284 end += [None, end, end] # sentinel node for doubly linked list
283 self.__map = {} # key --> [key, prev, next]
285 self.__map = {} # key --> [key, prev, next]
284 dict.clear(self)
286 dict.clear(self)
285
287
286 def __setitem__(self, key, value):
288 def __setitem__(self, key, value):
287 if key not in self:
289 if key not in self:
288 end = self.__end
290 end = self.__end
289 curr = end[1]
291 curr = end[1]
290 curr[2] = end[1] = self.__map[key] = [key, curr, end]
292 curr[2] = end[1] = self.__map[key] = [key, curr, end]
291 dict.__setitem__(self, key, value)
293 dict.__setitem__(self, key, value)
292
294
293 def __delitem__(self, key):
295 def __delitem__(self, key):
294 dict.__delitem__(self, key)
296 dict.__delitem__(self, key)
295 key, prev, next = self.__map.pop(key)
297 key, prev, next = self.__map.pop(key)
296 prev[2] = next
298 prev[2] = next
297 next[1] = prev
299 next[1] = prev
298
300
299 def __iter__(self):
301 def __iter__(self):
300 end = self.__end
302 end = self.__end
301 curr = end[2]
303 curr = end[2]
302 while curr is not end:
304 while curr is not end:
303 yield curr[0]
305 yield curr[0]
304 curr = curr[2]
306 curr = curr[2]
305
307
306 def __reversed__(self):
308 def __reversed__(self):
307 end = self.__end
309 end = self.__end
308 curr = end[1]
310 curr = end[1]
309 while curr is not end:
311 while curr is not end:
310 yield curr[0]
312 yield curr[0]
311 curr = curr[1]
313 curr = curr[1]
312
314
313 def popitem(self, last=True):
315 def popitem(self, last=True):
314 if not self:
316 if not self:
315 raise KeyError('dictionary is empty')
317 raise KeyError('dictionary is empty')
316 if last:
318 if last:
317 key = reversed(self).next()
319 key = reversed(self).next()
318 else:
320 else:
319 key = iter(self).next()
321 key = iter(self).next()
320 value = self.pop(key)
322 value = self.pop(key)
321 return key, value
323 return key, value
322
324
323 def __reduce__(self):
325 def __reduce__(self):
324 items = [[k, self[k]] for k in self]
326 items = [[k, self[k]] for k in self]
325 tmp = self.__map, self.__end
327 tmp = self.__map, self.__end
326 del self.__map, self.__end
328 del self.__map, self.__end
327 inst_dict = vars(self).copy()
329 inst_dict = vars(self).copy()
328 self.__map, self.__end = tmp
330 self.__map, self.__end = tmp
329 if inst_dict:
331 if inst_dict:
330 return (self.__class__, (items,), inst_dict)
332 return (self.__class__, (items,), inst_dict)
331 return self.__class__, (items,)
333 return self.__class__, (items,)
332
334
333 def keys(self):
335 def keys(self):
334 return list(self)
336 return list(self)
335
337
336 setdefault = DictMixin.setdefault
338 setdefault = DictMixin.setdefault
337 update = DictMixin.update
339 update = DictMixin.update
338 pop = DictMixin.pop
340 pop = DictMixin.pop
339 values = DictMixin.values
341 values = DictMixin.values
340 items = DictMixin.items
342 items = DictMixin.items
341 iterkeys = DictMixin.iterkeys
343 iterkeys = DictMixin.iterkeys
342 itervalues = DictMixin.itervalues
344 itervalues = DictMixin.itervalues
343 iteritems = DictMixin.iteritems
345 iteritems = DictMixin.iteritems
344
346
345 def __repr__(self):
347 def __repr__(self):
346 if not self:
348 if not self:
347 return '%s()' % (self.__class__.__name__,)
349 return '%s()' % (self.__class__.__name__,)
348 return '%s(%r)' % (self.__class__.__name__, self.items())
350 return '%s(%r)' % (self.__class__.__name__, self.items())
349
351
350 def copy(self):
352 def copy(self):
351 return self.__class__(self)
353 return self.__class__(self)
352
354
353 @classmethod
355 @classmethod
354 def fromkeys(cls, iterable, value=None):
356 def fromkeys(cls, iterable, value=None):
355 d = cls()
357 d = cls()
356 for key in iterable:
358 for key in iterable:
357 d[key] = value
359 d[key] = value
358 return d
360 return d
359
361
360 def __eq__(self, other):
362 def __eq__(self, other):
361 if isinstance(other, OrderedDict):
363 if isinstance(other, OrderedDict):
362 return len(self) == len(other) and self.items() == other.items()
364 return len(self) == len(other) and self.items() == other.items()
363 return dict.__eq__(self, other)
365 return dict.__eq__(self, other)
364
366
365 def __ne__(self, other):
367 def __ne__(self, other):
366 return not self == other
368 return not self == other
367
369
368
370
369 #===============================================================================
371 #===============================================================================
370 # TEST FUNCTIONS
372 # TEST FUNCTIONS
371 #===============================================================================
373 #===============================================================================
372 def create_test_index(repo_location, full_index):
374 def create_test_index(repo_location, full_index):
373 """Makes default test index
375 """Makes default test index
374 @param repo_location:
376 @param repo_location:
375 @param full_index:
377 @param full_index:
376 """
378 """
377 from pylons_app.lib.indexers.daemon import WhooshIndexingDaemon
379 from pylons_app.lib.indexers.daemon import WhooshIndexingDaemon
378 from pylons_app.lib.pidlock import DaemonLock, LockHeld
380 from pylons_app.lib.pidlock import DaemonLock, LockHeld
379 from pylons_app.lib.indexers import IDX_LOCATION
381 from pylons_app.lib.indexers import IDX_LOCATION
380 import shutil
382 import shutil
381
383
382 if os.path.exists(IDX_LOCATION):
384 if os.path.exists(IDX_LOCATION):
383 shutil.rmtree(IDX_LOCATION)
385 shutil.rmtree(IDX_LOCATION)
384
386
385 try:
387 try:
386 l = DaemonLock()
388 l = DaemonLock()
387 WhooshIndexingDaemon(repo_location=repo_location)\
389 WhooshIndexingDaemon(repo_location=repo_location)\
388 .run(full_index=full_index)
390 .run(full_index=full_index)
389 l.release()
391 l.release()
390 except LockHeld:
392 except LockHeld:
391 pass
393 pass
392
394
393 def create_test_env(repos_test_path, config):
395 def create_test_env(repos_test_path, config):
394 """Makes a fresh database and
396 """Makes a fresh database and
395 install test repository into tmp dir
397 install test repository into tmp dir
396 """
398 """
397 from pylons_app.lib.db_manage import DbManage
399 from pylons_app.lib.db_manage import DbManage
398 import tarfile
400 import tarfile
399 import shutil
401 import shutil
400 from os.path import dirname as dn, join as jn, abspath
402 from os.path import dirname as dn, join as jn, abspath
401
403
402 log = logging.getLogger('TestEnvCreator')
404 log = logging.getLogger('TestEnvCreator')
403 # create logger
405 # create logger
404 log.setLevel(logging.DEBUG)
406 log.setLevel(logging.DEBUG)
405 log.propagate = True
407 log.propagate = True
406 # create console handler and set level to debug
408 # create console handler and set level to debug
407 ch = logging.StreamHandler()
409 ch = logging.StreamHandler()
408 ch.setLevel(logging.DEBUG)
410 ch.setLevel(logging.DEBUG)
409
411
410 # create formatter
412 # create formatter
411 formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
413 formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
412
414
413 # add formatter to ch
415 # add formatter to ch
414 ch.setFormatter(formatter)
416 ch.setFormatter(formatter)
415
417
416 # add ch to logger
418 # add ch to logger
417 log.addHandler(ch)
419 log.addHandler(ch)
418
420
419 #PART ONE create db
421 #PART ONE create db
420 log.debug('making test db')
422 log.debug('making test db')
421 dbname = config['sqlalchemy.db1.url'].split('/')[-1]
423 dbname = config['sqlalchemy.db1.url'].split('/')[-1]
422 dbmanage = DbManage(log_sql=True, dbname=dbname, tests=True)
424 dbmanage = DbManage(log_sql=True, dbname=dbname, tests=True)
423 dbmanage.create_tables(override=True)
425 dbmanage.create_tables(override=True)
424 dbmanage.config_prompt(repos_test_path)
426 dbmanage.config_prompt(repos_test_path)
425 dbmanage.create_default_user()
427 dbmanage.create_default_user()
426 dbmanage.admin_prompt()
428 dbmanage.admin_prompt()
427 dbmanage.create_permissions()
429 dbmanage.create_permissions()
428 dbmanage.populate_default_permissions()
430 dbmanage.populate_default_permissions()
429
431
430 #PART TWO make test repo
432 #PART TWO make test repo
431 log.debug('making test vcs repo')
433 log.debug('making test vcs repo')
432 if os.path.isdir('/tmp/vcs_test'):
434 if os.path.isdir('/tmp/vcs_test'):
433 shutil.rmtree('/tmp/vcs_test')
435 shutil.rmtree('/tmp/vcs_test')
434
436
435 cur_dir = dn(dn(abspath(__file__)))
437 cur_dir = dn(dn(abspath(__file__)))
436 tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test.tar.gz"))
438 tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test.tar.gz"))
437 tar.extractall('/tmp')
439 tar.extractall('/tmp')
438 tar.close()
440 tar.close()
General Comments 0
You need to be logged in to leave comments. Login now