1
0
mirror of https://github.com/pocketbase/pocketbase.git synced 2025-01-10 00:43:36 +02:00
pocketbase/tools/osutils/dir.go

81 lines
1.8 KiB
Go
Raw Normal View History

package osutils
import (
"log"
"os"
"path/filepath"
"github.com/pocketbase/pocketbase/tools/list"
)
// MoveDirContent moves the src dir content, that is not listed in the exclide list,
// to dest dir (it will be created if missing).
//
// The rootExclude argument is used to specify a list of src root entries to exclude.
//
// Note that this method doesn't delete the old src dir.
//
// It is an alternative to os.Rename() for the cases where we can't
// rename/delete the src dir (see https://github.com/pocketbase/pocketbase/issues/2519).
func MoveDirContent(src string, dest string, rootExclude ...string) error {
entries, err := os.ReadDir(src)
if err != nil {
return err
}
// make sure that the dest dir exist
manuallyCreatedDestDir := false
if _, err := os.Stat(dest); err != nil {
if err := os.Mkdir(dest, os.ModePerm); err != nil {
return err
}
manuallyCreatedDestDir = true
}
moved := map[string]string{}
2023-07-30 12:40:22 +02:00
tryRollback := func() []error {
errs := []error{}
for old, new := range moved {
2023-07-30 12:40:22 +02:00
if err := os.Rename(new, old); err != nil {
errs = append(errs, err)
}
}
// try to delete manually the created dest dir if all moved files were restored
if manuallyCreatedDestDir && len(errs) == 0 {
if err := os.Remove(dest); err != nil {
errs = append(errs, err)
}
}
return errs
}
for _, entry := range entries {
basename := entry.Name()
if list.ExistInSlice(basename, rootExclude) {
continue
}
old := filepath.Join(src, basename)
new := filepath.Join(dest, basename)
if err := os.Rename(old, new); err != nil {
2023-07-30 12:40:22 +02:00
if errs := tryRollback(); len(errs) > 0 {
// currently just log the rollback errors
// in the future we may require go 1.20+ to use errors.Join()
log.Println(errs)
}
return err
}
moved[old] = new
}
return nil
}