スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

tracのマイルストーンもcommitメッセージで完了にしたい

「tracのマイルストーンもcommitメッセージで完了にしたい」とつぶやいたら、
@dexdev さんが、すぐにパッチをつくってくれました。
https://twitter.com/#!/dexdev/status/174380766506127360

tracの0.12だとpost-commit-hook使わない実装に変わっていたので、
教えてもらったパッチを参考に、プラグインで動くようにしてみました。

とりあえず、コミットでマイルストーンを完了に出きるようにはなったので、
マイルストーン側に完了時のコミットメッセージを追記するように修正予定。


 
# -*- coding: utf-8 -*-
from datetime import datetime
import re
from trac.core import Component, implements
from trac.config import Option
from trac.ticket import Milestone
from trac.util.datefmt import utc
from trac.versioncontrol import IRepositoryChangeListener, RepositoryManager
from trac.versioncontrol.web_ui.changeset import ChangesetModule
class CommitMilestoneUpdater(Component):
    implements(IRepositoryChangeListener)
    envelope = Option('milestone', 'commit_milestone_update_envelope', '',
        u"""Require commands to be enclosed in an envelope.
        
        Must be empty or contain two characters. For example, if set to "[]",
        then commands must be in the form of [complete 1.0α].""")
    commands_complete = Option('milestone', 'commit_milestone_update_commands.complete',
        'complete completed completes',
        """Commands that complete milestone.""")
    milestone_command = (r'(?P<action>[A-Za-z]*)\s\s*(?P<milestone>[^\s]*)\s*')
    @property
    def command_re(self):
        (begin, end) = (re.escape(self.envelope[0:1]),
                        re.escape(self.envelope[1:2]))
        return re.compile(begin + self.milestone_command + end)
    _last_cset_id = None
    # IRepositoryChangeListener methods
    def changeset_added(self, repos, changeset):
        if self._is_duplicate(changeset):
            return
        milestone = self._extract_milestone(changeset.message)
        self._update(milestone, repos, changeset )
    def changeset_modified(self, repos, changeset, old_changeset):
        if self._is_duplicate(changeset):
            return
        milestone = self._extract_milestone(changeset.message)
        self._update(milestone, repos, changeset )
    # private methods
    def _is_duplicate(self, changeset):
        # Avoid duplicate changes with multiple scoped repositories
        cset_id = (changeset.rev, changeset.message, changeset.author,
                   changeset.date)
        if cset_id != self._last_cset_id:
            self._last_cset_id = cset_id
            return False
        return True
    def _extract_milestone(self, message):
        cmd_groups = self.command_re.findall(message)
        for cmd, milestone_name in cmd_groups:
            for each in self.commands_complete.split():
                if cmd == each:
                    db = self.env.get_db_cnx()
                    return Milestone(self.env, milestone_name, db)
        return None
    def _make_changeset_info(self, repos, changeset):
        revstring = str(changeset.rev)
        if repos.reponame:
            revstring += '/' + repos.reponame
        return """[changeset:%s]""" % (revstring)
    def _update(self, milestone, repos, changeset):
        changeset_info = self._make_changeset_info(repos, changeset)
        milestone.completed = datetime.now(utc)
        milestone.update()
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメント

Secret

プロフィール

tenma

Author:tenma


AI好きのプログラマ
基本伊豆ダイバー(100本達成)
ゲーム実況好きのニコ厨(プレミアム会員)


follow _tenma at http://twitter.com

最新記事
最新コメント
最新トラックバック
カテゴリ
検索フォーム
リンク
FC2カウンター
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。