all: Convert folders to use filesystem abstraction
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4228
This commit is contained in:
committed by
Jakob Borg
parent
ab8c2fb5c7
commit
3d8b4a42b7
@@ -8,11 +8,11 @@ package versioner
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/osutil"
|
||||
)
|
||||
|
||||
@@ -22,17 +22,17 @@ func init() {
|
||||
}
|
||||
|
||||
type Trashcan struct {
|
||||
folderPath string
|
||||
fs fs.Filesystem
|
||||
cleanoutDays int
|
||||
stop chan struct{}
|
||||
}
|
||||
|
||||
func NewTrashcan(folderID, folderPath string, params map[string]string) Versioner {
|
||||
func NewTrashcan(folderID string, fs fs.Filesystem, params map[string]string) Versioner {
|
||||
cleanoutDays, _ := strconv.Atoi(params["cleanoutDays"])
|
||||
// On error we default to 0, "do not clean out the trash can"
|
||||
|
||||
s := &Trashcan{
|
||||
folderPath: folderPath,
|
||||
fs: fs,
|
||||
cleanoutDays: cleanoutDays,
|
||||
stop: make(chan struct{}),
|
||||
}
|
||||
@@ -44,52 +44,47 @@ func NewTrashcan(folderID, folderPath string, params map[string]string) Versione
|
||||
// Archive moves the named file away to a version archive. If this function
|
||||
// returns nil, the named file does not exist any more (has been archived).
|
||||
func (t *Trashcan) Archive(filePath string) error {
|
||||
info, err := osutil.Lstat(filePath)
|
||||
if os.IsNotExist(err) {
|
||||
info, err := t.fs.Lstat(filePath)
|
||||
if fs.IsNotExist(err) {
|
||||
l.Debugln("not archiving nonexistent file", filePath)
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
if info.IsSymlink() {
|
||||
panic("bug: attempting to version a symlink")
|
||||
}
|
||||
|
||||
versionsDir := filepath.Join(t.folderPath, ".stversions")
|
||||
if _, err := os.Stat(versionsDir); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
versionsDir := ".stversions"
|
||||
if _, err := t.fs.Stat(versionsDir); err != nil {
|
||||
if !fs.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
l.Debugln("creating versions dir", versionsDir)
|
||||
if err := osutil.MkdirAll(versionsDir, 0777); err != nil {
|
||||
if err := t.fs.MkdirAll(versionsDir, 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
osutil.HideFile(versionsDir)
|
||||
t.fs.Hide(versionsDir)
|
||||
}
|
||||
|
||||
l.Debugln("archiving", filePath)
|
||||
|
||||
relativePath, err := filepath.Rel(t.folderPath, filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
archivedPath := filepath.Join(versionsDir, relativePath)
|
||||
if err := osutil.MkdirAll(filepath.Dir(archivedPath), 0777); err != nil && !os.IsExist(err) {
|
||||
archivedPath := filepath.Join(versionsDir, filePath)
|
||||
if err := t.fs.MkdirAll(filepath.Dir(archivedPath), 0777); err != nil && !fs.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
l.Debugln("moving to", archivedPath)
|
||||
|
||||
if err := osutil.Rename(filePath, archivedPath); err != nil {
|
||||
if err := osutil.Rename(t.fs, filePath, archivedPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the mtime to the time the file was deleted. This is used by the
|
||||
// cleanout routine. If this fails things won't work optimally but there's
|
||||
// not much we can do about it so we ignore the error.
|
||||
os.Chtimes(archivedPath, time.Now(), time.Now())
|
||||
t.fs.Chtimes(archivedPath, time.Now(), time.Now())
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -129,15 +124,15 @@ func (t *Trashcan) String() string {
|
||||
}
|
||||
|
||||
func (t *Trashcan) cleanoutArchive() error {
|
||||
versionsDir := filepath.Join(t.folderPath, ".stversions")
|
||||
if _, err := osutil.Lstat(versionsDir); os.IsNotExist(err) {
|
||||
versionsDir := ".stversions"
|
||||
if _, err := t.fs.Lstat(versionsDir); fs.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
cutoff := time.Now().Add(time.Duration(-24*t.cleanoutDays) * time.Hour)
|
||||
currentDir := ""
|
||||
filesInDir := 0
|
||||
walkFn := func(path string, info os.FileInfo, err error) error {
|
||||
walkFn := func(path string, info fs.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -147,7 +142,7 @@ func (t *Trashcan) cleanoutArchive() error {
|
||||
// directory was empty and try to remove it. We ignore failure for
|
||||
// the time being.
|
||||
if currentDir != "" && filesInDir == 0 {
|
||||
os.Remove(currentDir)
|
||||
t.fs.Remove(currentDir)
|
||||
}
|
||||
currentDir = path
|
||||
filesInDir = 0
|
||||
@@ -156,7 +151,7 @@ func (t *Trashcan) cleanoutArchive() error {
|
||||
|
||||
if info.ModTime().Before(cutoff) {
|
||||
// The file is too old; remove it.
|
||||
os.Remove(path)
|
||||
t.fs.Remove(path)
|
||||
} else {
|
||||
// Keep this file, and remember it so we don't unnecessarily try
|
||||
// to remove this directory.
|
||||
@@ -165,14 +160,14 @@ func (t *Trashcan) cleanoutArchive() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := filepath.Walk(versionsDir, walkFn); err != nil {
|
||||
if err := t.fs.Walk(versionsDir, walkFn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The last directory seen by the walkFn may not have been removed as it
|
||||
// should be.
|
||||
if currentDir != "" && filesInDir == 0 {
|
||||
os.Remove(currentDir)
|
||||
t.fs.Remove(currentDir)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user