以前紹介したPython版Rakeもどきを改良してCodeReposに突っ込みました。まだ100行くらいです。自分では一番使っている自作モジュールなのでそろそろまとめようと思っていたのです。
http://coderepos.org/share/browser/lang/python/tasktools/trunk/tasktools.py
改良点
setuptoolsがあるときはそっちを使うようにした。use_without_standardメソッドによってdistutils標準タスクを消すことができる。これによって--help-commandsの画面がすっきりする。また、この場合名前空間のセパレータに:を用いるようになった。global_descriptionによってタスクファイル自体に説明がつけられるようになった。load_pathメソッドで指定したディレクトリ以下を再帰的に検索し「tasks.py」という名前のファイルを読み込むことができるようになった。--help-commandsで表示されるコマンドの並び順をソートするようにした。--help-commandsでサブコマンドを一覧表示するようにした。
使用方法
以前書いたのとほとんど同じなんですが、まとめなおしておきます。
tasktoolsとは?
distutilsおよびsetuptoolsを拡張してextra commandを簡単に作成するためのユーティリティです。RubyにおけるRakeのようなものです。ビルド機能がほしい場合はdistutils, setuptoolsの標準ビルド機能、もしくはSConsと組み合わせるとハッピーになれます。
ちなみに、tasktoolsというのは同じくdistutilsの拡張であるsetuptoolsの命名規則に習っています。task機能を強化するからtasktoolsです。
チュートリアル
典型的なtasktoolsの使い方です。
まずtasks.pyというファイルを作成します。典型的には以下の様になります。
- from __future__ import with_statement
- from tasktools import *
- global_description(u"""
- サンプルタスクファイルです。
- """)
- use_without_standard() # distutilsの標準コマンドを使用しないことを宣言します。
- load_path("./tasks") # "./tasks"以下のtasks.pyを再帰的に読み込みます
- with namespace("file") as ns:
- class mktmpfile(Task):
- u"""一時ファイルを作成します。
- """
- user_options = [("path=", "p", u"作成するパスです")]
- def run(self):
- print "create %s"%self.path
- def finalize_options(self):
- if not self.path: self.path = "/tmp/tmp.txt"
- class mklogfile(Task):
- u"""ログファイルを作成します。
- """
- def run(self):
- print "create log file"
- class init(Task):
- u"""ファイルを初期化します。
- """
- def run(self):
- pass
- sub_commands = [("file:mktmpfile", None),
- ("file:mklogfile", None)]
- if __name__ == "__main__":
- run()
ではpython tasks.py --help-commandsと実行してみましょう
############################################################
サンプルタスクファイルです。
############################################################
Commands:
file:init ファイルを初期化します。
sub commands:
file:mktmpfile
file:mklogfile
file:mklogfile ログファイルを作成します。
file:mktmpfile 一時ファイルを作成します。
usage: tasks.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
or: tasks.py --help [cmd1 cmd2 ...]
or: tasks.py --help-commands
or: tasks.py cmd --help
この様にglobal_descriptionで設定した説明と、定義したタスクの一覧が表示されます。
次に./tasks/tasks.pyを作成してみます。
- from __future__ import with_statement
- from tasktools import *
- use_without_standard()
- with namespace("subs") as ns:
- class test1(Task):
- u"""サブディレクトリで定義されたタスクです
- """
- def run(self):
- print "sub test"
- if __name__ == "__main__":
- run()
このファイルは./tasks.pyでload_path("./tasks")と宣言しているので./tasks.pyを実行すると自動的に読み込まれます。
もう一度python tasks.py --help-commandsと実行してみましょう
############################################################
サンプルタスクファイルです。
############################################################
Commands:
file:init ファイルを初期化します。
sub commands:
file:mktmpfile
file:mklogfile
file:mklogfile ログファイルを作成します。
file:mktmpfile 一時ファイルを作成します。
subs:test1 サブディレクトリで定義されたタスクです
usage: tasks.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
or: tasks.py --help [cmd1 cmd2 ...]
or: tasks.py --help-commands
or: tasks.py cmd --help
確かにsubs:test1コマンドが追加されています。
ではタスクを実行してみましょう。python tasks.py file:initを実行してみます。
running file:init
running file:mktmpfile
create /tmp/tmp.txt
running file:mklogfile
create log file
おお、実行されましたね。
user_optionsを定義しているタスクではオプションも渡せます。python tasks.py file:mktmpfile --path=/tmp/change.txtを実行してみましょう。
running file:mktmpfile
create /tmp/change.txt
ちゃんとオプションが渡されていますね。
こんな感じです。distutilsの独自コマンドに関する説明は46 新しいDistutilsコマンドの作成を参照してください。正直使えないページですが・・・。一応説明しておくとinitialize_optionsはuser_optionsの定義から自動生成するようになっています。また
distutils.core.Commandを継承しているのでこのクラスの機能も使えます。
せっかくCodereposに突っ込んだのでバグなんかが見つかったらガンガン直しちゃってください。




