使用预提交挂钩运行 Django 测试

发布于 2024-08-14 22:43:20 字数 9665 浏览 10 评论 0原文

我想使用 Mercurial 的预提交钩子运行所有 django 测试。每当测试失败时,提交就会中止。

目标是尽可能频繁地阻止破坏构建的提交。

编辑:最终使用外部脚本路由。这是我的 hgrc 的相关部分:

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

这是我在钩子函数上的进展:

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)

我在这里做错了什么?

PS - 它给出了一个巨大的错误回溯,它完整地包含在下面,

jim@ubuntu:~/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)

这是重要的部分:

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

其余的:

  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

I would like to run all my django tests using mercurial's precommit hook. Whenever a test fails the commit will be aborted.

The goal is to block build-breaking commits as often as possible.

edit: Ended up using the external script route. Here is the reletant portion of my hgrc:

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

Here is my progress on the hook function:

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)

What am I doing wrong here?

PS - It's giving a HUGE error traceback, which is included in it's entirety below

jim@ubuntu:~/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)

here is the important part:

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

and the rest:

  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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无风消散 2024-08-21 22:43:20

看起来 Mercurial 导入模块的方式与 Django 的方式有些冲突。

在尝试深入研究并解决这个问题之前,是否有任何理由不使用普通命令运行测试?

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

It looks like Mercurial's way of importing modules is clashing with Django's somehow.

Before trying to dive in and sort that out, is there any reason to not just run the tests with the normal command?

[hooks]
precommit.runtests = python manage.py test
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文