summaryrefslogtreecommitdiff
path: root/ungone_series.py
blob: 065ed01d0ad189db61a73357f1abc8da953349d1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import patchstate as ps
import io, os, sys
from import_series import lcs

def parse_prev(info):
    if not info.startswith('(was ') or not info.endswith(')'):
        raise ValueError
    return info[5:-1]

def main(args):
    args = iter(args)
    arg0 = next(args)

    @ps.argparse_all(args)
    def path(arg):
        raise RuntimeError(f'Invalid argument: {arg!r}')

    [repo_path] = path

    repo = ps.Repository(repo_path)

    with io.open(os.path.join(repo.path, 'series'), 'r') as f:
        pcur = ps.Series.parse(f.read())

    gone_seq = []
    new_seq = []
    updated = {}

    def fix_seq():
        s = lcs(gone_seq, new_seq, key=lambda p: p.patch_title)
        del gone_seq[:]
        del new_seq[:]

        for p_gone, p_new in s:
            if p_gone is None or p_new is None:
                continue
            updated[p_new] = parse_prev(p_gone.info[0])
            updated[p_gone] = None

    for i,pi in enumerate(pcur.info):
        m = pi.mode
        if m == 'gone':
            gone_seq.append(pi)
        elif m == 'new':
            new_seq.append(pi)
        else:
            fix_seq()
    fix_seq()

    inf = []
    for pi in pcur.info:
        try:
            mode = updated[pi]
        except KeyError:
            pass
        else:
            if mode is None:
                continue
            assert pi.mode == 'new'
            pi = pi.update(mode=mode)
        inf.append(pi)

    pnew = ps.Series(inf).fmt()
    with io.open(os.path.join(repo.path, 'series'), 'w') as f:
        f.write(pnew)

    return 0

if __name__ == '__main__':
    sys.exit(main(sys.argv))