Skip to content

Commit 7ca5472

Browse files
committed
wip
1 parent 9935f27 commit 7ca5472

File tree

1 file changed

+184
-3
lines changed

1 file changed

+184
-3
lines changed

scripts/repostat

Lines changed: 184 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,14 @@ def init_db(conn: sqlite3.Connection) -> None:
182182
plan TEXT NOT NULL,
183183
created_at TEXT DEFAULT (datetime('now'))
184184
);
185+
186+
CREATE TABLE IF NOT EXISTS apply_history (
187+
id INTEGER PRIMARY KEY AUTOINCREMENT,
188+
migration_plan_id INTEGER NOT NULL,
189+
applied_at TEXT DEFAULT (datetime('now')),
190+
notes TEXT,
191+
FOREIGN KEY (migration_plan_id) REFERENCES migration_plan(id)
192+
);
185193
"""
186194
)
187195
conn.commit()
@@ -941,9 +949,12 @@ def pick_move() -> None:
941949
# ---------------------------------------------------------------------------
942950

943951

944-
@app.command("show-plan")
945-
def show_plan() -> None:
946-
"""Show current ``migration_plan`` entries (mirror/move/etc.)."""
952+
@app.command("plan")
953+
def plan() -> None:
954+
"""Show the current migration *plan* (Terraform-style).
955+
956+
This is the main view of what will happen when you run ``repostat apply``.
957+
"""
947958

948959
conn = get_conn()
949960
cur = conn.cursor()
@@ -953,6 +964,11 @@ def show_plan() -> None:
953964
console.rule("Migration plan")
954965
if not rows:
955966
console.print("[yellow]No migration_plan entries yet.[/yellow]")
967+
console.print()
968+
console.print("[bold]Next steps:[/bold]")
969+
console.print("- Use [cyan]repostat pick-mirror[/cyan] or [cyan]repostat pick-move[/cyan] to add items to the plan.")
970+
console.print("- Run [cyan]repostat history[/cyan] to view previous apply runs.")
971+
console.print("- Run [cyan]repostat refresh[/cyan] to sync GitHub / Forgejo / local state.")
956972
return
957973

958974
table = Table(show_header=True, header_style="bold green", box=box.SIMPLE)
@@ -974,13 +990,166 @@ def show_plan() -> None:
974990
)
975991

976992
console.print(table)
993+
console.print()
994+
console.print("[bold]Next steps:[/bold]")
995+
console.print("- Run [cyan]repostat apply[/cyan] to record an apply of this plan.")
996+
console.print("- Run [cyan]repostat history[/cyan] to see previous apply runs.")
997+
998+
999+
# Alias: keep the old name for muscle memory
1000+
@app.command("show-plan")
1001+
def show_plan_alias() -> None:
1002+
"""Alias for :func:`plan` (kept for muscle memory)."""
1003+
1004+
plan()
1005+
1006+
1007+
# ---------------------------------------------------------------------------
1008+
# apply / history: terraform-style workflow
1009+
# ---------------------------------------------------------------------------
1010+
1011+
1012+
@app.command()
1013+
def apply() -> None:
1014+
"""Record an *apply* of the current migration plan.
1015+
1016+
This does **not** perform any network or Git operations yet; it simply
1017+
snapshots the current ``migration_plan`` table into ``apply_history`` so
1018+
that you can track when you considered a plan "applied".
1019+
"""
1020+
1021+
conn = get_conn()
1022+
cur = conn.cursor()
1023+
1024+
cur.execute("SELECT * FROM migration_plan ORDER BY created_at DESC, id DESC")
1025+
rows = cur.fetchall()
1026+
1027+
console.rule("Apply migration plan")
1028+
if not rows:
1029+
console.print("[yellow]No migration_plan entries to apply.[/yellow]")
1030+
console.print()
1031+
console.print("[bold]Next steps:[/bold]")
1032+
console.print("- Run [cyan]repostat plan[/cyan] (or [cyan]repostat show-plan[/cyan]) to see the current plan.")
1033+
console.print("- Use [cyan]repostat pick-mirror[/cyan] or [cyan]repostat pick-move[/cyan] to build a plan.")
1034+
return
1035+
1036+
table = Table(show_header=True, header_style="bold green", box=box.SIMPLE)
1037+
table.add_column("ID", justify="right")
1038+
table.add_column("Plan")
1039+
table.add_column("GitHub")
1040+
table.add_column("Forgejo")
1041+
table.add_column("Local path")
1042+
1043+
for r in rows:
1044+
table.add_row(
1045+
str(r["id"]),
1046+
r["plan"],
1047+
r["github_full_name"] or "",
1048+
r["forgejo_full_name"] or "",
1049+
r["local_path"] or "",
1050+
)
1051+
1052+
console.print(table)
1053+
1054+
confirm = input("Record this apply in history? [y/N]: ").strip().lower()
1055+
if confirm not in {"y", "yes"}:
1056+
console.print("[yellow]Apply aborted; nothing recorded.[/yellow]")
1057+
console.print()
1058+
console.print("[bold]Next steps:[/bold]")
1059+
console.print("- Run [cyan]repostat plan[/cyan] to review the plan again.")
1060+
console.print("- Run [cyan]repostat history[/cyan] to inspect previous applies.")
1061+
return
1062+
1063+
for r in rows:
1064+
cur.execute(
1065+
"INSERT INTO apply_history (migration_plan_id, notes) VALUES (?, ?)",
1066+
(r["id"], "applied via `repostat apply`"),
1067+
)
1068+
conn.commit()
1069+
1070+
console.print("[green]Apply recorded in history.[/green]")
1071+
console.print()
1072+
console.print("[bold]Next steps:[/bold]")
1073+
console.print("- Run [cyan]repostat refresh[/cyan] to sync current repo state.")
1074+
console.print("- Run [cyan]repostat history[/cyan] to view apply history.")
1075+
1076+
1077+
@app.command()
1078+
def history() -> None:
1079+
"""Show apply history for migration plans.
1080+
1081+
Each row represents a call to ``repostat apply`` and which plan entries
1082+
were included in that apply.
1083+
"""
1084+
1085+
conn = get_conn()
1086+
cur = conn.cursor()
1087+
1088+
cur.execute(
1089+
"""
1090+
SELECT
1091+
h.id AS history_id,
1092+
h.applied_at AS applied_at,
1093+
h.notes AS notes,
1094+
p.id AS plan_id,
1095+
p.plan AS plan,
1096+
p.github_full_name,
1097+
p.forgejo_full_name,
1098+
p.local_path
1099+
FROM apply_history h
1100+
JOIN migration_plan p ON p.id = h.migration_plan_id
1101+
ORDER BY h.applied_at DESC, h.id DESC
1102+
"""
1103+
)
1104+
rows = cur.fetchall()
1105+
1106+
console.rule("Apply history")
1107+
if not rows:
1108+
console.print("[yellow]No applies recorded yet.[/yellow]")
1109+
console.print()
1110+
console.print("[bold]Next steps:[/bold]")
1111+
console.print("- Run [cyan]repostat plan[/cyan] to see the current plan.")
1112+
console.print("- Run [cyan]repostat apply[/cyan] to record an apply.")
1113+
return
1114+
1115+
table = Table(show_header=True, header_style="bold green", box=box.SIMPLE)
1116+
table.add_column("History ID", justify="right")
1117+
table.add_column("Applied at")
1118+
table.add_column("Plan ID", justify="right")
1119+
table.add_column("Plan")
1120+
table.add_column("GitHub")
1121+
table.add_column("Forgejo")
1122+
table.add_column("Local path")
1123+
table.add_column("Notes")
1124+
1125+
for r in rows:
1126+
table.add_row(
1127+
str(r["history_id"]),
1128+
r["applied_at"] or "",
1129+
str(r["plan_id"]),
1130+
r["plan"],
1131+
r["github_full_name"] or "",
1132+
r["forgejo_full_name"] or "",
1133+
r["local_path"] or "",
1134+
r["notes"] or "",
1135+
)
1136+
1137+
console.print(table)
1138+
console.print()
1139+
console.print("[bold]Next steps:[/bold]")
1140+
console.print("- Run [cyan]repostat plan[/cyan] to review the current plan.")
1141+
console.print("- Run [cyan]repostat apply[/cyan] to record a new apply.")
9771142

9781143

9791144
# ---------------------------------------------------------------------------
9801145
# stats: quick overview / suggestions (and default command)
9811146
# ---------------------------------------------------------------------------
9821147

9831148

1149+
# @app.command(): quick overview / suggestions (and default command)
1150+
# # ---------------------------------------------------------------------------
1151+
1152+
9841153
@app.command()
9851154
def stats() -> None:
9861155
"""Show a quick summary of what's in the DB and some suggestions."""
@@ -1007,6 +1176,8 @@ def stats() -> None:
10071176

