diff options
author | Hristo Venev <hristo@venev.name> | 2021-08-26 17:30:35 +0300 |
---|---|---|
committer | Hristo Venev <hristo@venev.name> | 2021-08-26 17:30:35 +0300 |
commit | a2b2fe7da78378dc6a64f58c14e907496c9adea9 (patch) | |
tree | bc7a3c119afb2ca25fd232bbcaafe0e05bf93b75 /import_series.py |
Diffstat (limited to 'import_series.py')
-rw-r--r-- | import_series.py | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/import_series.py b/import_series.py new file mode 100644 index 0000000..800f0c9 --- /dev/null +++ b/import_series.py @@ -0,0 +1,86 @@ +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)) |