2009-12-14 13 views
4

Je souhaite exécuter tous mes tests django en utilisant le crochet précommit de mercurial. Chaque fois qu'un test échoue, le commit sera annulé.Exécution de tests Django avec un crochet de précommande

L'objectif est de bloquer les validations de rupture de build aussi souvent que possible.

éditer: Terminé en utilisant la route de script externe. Voici la partie reletant de mon hgrc:

[hooks] 
precommit = python ./pinax/projects/lgr/manage.py test lgr_photos --verbosity=0 --noinput 
commit = hg push 

Voici mes progrès sur la fonction crochet:

from os.path import join, dirname 
import sys 
from django.core.management import call_command 

def hook(ui, repo, **kwargs): 
    project_path = join(dirname(repo.path), 'pinax', 'projects') 
    sys.path.insert(0, project_path) 

    from lgr.manage import * 

    output = call_command('test', verbosity=0, interactive=False) 
    #ui.warn(output) 

ce que je fais mal ici?

PS - Il est de donner un retraçage d'erreur énorme, qui est inclus dans son intégralité ci-dessous

[email protected]:~/workspace/lgr$ hg ci -m 'testing hooks' 
No username found, using '[email protected]' instead 
error: precommit hook raised an exception: '_demandmod' object is not iterable 
** unknown exception encountered, details follow 
** report bug details to http://mercurial.selenic.com/bts/ 
** or [email protected] 
** Mercurial Distributed SCM (version 1.3.1) 
** Extensions loaded: 
Traceback (most recent call last): 
    File "/usr/bin/hg", line 27, in <module> 
    mercurial.dispatch.run() 
    File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 16, in run 
    sys.exit(dispatch(sys.argv[1:])) 
    File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 27, in dispatch 
    return _runcatch(u, args) 
    File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 43, in _runcatch 
    return _dispatch(ui, args) 
    File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 449, in _dispatch 
    return runcommand(lui, repo, cmd, fullargs, ui, options, d) 
    File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 317, in runcommand 
    ret = _runcommand(ui, options, cmd, d) 
    File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 501, in _runcommand 
    return checkargs() 
    File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 454, in checkargs 
    return cmdfunc() 
    File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 448, in <lambda> 
    d = lambda: util.checksignature(func)(ui, *args, **cmdoptions) 
    File "/usr/lib/pymodules/python2.6/mercurial/util.py", line 402, in check 
    return func(*args, **kwargs) 
    File "/usr/lib/pymodules/python2.6/mercurial/commands.py", line 667, in commit 
    node = cmdutil.commit(ui, repo, commitfunc, pats, opts) 
    File "/usr/lib/pymodules/python2.6/mercurial/cmdutil.py", line 1213, in commit 
    return commitfunc(ui, repo, message, match(repo, pats, opts), opts) 
    File "/usr/lib/pymodules/python2.6/mercurial/commands.py", line 665, in commitfunc 
    editor=e, extra=extra) 
    File "/usr/lib/pymodules/python2.6/mercurial/localrepo.py", line 886, in commit 
    ret = self.commitctx(cctx, True) 
    File "/usr/lib/pymodules/python2.6/mercurial/localrepo.py", line 915, in commitctx 
    self.hook("precommit", throw=True, parent1=xp1, parent2=xp2) 
    File "/usr/lib/pymodules/python2.6/mercurial/localrepo.py", line 139, in hook 
    return hook.hook(self.ui, self, name, throw, **args) 
    File "/usr/lib/pymodules/python2.6/mercurial/hook.py", line 119, in hook 
    r = _pythonhook(ui, repo, name, hname, hookfn, args, throw) or r 
    File "/usr/lib/pymodules/python2.6/mercurial/hook.py", line 52, in _pythonhook 
    r = obj(ui=ui, repo=repo, hooktype=name, **args) 

ici est la partie importante:

File "/home/jim/run_lgr_tests.py", line 11, in hook 
    output = call_command('test', verbosity=0, interactive=False) 

et le reste:

