-
Notifications
You must be signed in to change notification settings - Fork 0
/
filesystem.go
217 lines (181 loc) · 7.66 KB
/
filesystem.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
package filesystem
import (
"context"
"io"
"io/fs"
)
const (
PermissionBits = fs.ModePerm
)
// Note: DirEntry's Type()/Info() usage should generally be avoided since
// type/info may not be fully populated. User should use Stat the actual file
// for accurate information.
type DirEntry = fs.DirEntry
type FileInfo = fs.FileInfo
// Note: In general, only the PermissionBits in FileMode can be specified as
// argument; the file system implementator should ignore the non-permission
// bits. FileInfo/DirEntry's Mode() may include non-permission bits.
type FileMode = fs.FileMode
type PathError = fs.PathError
type WalkDirFunc = fs.WalkDirFunc
// XXX: Maybe support Seek
//
// Note: Unlike FileSystem's ReadDir, FileReader's ReadDir is unsorted.
//
// Note: DirEntry's IsDir/Type/Info maybe not be fully populated by file system
// implementation. User must Stat the actual file for accurate information.
type FileReader = fs.ReadDirFile
// XXX: Maybe support Sync
type FileWriter = io.WriteCloser
// Standard options across all implementations. (The implementation may
// choose to ignore these options, but must expose the api anyway).
type Options interface {
SetContext(ctx context.Context)
// File and dir permissions need to be separate in order to support Copy.
SetFilePerm(perm FileMode)
SetDirPerm(perm FileMode)
// All other file system implementation specific options should be set via
// this method (Standardizing the option setting interface simplifies
// file system api forwarding/proxying). File system implementation should
// ignore unrelated options. SetOption should only return error when
// optionValue is invalid.
SetOption(fsImplName string, optionName string, optionValue string) error
}
// Note that the user may pass in options not associated to the file system's
// method implementation, in which case, the implementation should ignore the
// option.
type Option func(Options) error
// Applicable to all file system methods.
func WithContext(ctx context.Context) Option {
return func(options Options) error {
options.SetContext(ctx)
return nil
}
}
// Applicable to file creation operations (Create, Append, WriteFile, CopyFile,
// and CopyAll). File system implementation may place additional (umask)
// restriction on the given permission.
func WithFilePerm(perm FileMode) Option {
return func(options Options) error {
options.SetFilePerm(perm & PermissionBits)
return nil
}
}
// Applicable to directory creation operations (Mkdir, MkdirAll, and CopyAll).
// File system implementation may place additional (umask) restriction on the
// given permission.
func WithDirPerm(perm FileMode) Option {
return func(options Options) error {
options.SetDirPerm(perm & PermissionBits)
return nil
}
}
// Similar to fs.FS, but extended to support write operations. All methods
// should return error on empty path string inputs.
//
// Note: Windows-style backslash (and volume named) paths are not supported.
// User should use golang's "path" (instead of "path/filepath") for path
// manipulation, and use the file system's Abs method to resolve non-absolute
// paths.
//
// Note: This is the minimal set of operations that the file system
// implementor must provide (The implementation should return error for
// unsupported functionalities). If the file system implementation does not
// implement the full set of FileSystem operations, the implementator should
// use ExtendMinimalFileSystem() to provide implementation for the remaining
// operations.
type MinimalFileSystem interface {
// Equivalent to path/filepath.Abs. If the file system implementation
// does not support working directory, this should return error when the
// path is not absolute. This should always return error when filePath
// is an empty string.
Abs(filePath string) (string, error)
// This returns a FileReader that behaves as if it was opened with O_RDONLY.
Open(filePath string, options ...Option) (FileReader, error)
// This returns a FileWriter that behaves as if it was opened with
// O_CREATE | O_WRONLY | O_TRUNC. The default permission should be 0664 or
// tighter if the file system supports unix style permission.
//
// If a file perm option is provided, the file system implementation may
// place additional (umask) restriction on the provided permission.
//
// This returns an error if Create is not supported.
Create(filePath string, options ...Option) (FileWriter, error)
// This returns a FileWriter that behaves as if it was opened with
// O_CREATE |O_WRONLY | O_APPEND. The default permission should be 0664
// or tighter if the file system supports unix style permission.
//
// If a file perm option is provided, the file system implementation may
// place additional (umask) restriction on the provided permission.
//
// This returns an error if Append is not supported.
Append(filePath string, options ...Option) (FileWriter, error)
// This creates a directory. The default permission should be 0775 or
// tighter.
//
// If a dir perm option is provided, the file system implementation may
// place additional (umask) restriction on the provided permission.
//
// This returns an error if Mkdir is not supported.
Mkdir(dirPath string, options ...Option) error
// This renames a file.
//
// This returns an error if Mkdir is not supported.
// Note that Rename may not be an atomic operation (the implementation
// could for example copy then delete).
Rename(srcPath string, destPath string, options ...Option) error
// This remove a file or an empty directory.
//
// This returns an error if Remove is not supported.
Remove(filePath string, options ... Option) error
// Intended for changing permission bits. The file system implementor
// should ignore non-permission file mode bits.
Chmod(filePath string, perm FileMode, options ...Option) error
// Note: It doesn't make sense to support unix style Chown since uid/gid are
// unix / localhost specific. Local uid/gid are meaningless in windows /
// distributed file systems. Maybe support Chown by user/group name instead?
}
// FileSystem specify additional operations on top of MinimalFileSystem for
// ease of use.
//
// Note: all path input must be absolute (i.e., not relative to local working
// directory) since the working directory is meaningless to all but the local
// file system implementation rooted at '/'. File system implementator must
// guard against non-absolute paths.
type FileSystem interface {
MinimalFileSystem
// This returns the path's FileInfo.
Stat(filePath string, options ...Option) (FileInfo, error)
// This returns a directory's content, sorted by filename.
ReadDir(dirPath string, options ...Option) ([]DirEntry, error)
// This walks a directory.
WalkDir(dirPath string, fn WalkDirFunc, options ...Option) error
// This globs a file pattern.
Glob(pattern string, options ...Option) ([]string, error)
// This returns a file's content.
ReadFile(filePath string, options ...Option) ([]byte, error)
// This writes a file.
WriteFile(
filePath string,
data []byte,
options ...Option,
) error
// Copy the file at srcFilePath to destFilePath. If destFilePath is a file,
// the file content is overwritten. If destFilePath is a directory, this
// returns error.
CopyFile(
srcFilePath string,
destFilePath string,
options ...Option,
) error
// Recursively copy src to dest.
CopyAll(
srcPath string,
destPath string,
options ...Option,
) error
// This recursively creates the directory dirPath.
MkdirAll(dirPath string, options ...Option) error
// This removes all files under filePath.
RemoveAll(filePath string, options ...Option) error
}