simple.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package versioner
  2. import (
  3. "os"
  4. "path/filepath"
  5. "sort"
  6. "strconv"
  7. "time"
  8. "github.com/calmh/syncthing/osutil"
  9. )
  10. func init() {
  11. // Register the constructor for this type of versioner with the name "simple"
  12. Factories["simple"] = NewSimple
  13. }
  14. // The type holds our configuration
  15. type Simple struct {
  16. keep int
  17. }
  18. // The constructor function takes a map of parameters and creates the type.
  19. func NewSimple(params map[string]string) Versioner {
  20. keep, err := strconv.Atoi(params["keep"])
  21. if err != nil {
  22. keep = 5 // A reasonable default
  23. }
  24. s := Simple{
  25. keep: keep,
  26. }
  27. if debug {
  28. l.Debugf("instantiated %#v", s)
  29. }
  30. return s
  31. }
  32. // Move away the named file to a version archive. If this function returns
  33. // nil, the named file does not exist any more (has been archived).
  34. func (v Simple) Archive(path string) error {
  35. _, err := os.Stat(path)
  36. if err != nil && os.IsNotExist(err) {
  37. return nil
  38. }
  39. if debug {
  40. l.Debugln("archiving", path)
  41. }
  42. file := filepath.Base(path)
  43. dir := filepath.Join(filepath.Dir(path), ".stversions")
  44. err = os.MkdirAll(dir, 0755)
  45. if err != nil && !os.IsExist(err) {
  46. return err
  47. } else {
  48. osutil.HideFile(dir)
  49. }
  50. ver := file + "~" + time.Now().Format("20060102-150405")
  51. err = osutil.Rename(path, filepath.Join(dir, ver))
  52. if err != nil {
  53. return err
  54. }
  55. versions, err := filepath.Glob(filepath.Join(dir, file+"~*"))
  56. if err != nil {
  57. l.Warnln(err)
  58. return nil
  59. }
  60. if len(versions) > v.keep {
  61. sort.Strings(versions)
  62. for _, toRemove := range versions[:len(versions)-v.keep] {
  63. err = os.Remove(toRemove)
  64. if err != nil {
  65. l.Warnln(err)
  66. }
  67. }
  68. }
  69. return nil
  70. }