-
Notifications
You must be signed in to change notification settings - Fork 0
/
basefiledecoratorfs.go
125 lines (99 loc) · 2.34 KB
/
basefiledecoratorfs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package valueobject
import (
"fmt"
"github.com/spf13/afero"
"os"
"path/filepath"
iofs "io/fs"
)
func decorateDirs(fs afero.Fs, meta *FileMeta) afero.Fs {
ffs := &BaseFileDecoratorFs{Fs: fs}
decorator := func(fi FileNameIsDir, name string) (FileNameIsDir, error) {
if !fi.IsDir() {
// Leave regular files as they are.
return fi, nil
}
return DecorateFileInfo(fi, nil, "", meta), nil
}
ffs.Decorate = decorator
return ffs
}
type BaseFileDecoratorFs struct {
afero.Fs
Decorate func(fi FileNameIsDir, name string) (FileNameIsDir, error)
}
func (fs *BaseFileDecoratorFs) UnwrapFilesystem() afero.Fs {
return fs.Fs
}
func (fs *BaseFileDecoratorFs) Stat(name string) (os.FileInfo, error) {
fi, err := fs.Fs.Stat(name)
if err != nil {
return nil, err
}
fim, err := fs.Decorate(fi, name)
if err != nil {
return nil, err
}
return fim.(os.FileInfo), nil
}
func (fs *BaseFileDecoratorFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
var (
fi os.FileInfo
err error
ok bool
)
if lstater, isLstater := fs.Fs.(afero.Lstater); isLstater {
fi, ok, err = lstater.LstatIfPossible(name)
} else {
fi, err = fs.Fs.Stat(name)
}
if err != nil {
return nil, false, err
}
fim, err := fs.Decorate(fi, name)
if err != nil {
return nil, false, err
}
return fim.(os.FileInfo), ok, err
}
func (fs *BaseFileDecoratorFs) Open(name string) (afero.File, error) {
f, err := fs.Fs.Open(name)
if err != nil {
return nil, err
}
return &baseFileDecoratorFile{File: f, fs: fs}, nil
}
type baseFileDecoratorFile struct {
afero.File
fs *BaseFileDecoratorFs
}
func (l *baseFileDecoratorFile) ReadDir(n int) ([]iofs.DirEntry, error) {
fis, err := l.File.(iofs.ReadDirFile).ReadDir(-1)
if err != nil {
return nil, err
}
fisp := make([]iofs.DirEntry, len(fis))
for i, fi := range fis {
filename := fi.Name()
if l.Name() != "" {
filename = filepath.Join(l.Name(), fi.Name())
}
fid, err := l.fs.Decorate(fi, filename)
if err != nil {
return nil, fmt.Errorf("decorate: %w", err)
}
fisp[i] = fid.(iofs.DirEntry)
}
return fisp, err
}
func (l *baseFileDecoratorFile) Readdir(c int) (ofi []os.FileInfo, err error) {
dirEntry, err := l.ReadDir(c)
if err != nil {
return nil, err
}
var result []os.FileInfo
for _, d := range dirEntry {
result = append(result, d.(os.FileInfo))
}
return result, nil
}