10081177
cur.execute("SELECT COUNT(*) FROM migration_plan")
10091178
plan_count = int(cur.fetchone()[0])
1179+
cur.execute("SELECT COUNT(*) FROM apply_history")
1180+
history_count = int(cur.fetchone()[0])
10101181

10111182
console.rule("Repo stats")
10121183
table = Table(show_header=False, box=box.MINIMAL_DOUBLE_HEAD)
@@ -1017,6 +1188,7 @@ def stats() -> None:
10171188
table.add_row("Local missing remote", str(missing_remote))
10181189
table.add_row("Local missing README", str(missing_readme))
10191190
table.add_row("Migration plan entries", str(plan_count))
1191+
table.add_row("Apply history entries", str(history_count))
10201192
console.print(table)
10211193

10221194
console.print()
@@ -1033,6 +1205,15 @@ def stats() -> None:
10331205
console.print(
10341206
"- Run [cyan]repostat show-missing[/cyan] and [cyan]repostat pick-newrepo[/cyan] to clean up local repos."
10351207
)
1208+
if plan_count == 0:
1209+
console.print(
1210+
"- Build a plan with [cyan]repostat pick-mirror[/cyan] or [cyan]repostat pick-move[/cyan]."
1211+
)
1212+
else:
1213+
console.print("- Review the current plan with [cyan]repostat plan[/cyan].")
1214+
console.print("- Record an apply with [cyan]repostat apply[/cyan].")
1215+
if history_count:
1216+
console.print("- Inspect previous applies with [cyan]repostat history[/cyan].")
10361217
if gh_count and fj_count:
10371218
console.print(
10381219
"- Run [cyan]repostat show-only-github[/cyan] to see repos that exist only on GitHub."

0 commit comments

Comments
 (0)