tool to sync save states for my games
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.5KB

  1. // command saves pushes and pulls save files from my server
  2. package main
  3. import (
  4. "bytes"
  5. "fmt"
  6. "io/ioutil"
  7. "log"
  8. "os"
  9. "os/exec"
  10. "os/user"
  11. )
  12. const usage = "saves <list|push|pull|link>"
  13. func main() {
  14. if len(os.Args) != 2 {
  15. fmt.Fprintf(os.Stderr, "%s\n", usage)
  16. os.Exit(1)
  17. }
  18. u, err := user.Current()
  19. if err != nil {
  20. fmt.Fprintf(os.Stderr, "cannot calculate home dir: %v", err)
  21. os.Exit(1)
  22. }
  23. docs := fmt.Sprintf("%s/Documents", u.HomeDir)
  24. saves := fmt.Sprintf("%s/Documents/saves", u.HomeDir)
  25. appSupport := fmt.Sprintf("%s/Library/Application Support", u.HomeDir)
  26. var cmd *exec.Cmd
  27. switch os.Args[1] {
  28. case "pull", "push":
  29. if os.Args[1] == "push" {
  30. cmd = exec.Command("rsync", "-auv", "sj.mcquay.me:~/docs/saves", fmt.Sprintf("%s/", docs))
  31. } else {
  32. cmd = exec.Command("rsync", "-auv", fmt.Sprintf("%s/saves", docs), "sj.mcquay.me:~/docs/")
  33. }
  34. if cmd == nil {
  35. fmt.Fprintf(os.Stderr, "failed to populate command\n")
  36. os.Exit(1)
  37. }
  38. var so, se bytes.Buffer
  39. cmd.Stdout = &so
  40. cmd.Stderr = &se
  41. if rc := cmd.Run(); rc != nil {
  42. log.Printf("cmd: %+v", cmd)
  43. log.Printf("so: %s", so.Bytes())
  44. log.Printf("se: %s", se.Bytes())
  45. log.Printf("rc: %+v", rc)
  46. }
  47. case "link", "ln":
  48. dirs, err := ioutil.ReadDir(saves)
  49. if err != nil {
  50. fmt.Fprintf(os.Stderr, "could not read saves dir: %+v\n", err)
  51. os.Exit(1)
  52. }
  53. for _, dir := range dirs {
  54. src := fmt.Sprintf("%s/%s", saves, dir.Name())
  55. dst := fmt.Sprintf("%s/%s", appSupport, dir.Name())
  56. if err := os.RemoveAll(dst); err != nil {
  57. fmt.Fprintf(os.Stderr, "could not make way for link:%+v\n", err)
  58. os.Exit(1)
  59. }
  60. if err := os.Symlink(src, dst); err != nil {
  61. fmt.Fprintf(os.Stderr, "could not link:%+v\n", err)
  62. os.Exit(1)
  63. }
  64. }
  65. case "list", "ls":
  66. known := map[string]bool{}
  67. dirs, err := ioutil.ReadDir(saves)
  68. if err != nil {
  69. fmt.Fprintf(os.Stderr, "could not read saves dir: %+v\n", err)
  70. os.Exit(1)
  71. }
  72. for _, dir := range dirs {
  73. status := "l"
  74. dst := fmt.Sprintf("%s/%s", appSupport, dir.Name())
  75. if _, err := os.Lstat(dst); os.IsNotExist(err) {
  76. status = "m"
  77. }
  78. fmt.Printf("%s %s\n", status, dir.Name())
  79. known[dir.Name()] = true
  80. }
  81. dirs, err = ioutil.ReadDir(appSupport)
  82. if err != nil {
  83. fmt.Fprintf(os.Stderr, "could not read saves dir: %+v\n", err)
  84. os.Exit(1)
  85. }
  86. for _, dir := range dirs {
  87. if dir.Mode()&os.ModeSymlink == os.ModeSymlink {
  88. if _, ok := known[dir.Name()]; !ok {
  89. fmt.Fprintf(os.Stderr, "? %s\n", dir.Name())
  90. }
  91. }
  92. }
  93. default:
  94. fmt.Fprintf(os.Stderr, "%s\n", usage)
  95. os.Exit(1)
  96. }
  97. }