summaryrefslogblamecommitdiff
path: root/import_series.py
blob: 800f0c9de4c81540ab2713b669cec9c17c7d041b (plain) (tree)





















































































                                                                     
import patchstate as ps
import io, os, sys

def lcs(a, b, *, key):
    a = [*a]
    b = [*b]
    if not a or not b:
        return []

    kas = [*map(key, a)]

    m = [(0,)]
    for v in a:
        m.append((m[-1][0] + 1, v, None, m[-1]))
    for v in b:
        kb = key(v)

        mi = iter(m)
        mv = next(mi)
        m2 = [(mv[0] + 1, None, v, mv)]
        for ia,mv in enumerate(mi):
            if kas[ia] == kb:
                mv = m[ia]
                m2.append((mv[0], a[ia], v, mv))
                continue
            mv1 = m2[-1]
            if mv[0] <= mv1[0]:
                m2.append((mv[0] + 1, None, v, mv))
            else:
                m2.append((mv1[0] + 1, a[ia], None, mv1))
            del mv1
            del ia
        del mi, mv
        m = m2

    m = m[-1]
    del v, a, b, kas
    m2 = []
    while len(m) == 4:
        _,a,b,m = m
        m2.append((a,b))
    assert m == (0,)
    m2.reverse()
    return m2

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, import_path] = path

    repo = ps.Repository(repo_path)

    pnew = repo.import_dir(import_path)

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

    r = []
    for p1,p2 in lcs(pcur.info, pnew.info, key=lambda p: p.patch_id):
        if p1 is None:
            r.append(p2)
            continue

        if p2 is None:
            r.append(p1.update(new_mode='gone'))
            continue

        r.append(p2.update(mode=p1.mode, info=p1.info))

    pnew.info = r

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

    repo.gc({p.patch_hash for p in pnew.info})

    return 0

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