summaryrefslogtreecommitdiff
path: root/import_series.py
diff options
context:
space:
mode:
Diffstat (limited to 'import_series.py')
-rw-r--r--import_series.py86
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))