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))