trac.ini を更新するスクリプト書いてみた

Trac 月から Trac Lightning にアップグレードする際、すべてのプロジェクトの trac.ini に、inherit セクションの追加と、チケットのカスタムフィールドの修正をしないといけません。プロジェクトが1個ならまぁ手作業でもいいんですが、10個くらいあるので、手作業だと数分かかってしまいます。

Trac Lightning にアップグレードして大丈夫か検証するために、仮想マシン上で何度もアップグレード作業をやってるんですが、そのたび手作業で trac.ini 書き変えるの面倒です。というか、やってられない。検証が上手くいかずイライラしてきたので、Python でスクリプト書いてみました。

# -*- coding: utf-8 -*-

import glob
import os
import ConfigParser

TRAC_LIGHT_HOME = "C:/TracLight"
PROJECTS_DIR = TRAC_LIGHT_HOME + "/projects"
TRAC_DIR = PROJECTS_DIR + "/trac"
INHERIT_FILE = TRAC_LIGHT_HOME + "/python/share/trac/conf/trac.ini"
INHERIT_SECTION = "inherit"
TICKET_CUSTOM_SECTION = "ticket-custom"

def update_ini_file(path):
    # ConfigParser を使って ini ファイルを編集
    config = ConfigParser.ConfigParser()
    config.read(path)
    
    # inherit セクションを編集
    if not config.has_section(INHERIT_SECTION):
        config.add_section(INHERIT_SECTION)
    config.set(INHERIT_SECTION, "file", INHERIT_FILE)

    # ticket-custom セクションを編集
    if not config.has_section(TICKET_CUSTOM_SECTION):
        config.add_section(TICKET_CUSTOM_SECTION)
    # 開始予定日
    config.set(TICKET_CUSTOM_SECTION, "due_assign", "text")
    config.set(TICKET_CUSTOM_SECTION, "due_assign.date", "true")
    config.set(TICKET_CUSTOM_SECTION, "due_assign.date_empty", "on")
    config.set(TICKET_CUSTOM_SECTION, "due_assign.label", u"開始予定日")
    config.set(TICKET_CUSTOM_SECTION, "due_assign.order", "0")
    # 終了予定日
    config.set(TICKET_CUSTOM_SECTION, "due_close", "text")
    config.set(TICKET_CUSTOM_SECTION, "due_close.date", "true")
    config.set(TICKET_CUSTOM_SECTION, "due_close.date_empty", "on")
    config.set(TICKET_CUSTOM_SECTION, "due_close.label", u"終了予定日")
    config.set(TICKET_CUSTOM_SECTION, "due_close.order", "1")
    # 進捗率
    config.set(TICKET_CUSTOM_SECTION, "complete", "text")
    config.set(TICKET_CUSTOM_SECTION, "complete.label", u"進捗率(%)")
    config.set(TICKET_CUSTOM_SECTION, "complete.order", "2")

    # ファイルを上書き
    try:
        file = open(path, "w")
        file.write("# -*- coding: utf-8 -*-\n")
        config.write(file)
    finally:
        file.close()
    print(u"'%s' を更新しました。" % path)

list = glob.glob(TRAC_DIR + "/*")
for path in list:
    if not os.path.isfile(path):
        # フォルダのとき
        trac_ini_path = path + "/conf/trac.ini"
        update_ini_file(trac_ini_path)

プロジェクトが何十個あろうと、スクリプトを実行すれば書き変え完了。おかげでだいぶイライラが収まりました。

それにしても、ini ファイルを扱うクラスが標準ライブラリに含まれているとは思って……思っていました。Python 標準ライブラリの充実っぷりはスゴイですね。