PylonsがベースとしているPasteは、サブモジュールにPasteScriptってのがあって、PylonsのrestcontrollerとかcontrollerなどもPasteScriptコマンドなのだね。
で、Pylons自体には、いまのところコントローラー生成のコマンドはあるのだけど、モデル生成のコマンドがない。
勉強がてら、モデル生成のコマンドを作ってみる。
model.py_tmpl
from elixir import *
class ${classname}(Entity):
""" ${classname}
"""
非常にいい加減なテンプレート。
クラス定義だが、中身を決められないので、Entityを継承したクラスってことくらいしか書けない。
まあ、いいか。
PasteScriptには、filemakerというモジュールがあって、ファイル生成処理に必要なことを色々やってくれるFileOpというクラスがある。
FileOpは生成するときに、テンプレートのありかを指定しておく。
今回は、commands.py内にModelCommandクラスもって、相対パスtemplates内に、上記のmodel.py_tmplを配置した。
このときFileOpの生成はこんな感じ
file_op = FileOp(source_dir=os.path.join(os.path.dirname(__file__), 'templates')
んで、テンプレート内で展開される変数もfile_opに持たせてあげる。
file_op.template_vars.update({'classname':'Spam'})
テンプレートから実際のファイルを生成するには、copy_fileメソッドを使う。
file_op.copy_file(template='model.py_tmpl',
dest='model',
filename='spam')
.pyの拡張子は自動で付けてくれるっぽい。
destは、ファイル生成先のディレクトリだけど、プロジェクトパッケージからの相対パスになるみたいだ。
(hogeプロジェクトなら、hoge/model 以下に生成される)
結局は、このあたりのFileOpオブジェクトに対する操作を、コマンドの中でやればいい。
PasteScriptコマンドは、paste.script.command.Commandクラスを継承をする。
また、クラス属性で、引数の数や、オプション、コマンドの説明など、メタ属性を設定する。
from paste.script import command
class ModelCommand(command.Command):
max_args = 1
min_args = 1
usage = "paster model model_name"
summary = "Create a set of REST Controller, Model and Templates."
group_name = "roadcones"
parser = command.Command.standard_parser(verbose=True)
コマンドが実行されたときは、commandメソッドが呼ばれる。
commandメソッドをオーバーライドして、先ほどのFileOpを操れば、とりあえずコード生成ができる。
def command(self):
file_op = FileOp(source_dir=os.path.join(
os.path.dirname(__file__), 'templates'))
member_name = self.args[0]
model_name = util.class_name_from_module_name(member_name)
file_op.template_vars.update(
{'classname':model_name
}
)
file_op.copy_file(template='model.py_tmpl',
dest='model',
filename=member_name)
args属性に、コマンドライン引数が入ってるので、1つの引数を受け取っておく。
この引数はモデルのファイル名とクラス名に用いる。
FileOpオブジェクトの使い方は上述の通り。
また、util.class_name_form_module_nameは、ファイル名からクラス名に変換するもの。
pylons.utilを使っている。
さてこのクラスをPasteScriptコマンドに登録しないと使えない。
setup.pyのentry_pointsに以下のように追加しておく。
(以下のソース例では、このコマンドをroadconesプロジェクトで作ってるものとしています。)
[paste.paster_command]
resource = roadcones.commands:ModelCommand
setup.pyを変更したら、egg_infoを更新しときましょう。
$ python setup.py egg_info
ちなみに、setup.py develop でegg_infoを登録しておくと、編集中のソースツリーがPYTHON_PATHに追加されるので、便利です。
あとは、このコマンドを使いたいプロジェクトで、egg_info/paster_plugins.txt内に、コマンドを定義しているegg名を記述しておくとコマンドを使えるようになります。
paster_plugins.txtの例
Pylons
WebHelpers
roadcones
PasteScript
実際には、paster_pluginsに追加する処理は、PasteScriptのプロジェクトテンプレートでやることになるでしょう。
|