読者です 読者をやめる 読者になる 読者になる

コミット時にpdb消し忘れてないかチェックするhg hook

チェック用のスクリプト

こんな感じのスクリプト作成

#!/usr/bin/env python

import os
import sys


COMMAND = r"find . -name '*.py' | xargs grep -lr '{pattern}'"
INFO = '{filename}: pdb found.'


def check(pattern):
    return os.popen(COMMAND.format(pattern=pattern)).readlines()


def display_warning(lines):
    for line in lines:
        print >> sys.stderr, INFO.format(filename=line.strip('\n'))


def check_pdb(*args, **kwargs):
    lines = check('pdb.set_trace')
    if lines:
        display_warning(lines)
        sys.exit(1)

~/.hgext/hookpdb/check.py みたいな感じで配置。

.hgrcに追記

[hook]
pretxncommit.pdb = python:~/.hgext/hookpdb/check.py:check_pdb

試してみる

pdb仕込みっぱなしのファイルがある状態でコミットしようとすると…

$ hg ci
./hoge.py: pdb found.
transaction abort!
rollback completed
note: commit message saved in .hg/last-message.txt

うん、できてる。けど、ファイル多いともっさりがキニナルような…

追記

ありがとうございますありがとうございます!
描き直してみました。

#!/usr/bin/env python

import os
import sys
from fnmatch import fnmatch


COMMAND = r"grep -l {pattern} {file}"
INFO = '{filename}: debugger found.'
PATTERNS = ['pdb.set_trace', 'import debug']


def check(repo, file, patterns):
    patterns = ['-e "{ptn}"'.format(ptn=pattern) for pattern in patterns]
    pattern = ' '.join(patterns)
    file = os.path.join(repo.root, file)
    return os.popen(COMMAND.format(pattern=pattern, file=file)).read()


def display_warning(lines):
    for line in lines:
        print >> sys.stderr, INFO.format(filename=line.strip('\n'))


def get_pyfiles(repo, node):
    return [f for f in repo[node].files() if fnmatch(f, '*.py')]


def check_pdb(ui, repo, hooktype, node=None, source=None, **kwargs):
    lines = [f for f in get_pyfiles(repo, node) if check(repo, f, PATTERNS)]
    if lines:
        display_warning(lines)
        sys.exit(1)

さらに修正

リポジトリルートで実行しないとgrep時にnot foundになってしまっていたので絶対パスgrepするように修正しました。

さらにさらに修正

ゆとりな僕はpdbよりもdebugモジュールを使いがちなのでパターンを複数受け取れるように修正しました。もうGistでやれよと思います。