-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmergefs.go
130 lines (105 loc) · 1.94 KB
/
mergefs.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
126
127
128
129
130
package mergefs
import (
"io/fs"
)
type MergeFS struct {
fss []fs.FS
}
func New(fss ...fs.FS) fs.FS {
return &MergeFS{fss: fss}
}
func (mfs *MergeFS) Open(name string) (fs.File, error) {
var f fs.File
var err error
for _, fsys := range mfs.fss {
f, err = fsys.Open(name)
if err == nil {
break
}
}
return f, err
}
func (mfs *MergeFS) Stat(name string) (fs.FileInfo, error) {
var last_err error
var newer_fi fs.FileInfo
all_err := true
for _, fsys := range mfs.fss {
fi, err := fs.Stat(fsys, name)
if err != nil {
last_err = err
continue
}
all_err = false
last_err = nil
if !fi.IsDir() {
newer_fi = fi
break
}
if newer_fi == nil || fi.ModTime().After(newer_fi.ModTime()) {
newer_fi = fi
}
}
if all_err {
return nil, last_err
}
return newer_fi, nil
}
func (mfs *MergeFS) ReadFile(name string) ([]byte, error) {
var buf []byte
var err error
for _, fsys := range mfs.fss {
buf, err = fs.ReadFile(fsys, name)
if err == nil {
break
}
}
return buf, err
}
func (mfs *MergeFS) ReadDir(name string) ([]fs.DirEntry, error) {
uniq := map[string]struct{}{}
all_dent := []fs.DirEntry{}
var err error
for _, fsys := range mfs.fss {
dent, e := fs.ReadDir(fsys, name)
if e != nil {
err = e
continue
}
err = nil
for _, ent := range dent {
n := ent.Name()
if _, ok := uniq[n]; ok {
continue
}
uniq[n] = struct{}{}
all_dent = append(all_dent, ent)
}
}
if err != nil {
return nil, err
}
return all_dent, nil
}
func (mfs *MergeFS) Glob(pattern string) ([]string, error) {
uniq := map[string]struct{}{}
var last_err error
all_err := true
for _, fsys := range mfs.fss {
lst, e := fs.Glob(fsys, pattern)
last_err = e
if e == nil {
all_err = false
}
for _, n := range lst {
uniq[n] = struct{}{}
}
}
if all_err {
return nil, last_err
}
list := make([]string, 0, len(uniq))
for k := range uniq {
list = append(list, k)
}
return list, nil
}