Mercurialのhookをplugpyで書く
まだbranchなんだけど思いついたので書いておく。
次で入れるかも。
Mercurialのhook
Mercurialのhookはpythonで書くことができる。
設定するには.hgrcに
"python:"ではじめて、<モジュール名>.<メソッド名>と書いておくと呼ばれる。
まあ呼ばれるんだけどふつーのモジュール扱いなのでhook用のscriptは
PYTHONPATHを通すか、あるいはパッケージにしてinstallなどpythonから見える
ようにしなくてはならない。
まあそれがめんどいなあと思ったのでplugpyにhg用のextを追加してみた。
hook用のpluginを書く
plugpy.hg.HgPluginを継承したクラスを書くだけ。
show_branch.py
from plugpy.hg import HgPlugin class Test(HgPlugin): def on_update(self, branch_name, *args, **kwargs): self.show_branch(branch_name, *args, **kwargs) def on_commit(self, branch_name, *args, **kwargs): self.show_branch(branch_name, *args, **kwargs) def show_branch(self, branch_name, *args, **kwargs): print branch_name return False
branch_nameを出力するだけのもの。
branch_nameはホントはrepoから取り出さないといけないんだけど渡ってくるようにしてある。
hookで呼ばれるメソッドは'on_
updateならばon_update、commitならばon_commitのようになる。
(もちろん.hgrcでhookの設定は書かないといけない)
pluginを置く
全体に適用する
Mercurialのrepo全体に適用したい場合は$HOMEの.plugpy/pluginsというdirを作っておいておくと呼ばれます。
repo単位で適用する
repo単位で適用する場合にはrepoのrootのdirに'.hghooks'というdirを作ってそこに置くと呼ばれます。
これでsys.pathとか気にせずに簡単にhook scriptを書けますね。
repo単位のものはhook scriptもrepo管理しておいてもいいです。
仕掛け
まあ簡単
plugpy/hg.py
from plugpy import * import os.path class HgPlugin(object): def __init__(self, *args, **kwargs): pass def hook(hooktype, *args, **kwargs): config = dict() path = os.path.join(kwargs['repo'].root, './.hghooks') res = load_plugins(config, plugin_path=path, plugin_class=[HgPlugin], debug=False) name = kwargs['repo'].dirstate.branch() results = dispatch(hooktype, *args, target=HgPlugin, branch_name=name, **kwargs) for res in results: if res[0]: return True return False
すでに読み込まれてるモジュール内のHgPluginをひっかけてきて呼んでるだけ。
元々、Mercurialのhookには複数のhookを書けるようにprefixとか設定できるんですがPluginだと
それも1行の設定で書けます。