1package filesystem
2
3import (
4 "context"
5 "os"
6 "path/filepath"
7
8 "github.com/bnema/dumber/internal/application/port"
9)
10
11// Adapter implements port.FileSystem using the OS filesystem.
12type Adapter struct{}
13
14// New creates a new filesystem adapter.
15func New() *Adapter {
16 return &Adapter{}
17}
18
19func (a *Adapter) Exists(_ context.Context, path string) (bool, error) {
20 _, err := os.Stat(path)
21 if err == nil {
22 return true, nil
23 }
24 if os.IsNotExist(err) {
25 return false, nil
26 }
27 return false, err
28}
29
30func (a *Adapter) IsDirectory(_ context.Context, path string) (bool, error) {
31 info, err := os.Stat(path)
32 if err != nil {
33 return false, err
34 }
35 return info.IsDir(), nil
36}
37
38func (a *Adapter) GetSize(_ context.Context, path string) (int64, error) {
39 info, err := os.Stat(path)
40 if err != nil {
41 if os.IsNotExist(err) {
42 return 0, nil
43 }
44 return 0, err
45 }
46 if !info.IsDir() {
47 return info.Size(), nil
48 }
49
50 var size int64
51 err = filepath.Walk(path, func(_ string, fi os.FileInfo, walkErr error) error {
52 if walkErr != nil {
53 return walkErr
54 }
55 if !fi.IsDir() {
56 size += fi.Size()
57 }
58 return nil
59 })
60 if err != nil {
61 return 0, err
62 }
63 return size, nil
64}
65
66func (a *Adapter) RemoveAll(_ context.Context, path string) error {
67 return os.RemoveAll(path)
68}
69
70// ResolveExistingPath expands supported user path syntax, absolutizes the path,
71// and reports whether it exists in the OS filesystem.
72func (a *Adapter) ResolveExistingPath(_ context.Context, input string) (string, bool, error) {
73 if input == "" {
74 return "", false, nil
75 }
76 path := input
77 if len(path) >= 2 && path[0:2] == "~/" {
78 home, err := os.UserHomeDir()
79 if err != nil {
80 return "", false, err
81 }
82 path = filepath.Join(home, path[2:])
83 }
84 absPath, err := filepath.Abs(path)
85 if err != nil {
86 return "", false, err
87 }
88 if _, err := os.Stat(absPath); err != nil {
89 if os.IsNotExist(err) {
90 return "", false, nil
91 }
92 return "", false, err
93 }
94 return absPath, true, nil
95}
96
97var _ port.FileSystem = (*Adapter)(nil)
98var _ port.LocalPathResolver = (*Adapter)(nil)