2013年4月19日金曜日

patch.py(仮題)

手作業で差分からファイルを作るのは辛いのでpythonで書いてみました。
ZIPファイルを全部展開する必要はなくて、必要なファイルだけに差分を適用して書き出します。

使用例:
c:\python27\python patch.py AN11321.zip < diff.txt


# patch.py 2013/4/19
import zipfile
import sys
import re
import copy

def patch(fromarc, diff):
    from_zip = zipfile.ZipFile(fromarc)
    assert(from_zip)
    tolines = {}
    for line in diff:
        if line.find("--- ") == 0:
            fromfile = line[4:].rstrip()
            assert(fromfile in from_zip.namelist())
            with from_zip.open(fromfile, 'U') as f:
                fromlines = f.readlines()
        elif line.find("+++ ") == 0:
            tofile = line[4:].rstrip()
            tolines[tofile] = copy.deepcopy(fromlines)
            print "%s <- %s" % (tofile, fromfile)
        elif line.find("@@ ") == 0:
            m = re.search(r"@@\s+\-(\d+),(\d+)\s+\+(\d+),(\d+)", line)
            assert(m)
            from_pos = int(m.group(1)) - 1
            to_pos = int(m.group(3)) - 1
        elif line.find(" ") == 0:
            assert(line[1:] == fromlines[from_pos])
            from_pos += 1
            assert(line[1:] == tolines[tofile][to_pos])
            to_pos += 1
        elif line.find("+") == 0:
            line2 = line[1:]
            tolines[tofile].insert(to_pos, line[1:])
            to_pos += 1
        elif line.find("-") == 0:
            assert(line[1:] == fromlines[from_pos])
            from_pos += 1
            assert(line[1:] == tolines[tofile][to_pos])
            del tolines[tofile][to_pos]
        else:
            assert(0)

    for tofile in tolines:
        with open(tofile, "w") as f:
            f.writelines(tolines[tofile])

if __name__ == '__main__':
    fromarc = sys.argv[1]
    diff = sys.stdin.readlines()
    patch(fromarc, diff)


(2013/4/19)
---

0 件のコメント: