subsyt/internal/fsops/fsops.go
Viktor Varland 09134c46c4
Some checks are pending
build / build (push) Waiting to run
refactor: split logic into distinct parts
2025-10-01 21:21:59 +02:00

134 lines
2.4 KiB
Go

package fsops
import (
"errors"
"fmt"
"log"
"os"
"path/filepath"
)
type Manager struct {
DryRun bool
}
func (m Manager) EnsureDir(path string) error {
if path == "" {
return fmt.Errorf("ensure dir: empty path")
}
if m.DryRun {
log.Printf("[dry-run] ensure dir %s\n", path)
return nil
}
if err := os.MkdirAll(path, 0o755); err != nil {
return fmt.Errorf("ensure dir %s: %w", path, err)
}
return nil
}
func (m Manager) Move(src, dst string) error {
if src == "" || dst == "" {
return fmt.Errorf("move: empty source or destination")
}
dstDir := filepath.Dir(dst)
if err := m.EnsureDir(dstDir); err != nil {
return err
}
if m.DryRun {
log.Printf("[dry-run] move %s -> %s\n", src, dst)
return nil
}
if err := os.Rename(src, dst); err != nil {
return fmt.Errorf("move %s -> %s: %w", src, dst, err)
}
return nil
}
func (m Manager) Remove(path string) error {
if path == "" {
return fmt.Errorf("remove: empty path")
}
if m.DryRun {
log.Printf("[dry-run] remove %s\n", path)
return nil
}
if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("remove %s: %w", path, err)
}
return nil
}
func (m Manager) RemoveAll(path string) error {
if path == "" {
return fmt.Errorf("remove all: empty path")
}
if m.DryRun {
log.Printf("[dry-run] remove tree %s\n", path)
return nil
}
if err := os.RemoveAll(path); err != nil {
return fmt.Errorf("remove all %s: %w", path, err)
}
return nil
}
func (m Manager) RemoveEmptyDirs(root string) error {
if root == "" {
return fmt.Errorf("remove empty dirs: empty root")
}
if _, err := os.Stat(root); errors.Is(err, os.ErrNotExist) {
return nil
} else if err != nil {
return err
}
return filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error {
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil
}
return err
}
if path == root {
return nil
}
if !d.IsDir() {
return nil
}
entries, readErr := os.ReadDir(path)
if readErr != nil {
if errors.Is(readErr, os.ErrNotExist) {
return nil
}
return readErr
}
if len(entries) > 0 {
return nil
}
if m.DryRun {
log.Printf("[dry-run] remove empty dir %s\n", path)
return nil
}
if rmErr := os.Remove(path); rmErr != nil && !os.IsNotExist(rmErr) {
return fmt.Errorf("remove empty dir %s: %w", path, rmErr)
}
return nil
})
}