Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/vendor/github.com/spf13/afero/iofs.go
2875 views
1
//go:build go1.16
2
// +build go1.16
3
4
package afero
5
6
import (
7
"io"
8
"io/fs"
9
"os"
10
"path"
11
"sort"
12
"time"
13
14
"github.com/spf13/afero/internal/common"
15
)
16
17
// IOFS adopts afero.Fs to stdlib io/fs.FS
18
type IOFS struct {
19
Fs
20
}
21
22
func NewIOFS(fs Fs) IOFS {
23
return IOFS{Fs: fs}
24
}
25
26
var (
27
_ fs.FS = IOFS{}
28
_ fs.GlobFS = IOFS{}
29
_ fs.ReadDirFS = IOFS{}
30
_ fs.ReadFileFS = IOFS{}
31
_ fs.StatFS = IOFS{}
32
_ fs.SubFS = IOFS{}
33
)
34
35
func (iofs IOFS) Open(name string) (fs.File, error) {
36
const op = "open"
37
38
// by convention for fs.FS implementations we should perform this check
39
if !fs.ValidPath(name) {
40
return nil, iofs.wrapError(op, name, fs.ErrInvalid)
41
}
42
43
file, err := iofs.Fs.Open(name)
44
if err != nil {
45
return nil, iofs.wrapError(op, name, err)
46
}
47
48
// file should implement fs.ReadDirFile
49
if _, ok := file.(fs.ReadDirFile); !ok {
50
file = readDirFile{file}
51
}
52
53
return file, nil
54
}
55
56
func (iofs IOFS) Glob(pattern string) ([]string, error) {
57
const op = "glob"
58
59
// afero.Glob does not perform this check but it's required for implementations
60
if _, err := path.Match(pattern, ""); err != nil {
61
return nil, iofs.wrapError(op, pattern, err)
62
}
63
64
items, err := Glob(iofs.Fs, pattern)
65
if err != nil {
66
return nil, iofs.wrapError(op, pattern, err)
67
}
68
69
return items, nil
70
}
71
72
func (iofs IOFS) ReadDir(name string) ([]fs.DirEntry, error) {
73
f, err := iofs.Fs.Open(name)
74
if err != nil {
75
return nil, iofs.wrapError("readdir", name, err)
76
}
77
78
defer f.Close()
79
80
if rdf, ok := f.(fs.ReadDirFile); ok {
81
items, err := rdf.ReadDir(-1)
82
if err != nil {
83
return nil, iofs.wrapError("readdir", name, err)
84
}
85
sort.Slice(items, func(i, j int) bool { return items[i].Name() < items[j].Name() })
86
return items, nil
87
}
88
89
items, err := f.Readdir(-1)
90
if err != nil {
91
return nil, iofs.wrapError("readdir", name, err)
92
}
93
sort.Sort(byName(items))
94
95
ret := make([]fs.DirEntry, len(items))
96
for i := range items {
97
ret[i] = common.FileInfoDirEntry{FileInfo: items[i]}
98
}
99
100
return ret, nil
101
}
102
103
func (iofs IOFS) ReadFile(name string) ([]byte, error) {
104
const op = "readfile"
105
106
if !fs.ValidPath(name) {
107
return nil, iofs.wrapError(op, name, fs.ErrInvalid)
108
}
109
110
bytes, err := ReadFile(iofs.Fs, name)
111
if err != nil {
112
return nil, iofs.wrapError(op, name, err)
113
}
114
115
return bytes, nil
116
}
117
118
func (iofs IOFS) Sub(dir string) (fs.FS, error) { return IOFS{NewBasePathFs(iofs.Fs, dir)}, nil }
119
120
func (IOFS) wrapError(op, path string, err error) error {
121
if _, ok := err.(*fs.PathError); ok {
122
return err // don't need to wrap again
123
}
124
125
return &fs.PathError{
126
Op: op,
127
Path: path,
128
Err: err,
129
}
130
}
131
132
// readDirFile provides adapter from afero.File to fs.ReadDirFile needed for correct Open
133
type readDirFile struct {
134
File
135
}
136
137
var _ fs.ReadDirFile = readDirFile{}
138
139
func (r readDirFile) ReadDir(n int) ([]fs.DirEntry, error) {
140
items, err := r.Readdir(n)
141
if err != nil {
142
return nil, err
143
}
144
145
ret := make([]fs.DirEntry, len(items))
146
for i := range items {
147
ret[i] = common.FileInfoDirEntry{FileInfo: items[i]}
148
}
149
150
return ret, nil
151
}
152
153
// FromIOFS adopts io/fs.FS to use it as afero.Fs
154
// Note that io/fs.FS is read-only so all mutating methods will return fs.PathError with fs.ErrPermission
155
// To store modifications you may use afero.CopyOnWriteFs
156
type FromIOFS struct {
157
fs.FS
158
}
159
160
var _ Fs = FromIOFS{}
161
162
func (f FromIOFS) Create(name string) (File, error) { return nil, notImplemented("create", name) }
163
164
func (f FromIOFS) Mkdir(
165
name string,
166
perm os.FileMode,
167
) error {
168
return notImplemented("mkdir", name)
169
}
170
171
func (f FromIOFS) MkdirAll(path string, perm os.FileMode) error {
172
return notImplemented("mkdirall", path)
173
}
174
175
func (f FromIOFS) Open(name string) (File, error) {
176
file, err := f.FS.Open(name)
177
if err != nil {
178
return nil, err
179
}
180
181
return fromIOFSFile{File: file, name: name}, nil
182
}
183
184
func (f FromIOFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) {
185
return f.Open(name)
186
}
187
188
func (f FromIOFS) Remove(name string) error {
189
return notImplemented("remove", name)
190
}
191
192
func (f FromIOFS) RemoveAll(path string) error {
193
return notImplemented("removeall", path)
194
}
195
196
func (f FromIOFS) Rename(oldname, newname string) error {
197
return notImplemented("rename", oldname)
198
}
199
200
func (f FromIOFS) Stat(name string) (os.FileInfo, error) { return fs.Stat(f.FS, name) }
201
202
func (f FromIOFS) Name() string { return "fromiofs" }
203
204
func (f FromIOFS) Chmod(name string, mode os.FileMode) error {
205
return notImplemented("chmod", name)
206
}
207
208
func (f FromIOFS) Chown(name string, uid, gid int) error {
209
return notImplemented("chown", name)
210
}
211
212
func (f FromIOFS) Chtimes(name string, atime time.Time, mtime time.Time) error {
213
return notImplemented("chtimes", name)
214
}
215
216
type fromIOFSFile struct {
217
fs.File
218
name string
219
}
220
221
func (f fromIOFSFile) ReadAt(p []byte, off int64) (n int, err error) {
222
readerAt, ok := f.File.(io.ReaderAt)
223
if !ok {
224
return -1, notImplemented("readat", f.name)
225
}
226
227
return readerAt.ReadAt(p, off)
228
}
229
230
func (f fromIOFSFile) Seek(offset int64, whence int) (int64, error) {
231
seeker, ok := f.File.(io.Seeker)
232
if !ok {
233
return -1, notImplemented("seek", f.name)
234
}
235
236
return seeker.Seek(offset, whence)
237
}
238
239
func (f fromIOFSFile) Write(p []byte) (n int, err error) {
240
return -1, notImplemented("write", f.name)
241
}
242
243
func (f fromIOFSFile) WriteAt(p []byte, off int64) (n int, err error) {
244
return -1, notImplemented("writeat", f.name)
245
}
246
247
func (f fromIOFSFile) Name() string { return f.name }
248
249
func (f fromIOFSFile) Readdir(count int) ([]os.FileInfo, error) {
250
rdfile, ok := f.File.(fs.ReadDirFile)
251
if !ok {
252
return nil, notImplemented("readdir", f.name)
253
}
254
255
entries, err := rdfile.ReadDir(count)
256
if err != nil {
257
return nil, err
258
}
259
260
ret := make([]os.FileInfo, len(entries))
261
for i := range entries {
262
ret[i], err = entries[i].Info()
263
if err != nil {
264
return nil, err
265
}
266
}
267
268
return ret, nil
269
}
270
271
func (f fromIOFSFile) Readdirnames(n int) ([]string, error) {
272
rdfile, ok := f.File.(fs.ReadDirFile)
273
if !ok {
274
return nil, notImplemented("readdir", f.name)
275
}
276
277
entries, err := rdfile.ReadDir(n)
278
if err != nil {
279
return nil, err
280
}
281
282
ret := make([]string, len(entries))
283
for i := range entries {
284
ret[i] = entries[i].Name()
285
}
286
287
return ret, nil
288
}
289
290
func (f fromIOFSFile) Sync() error { return nil }
291
292
func (f fromIOFSFile) Truncate(size int64) error {
293
return notImplemented("truncate", f.name)
294
}
295
296
func (f fromIOFSFile) WriteString(s string) (ret int, err error) {
297
return -1, notImplemented("writestring", f.name)
298
}
299
300
func notImplemented(op, path string) error {
301
return &fs.PathError{Op: op, Path: path, Err: fs.ErrPermission}
302
}
303
304