diff options
Diffstat (limited to 'restore.go')
-rw-r--r-- | restore.go | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/restore.go b/restore.go new file mode 100644 index 0000000..f99196a --- /dev/null +++ b/restore.go @@ -0,0 +1,75 @@ +/* Restore from a series of restic snapshots. */ +package main + +import ( + "fmt" + "os" + "io" + "log" + "strings" + "slices" +) + +type Snapshot struct { + id string + dirs []string +} + +func main() { + body, err := io.ReadAll(os.Stdin) + if err != nil { + log.Fatal(err) + } + + var shots []Snapshot + var current Snapshot + + lines := strings.Split(string(body), "\n") + for _, s := range lines[2:len(lines) - 3] { + split := strings.Split(s, " ") + if len(s) == 0 { + shots = append(shots, current) + // Old snapshot is garbage collected. + current = Snapshot{} + } else if s[0] == ' ' { + // Directory at the end of line. + current.dirs = append(current.dirs, split[len(split) - 1]) + } else { + // New snapshot. + current.id = split[0] + current.dirs = []string{split[len(split) - 1]} + } + } + + // Last not followed by blank line. + shots = append(shots, current) + + /* + for _, shot := range shots { + fmt.Println(shot.id) + for _, dir := range shot.dirs { + fmt.Println("\t" + dir) + } + } */ + + /* Traverse through the snapshots in reverse order. + The earlier entries covered by current are removed. */ + seen := []string{} + list := make(map[string]string) + for i := len(shots) - 1; i >= 0; i-- { + for _, dir := range(shots[i].dirs) { + if !slices.Contains(seen, dir) { + seen = append(seen, dir) + list[shots[i].id] += dir + "," + } + } + } + + for id, paths := range list { + for _, dir := range strings.Split(paths, ",") { + if dir != "" { + fmt.Println("restic restore " + id + ":" + dir + " --overwrite=if-newer --target=" + dir) + } + } + } +} |