PlanRaw: an original that was archived but never removed (it has a .processed marker AND a byte-identical copy under raw/processed/) is deleted with its marker; a marker without a note is deleted; an unmarked note, a note without an identical archive copy, and AutoTunnel's tunnel-candidates-* review queue are never touched. The archive key flattens the whole path so raw/x.md and wiki/sources/x.md cannot overwrite each other. Live dry run: 84 entries, 16 move, 53 delete (24 junk + 29 raw leftovers), 15 left. Mutation-checked. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
68 lines
2.2 KiB
Go
68 lines
2.2 KiB
Go
// Command legacymove clears the leftovers of the retired layout (hyperguild
|
|
// #209): wiki/sources/ (videos and articles move to the default wing, the
|
|
// auto-tunnel review logs are deleted) and raw/ (originals archived before inbox
|
|
// zero, their markers, orphan markers). Default is a dry run that prints the
|
|
// plan; -apply performs it after archiving every page it touches; -rollback
|
|
// restores from an archive.
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/mathiasbq/hyperguild/ingestion/internal/legacymove"
|
|
)
|
|
|
|
func main() {
|
|
brain := flag.String("brain", "/var/lib/supervisor/brain", "brain directory")
|
|
wing := flag.String("wing", "web-clip", "wing that receives video and article sources")
|
|
apply := flag.Bool("apply", false, "perform the plan (default: dry run)")
|
|
rollback := flag.String("rollback", "", "restore from this archive dir (brain-relative, e.g. archive/wing-migration-2026-10-20)")
|
|
flag.Parse()
|
|
|
|
if err := run(*brain, *wing, *apply, *rollback); err != nil {
|
|
slog.Error("legacymove", "err", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func run(brain, wing string, apply bool, rollback string) error {
|
|
if rollback != "" {
|
|
if err := legacymove.Rollback(brain, rollback); err != nil {
|
|
return err
|
|
}
|
|
fmt.Println("rolled back from", rollback)
|
|
return nil
|
|
}
|
|
sources, err := legacymove.Plan(brain, wing)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
rawLeft, err := legacymove.PlanRaw(brain)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
items := append(sources, rawLeft...)
|
|
counts := map[legacymove.Action]int{}
|
|
for _, it := range items {
|
|
counts[it.Action]++
|
|
}
|
|
fmt.Printf("# legacy plan\n\n%d entries: %d move, %d delete, %d left\n\n", len(items), counts[legacymove.Move], counts[legacymove.Delete], counts[legacymove.Skip])
|
|
fmt.Println("| action | from | to | why |")
|
|
fmt.Println("|---|---|---|---|")
|
|
for _, it := range items {
|
|
fmt.Printf("| %s | %s | %s | %s |\n", it.Action, it.From, it.To, strings.ReplaceAll(it.Reason, "|", "/"))
|
|
}
|
|
if !apply {
|
|
fmt.Println("\n_dry run: nothing was changed_")
|
|
return nil
|
|
}
|
|
res, err := legacymove.Apply(brain, items, time.Now())
|
|
fmt.Printf("\nmoved %d, deleted %d; archive: %s\n", res.Moved, res.Deleted, res.ArchiveDir)
|
|
return err
|
|
}
|