Files
troupe-standup/wizard-work/volt/q150/insert_row.py
T

46 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""insert_row.py <ledger.tsv> '<c>|<path>|<verdict>|<rc>|<secs>|<note>|<blob>|<host>'
Insert one already-measured row into a ledger, in path order, replacing any
existing row for the same path.
Why this exists (Q150): a `--merge` run removes the rows it is about to re-take
BEFORE it takes them, so a run killed mid-flight leaves the ledger without the
rows it had not rewritten. The reading for that path was taken this tick and is
in the transcript; dropping it would either lose a measurement or force a
second 30-minute HTTP pass over the same bytes. The row goes back exactly as
measured -- fields are '|'-separated so no tab has to survive shell quoting.
A row whose rc column is empty (TIMEOUT/ERROR/MISSING) is written with an empty
fifth... fourth column, which is the format emit() itself writes.
"""
import sys
ledger, spec = sys.argv[1], sys.argv[2]
cells = spec.split("|")
if len(cells) != 8:
sys.exit("insert_row: need 8 '|'-separated cells, got %d" % len(cells))
if "\t" in spec:
sys.exit("insert_row: refusing -- spec contains a literal tab")
path = cells[1]
rows, out = 0, []
for line in open(ledger, encoding="utf-8"):
line = line.rstrip("\n")
if line.startswith("#") or not line:
out.append(line)
continue
rows += 1
if line.split("\t")[1] == path:
continue # the row being replaced
out.append(line)
seen = [i for i, l in enumerate(out) if not l.startswith("#") and l]
keep = [l for l in out if not l.startswith("#")]
head = [l for l in out if l.startswith("#")]
keep.append("\t".join(cells))
keep.sort(key=lambda l: l.split("\t")[1])
open(ledger, "w", encoding="utf-8").write("\n".join(head + keep) + "\n")
print("inserted: %s" % path)
print("rows: %d -> %d" % (rows, len(keep)))