File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 166, in call_command 
    return klass.execute(*args, **defaults) 
    File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 213, in execute 
    translation.activate('en-us') 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/__init__.py", line 73, in activate 
    return real_activate(language) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/__init__.py", line 43, in delayed_loader 
    return g['real_%s' % caller](*args, **kwargs) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 205, in activate 
    _active[currentThread()] = translation(language) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 194, in translation 
    default_translation = _fetch(settings.LANGUAGE_CODE) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 180, in _fetch 
    app = import_module(appname) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/importlib.py", line 35, in import_module 
    __import__(name) 
    File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 84, in _demandimport 
    return _origimport(name, globals, locals, fromlist) 
    File "/home/jim/workspace/lgr/pinax/projects/lgr/apps/lgr_hacks.py", line 5, in <module> 
    User.email = models.EmailField(_('email address'), blank=True, max_length=200) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/__init__.py", line 62, in ugettext 
    return real_ugettext(message) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 286, in ugettext 
    return do_translate(message, 'ugettext') 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 276, in do_translate 
    _default = translation(settings.LANGUAGE_CODE) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 194, in translation 
    default_translation = _fetch(settings.LANGUAGE_CODE) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 180, in _fetch 
    app = import_module(appname) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/importlib.py", line 35, in import_module 
    __import__(name) 
    File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 84, in _demandimport 
    return _origimport(name, globals, locals, fromlist) 
    File "/home/jim/workspace/lgr/pinax/apps/external_apps/djangodblog/__init__.py", line 1, in <module> 
    import djangodblog.admin 
    File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 91, in _demandimport 
    return _origimport(name, globals, locals, fromlist) 
    File "/home/jim/workspace/lgr/pinax/apps/external_apps/djangodblog/admin.py", line 14, in <module> 
    admin.site.register(ErrorBatch, ErrorBatchAdmin) 
    File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/sites.py", line 90, in register 
    validate(admin_class, model) 
    File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/validation.py", line 22, in validate 
    models.get_apps() 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 100, in get_apps 
    self._populate() 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 58, in _populate 
    self.load_app(app_name, True) 
    File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 74, in load_app 
    models = import_module('.models', app_name) 
    File "/usr/local/lib/python2.6/dist-packages/django/utils/importlib.py", line 35, in import_module 
    __import__(name) 
    File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 84, in _demandimport 
    return _origimport(name, globals, locals, fromlist) 
    File "/home/jim/workspace/lgr/pinax/projects/lgr/apps/account/models.py", line 7, in <module> 
    from timezones.fields import TimeZoneField 
    File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 103, in _demandimport 
    mod = _origimport(name, globals, locals) 
    File "/home/jim/workspace/lgr/pinax/apps/external_apps/timezones/fields.py", line 12, in <module> 
    default_tz = pytz.timezone(getattr(settings, "TIME_ZONE", "UTC")) 
    File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 75, in __getattribute__ 
    self._load() 
    File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 47, in _load 
    mod = _origimport(head, globals, locals) 
    File "/home/jim/workspace/lgr/pinax/libs/external_libs/pytz-2008b/pytz/__init__.py", line 29, in <module> 
    from pkg_resources import resource_stream 
    File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 103, in _demandimport 
    mod = _origimport(name, globals, locals) 
    File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 2562, in <module> 
    working_set.require(__requires__) 
    File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 626, in require 
    needed = self.resolve(parse_requirements(requirements)) 
    File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 505, in resolve 
    requirements = list(requirements)[::-1] # set up the stack 
    File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 2380, in parse_requirements 
    for line in lines: 
    File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 1814, in yield_lines 
    for s in yield_lines(ss): 
    File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 1813, in yield_lines 
    for ss in strs: 
TypeError: '_demandmod' object is not iterable 

Répondre

6

Il semble que la manière d'importer des modules de Mercurial soit en conflit avec celle de Django.

Avant d'essayer de faire un plongeon, y a-t-il une raison de ne pas simplement lancer les tests avec la commande normale?

[hooks] 
precommit.runtests = python manage.py test 
+0

retournera-t-il l'état 1 lorsque les tests échoueront? – Jiaaro

+0

réponse: oui c'est le cas! :) merci – Jiaaro

+0

En fait, il va retourner le nombre de tests qui ont échoué comme le code de retour - ex: 3 tests ont échoué -> code de retour == 3, tous les tests réussis -> code de retour 0. Donc oui, cela fonctionnera comme crochet. –