ScrumもどきPlugin開発記
を書くことにした。せっかくなので。
pythonもTrac plugin開発も未熟なので、もし識者が読んでツッコミ入れてくれたら・・・という淡い期待も。
参考にしたのは以下のチュートリアル。Trac0.11用なので注意。
EggCookingTutorialTrac0.11 – Trac Hacks - Plugins Macros etc.
構成
- Red Hat Enterprise Linux ES release 4
- python2.5.2
- Trac 0.11b
いっちょやってみっか!
とりあえずTracに必要なcustom ticketを挿入する機能を作ってみよう。
そしたらこのplugin開発自体をTracで管理して、かつテストまで出来るしね。
追加するticketは
estimate | 見積もり |
remain | 残作業量 |
の二つ。
trac.iniに直接記述するとしたら、以下になるイメージ。
[ticket-custom] estimate = text estimate.label = Estimated hours estimate.order = 10 estimate.value = 0 remain = text remain.label = Remain remain.order = 11 remain.value = 0
参考にしたのはTiming And Estimating pluginのソース。
ディレクトリ構成
src │ setup.py │ └─scrumhalf initenv.py __init__.py
実装
initenv.py
import re import time from trac.core import * from trac.env import IEnvironmentSetupParticipant from trac.perm import IPermissionRequestor, PermissionSystem class SetupEnv(Component): implements(IEnvironmentSetupParticipant) def __init__(self): pass def environment_created(self): if self.environment_needs_upgrade(None): self.upgrade_environment(None) def ticket_fields_need_upgrade(self): ticket_custom = "ticket-custom" return not ( self.config.get( ticket_custom, "estimate" ) and \ self.config.get( ticket_custom, "remain" ) and \ self.config.get( ticket_custom, "estimate.order") and \ self.config.get( ticket_custom, "remain.order")) def do_ticket_field_upgrade(self): ticket_custom = "ticket-custom" self.config.set(ticket_custom,"estimate", "text") if not self.config.get( ticket_custom, "estimate.order") : self.config.set(ticket_custom,"estimate.order", "10") self.config.set(ticket_custom,"estimate.value", "0") self.config.set(ticket_custom,"estimate.label", "Estimated hours") self.config.set(ticket_custom,"remain", "text") if not self.config.get( ticket_custom, "remain.order") : self.config.set(ticket_custom,"remain.order", "11") self.config.set(ticket_custom,"remain.value", "0") self.config.set(ticket_custom,"remain.label", "Remain") self.config.save(); def environment_needs_upgrade(self, db): return self.ticket_fields_need_upgrade() def upgrade_environment(self, db): if self.ticket_fields_need_upgrade(): self.do_ticket_field_upgrade() print "Done Upgrading"
自分もまだ理解していないが、いちお解説^^;
まずTrac pluginはtrac.core.Componentを継承するもの・・・らしい。
class SetupEnv(Component):
この辺のアーキテクチャについてはComponentArchitecture参照。
次に以下の文、
implements(IEnvironmentSetupParticipant)
implementsメソッドで、インターフェース(拡張ポイント)を実装する。javaのイベントアーキテクチャ(なんたらListenerやらHandler)と似てる。
必要な拡張ポイントは複数implements出来る。その他標準拡張ポイントはTracDev/PluginDevelopment – The Trac Project参照。
IEnvironmentSetupParticipantインターフェースは、「Trac環境の初期化及びアップグレードを行う為の拡張ポイント」(IEnvironmentSetupParticipantコメントより意訳)だそうだ。Timing and Estimating pluginではDBテーブル作成などもしていたが、ここではとりあえずcustom ticketのみ追加しておく。
IEnvironmentSetupParticipantに定義されているメソッド(イベントハンドラ)は以下の3つ。
environment_created | 新しいTrac環境が作成された時に呼び出される |
environment_needs_upgrade | Trac環境の更新が必要かどうかを返す |
upgrade_environment | 環境の更新を行う |
Trac環境(原文:Trac environment)ってのはtrac-admin initenvで作成したプロジェクトのことかな。
うーん・・・。イマイチまだ把握出来ていないが・・・ここはとりあえずTiming And Estimating Pluginを参考に、各メソッドを実装する。
__init__.py
# TracScrumHalf module from initenv import *
このファイルは、パッケージの初期化コードを記述する特殊ファイル。python仕様なので割愛。ここでComponentを定義してあるモジュールをimportする。importするだけで何故かTracから認識される。非常に簡単だが何やってるのかは謎。。とりあえずいつか調べる。
setup.py
#!/usr/bin/env python from setuptools import find_packages, setup # name can be any name. This name will be used to create .egg file. # name that is used in packages is the one that is used in the trac.ini file. # use package name as entry_points setup( name='TracScrumHalf', version='0.10', packages=find_packages(exclude=['*.tests*']), entry_points = """ [trac.plugins] scrumhalf = scrumhalf """, package_data={'scrumhalf': ['templates/*.html', 'htdocs/css/*.css', 'htdocs/images/*']}, )
setuptoolsの為のファイル。
インストール
setup.pyのあるディレクトリで、
python setup.py develop
を実行。developを指定すると開発用インストール。python/site-packages以下にリンクが張られて、以降setup.pyを再実行する必要がなくなる・・・らしい。
Trac再起動
今回はTracdを使っているので、それを再起動する。自分はkill -9でshutdownしているけど、他に良い方法あるのかな??
Pluginを有効にする。
TracにAdmin権限を持つユーザでログインし、WebAdminより有効にする。
「Apply Changes」ボタンを押すと、500エラーになってしまうが、慌てず騒がず
trac-admin <Tracプロジェクト・ディレクトリパス> upgrade
Javaの是非
最近、スクリプト言語が流行ってきて、Javaバッシングが増えてきている気がする。
まあ言語自体のバッシングは別にいいと思うんだけど、ユーザまで対象にしてバッシング始めると、不要なイザコザが生まれますよね。
Javaは良くも悪くも枯れたんだな〜と思う。
言語や技術のユーザって枯れていない頃は優秀な人の比率がとても高い。でも枯れてくると、案件が増えて人が足りなくなるから、優秀でない(モチベーションの低い)ユーザ比率がとても高くなってくる。でもこれは歴史的に仕方のないことで、むしろ喜ばしいことじゃないかな。
Rubyだってもし今後メジャーになったら同じ道をたどるでしょ。
ともあれ、技術系のブログを見てる人ってのは少なからずモチベーション高い人なわけで、そこに「javaユーザは無能」とか一括りの記述をされたら、そりゃカチンと来ますよね。