-
Notifications
You must be signed in to change notification settings - Fork 6
feat(filesystem): add filesystem modules for go-fries #915
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ab127de
2de1ba9
ae9f17b
516f5bf
9f1f281
4778b1a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,6 @@ linters: | |
- mnd | ||
- gocyclo | ||
- ineffassign | ||
- lll | ||
- prealloc | ||
- revive | ||
- staticcheck | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,112 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
package filesystem | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||
"context" | ||||||||||||||||||||||||||||||||||||||||||||||||||
"errors" | ||||||||||||||||||||||||||||||||||||||||||||||||||
"time" | ||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
var ErrNotSupported = errors.New("[storage] not supported") | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
type Filesystem interface { | ||||||||||||||||||||||||||||||||||||||||||||||||||
// Read the value at the given path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Read(ctx context.Context, path string) ([]byte, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Write the value at the given path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Write(ctx context.Context, path string, value []byte) error | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Delete the value at the given path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Delete(ctx context.Context, path string) error | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Exists checks if the path exists. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Exists(ctx context.Context, path string) (bool, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Rename renames the value from the old path to the new path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Rename(ctx context.Context, oldPath, newPath string) error | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Link creates a hard link from the old path to the new path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Link(ctx context.Context, oldPath, newPath string) error | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Symlink creates a symbolic link from the old path to the new path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Symlink(ctx context.Context, oldPath, newPath string) error | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Files lists the files in the given path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Files(ctx context.Context, path string) ([]string, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// AllFiles lists all the files in the given path.(including subdirectories) | ||||||||||||||||||||||||||||||||||||||||||||||||||
AllFiles(ctx context.Context, path string) ([]string, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Directories lists the directories in the given path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Directories(ctx context.Context, path string) ([]string, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// AllDirectories lists all the directories in the given path.(including subdirectories) | ||||||||||||||||||||||||||||||||||||||||||||||||||
AllDirectories(ctx context.Context, path string) ([]string, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// MakeDirectory creates a directory at the given path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
MakeDirectory(ctx context.Context, path string) error | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// DeleteDirectory deletes the directory at the given path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
DeleteDirectory(ctx context.Context, path string) error | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// IsFile checks if the path is a file. | ||||||||||||||||||||||||||||||||||||||||||||||||||
IsFile(ctx context.Context, path string) (bool, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// IsDir checks if the path is a directory. | ||||||||||||||||||||||||||||||||||||||||||||||||||
IsDir(ctx context.Context, path string) (bool, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Size returns the size of the file in bytes. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Size(ctx context.Context, path string) (int64, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// LastModified returns the last modified time of the file. | ||||||||||||||||||||||||||||||||||||||||||||||||||
LastModified(ctx context.Context, path string) (*time.Time, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Path returns the full path for the given path. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Path(ctx context.Context, path string) string | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Name returns the name of the file, without the extension. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Name(ctx context.Context, path string) string | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Basename returns the base name of the file, with the extension. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Basename(ctx context.Context, path string) string | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Dirname returns the directory name of the file. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Dirname(ctx context.Context, path string) string | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
// Extension returns the extension of the file. | ||||||||||||||||||||||||||||||||||||||||||||||||||
Extension(ctx context.Context, path string) string | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
type Copyable interface { | ||||||||||||||||||||||||||||||||||||||||||||||||||
Copy(ctx context.Context, oldPath, newPath string) error | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
type NoopFilesystem struct{} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
var ( | ||||||||||||||||||||||||||||||||||||||||||||||||||
_ Filesystem = (*NoopFilesystem)(nil) | ||||||||||||||||||||||||||||||||||||||||||||||||||
_ Copyable = (*NoopFilesystem)(nil) | ||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Read(context.Context, string) ([]byte, error) { return nil, nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Write(context.Context, string, []byte) error { return nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Delete(context.Context, string) error { return nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Exists(context.Context, string) (bool, error) { return true, nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Rename(context.Context, string, string) error { return nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Link(context.Context, string, string) error { return nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Symlink(context.Context, string, string) error { return nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Files(context.Context, string) ([]string, error) { return nil, nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) AllFiles(context.Context, string) ([]string, error) { return nil, nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Directories(context.Context, string) ([]string, error) { return nil, nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) AllDirectories(context.Context, string) ([]string, error) { return nil, nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) MakeDirectory(context.Context, string) error { return nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) DeleteDirectory(context.Context, string) error { return nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) IsFile(context.Context, string) (bool, error) { return false, nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) IsDir(context.Context, string) (bool, error) { return false, nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+93
to
+104
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Ensure logical consistency in NoopFilesystem boolean methods The implementation has a logical inconsistency: Exists() returns true (line 93) while IsFile() and IsDir() both return false (lines 103-104). In most filesystems, if a path exists, it should be either a file or directory. For a no-op implementation, consider making these logically consistent: -func (NoopFilesystem) Exists(context.Context, string) (bool, error) { return true, nil }
+func (NoopFilesystem) Exists(context.Context, string) (bool, error) { return false, nil } Or alternatively: -func (NoopFilesystem) IsFile(context.Context, string) (bool, error) { return false, nil }
+func (NoopFilesystem) IsFile(context.Context, string) (bool, error) { return true, nil } 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Size(context.Context, string) (int64, error) { return 0, nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) LastModified(context.Context, string) (*time.Time, error) { return nil, nil } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Path(context.Context, string) string { return "" } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Name(context.Context, string) string { return "" } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Basename(context.Context, string) string { return "" } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Dirname(context.Context, string) string { return "" } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Extension(context.Context, string) string { return "" } | ||||||||||||||||||||||||||||||||||||||||||||||||||
func (NoopFilesystem) Copy(context.Context, string, string) error { return nil } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package filesystem | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestStorage(t *testing.T) { | ||
var ( | ||
noop = NoopFilesystem{} | ||
ctx = context.Background() | ||
) | ||
|
||
_, err := noop.Read(ctx, "test") | ||
assert.NoError(t, err) | ||
|
||
assert.NoError(t, noop.Write(ctx, "noop", []byte("noop"))) | ||
assert.NoError(t, noop.Delete(ctx, "noop")) | ||
|
||
has, err := noop.Exists(ctx, "noop") | ||
assert.NoError(t, err) | ||
assert.True(t, has) | ||
|
||
assert.NoError(t, noop.Rename(ctx, "noop", "noop")) | ||
assert.NoError(t, noop.Link(ctx, "noop", "noop")) | ||
assert.NoError(t, noop.Symlink(ctx, "noop", "noop")) | ||
|
||
files, err := noop.Files(ctx, "noop") | ||
assert.NoError(t, err) | ||
assert.Len(t, files, 0) | ||
|
||
allFiles, err := noop.AllFiles(ctx, "noop") | ||
assert.NoError(t, err) | ||
assert.Len(t, allFiles, 0) | ||
|
||
directories, err := noop.Directories(ctx, "noop") | ||
assert.NoError(t, err) | ||
assert.Len(t, directories, 0) | ||
|
||
allDirectories, err := noop.AllDirectories(ctx, "noop") | ||
assert.NoError(t, err) | ||
assert.Len(t, allDirectories, 0) | ||
|
||
isFile, err := noop.IsFile(ctx, "noop") | ||
assert.NoError(t, err) | ||
assert.False(t, isFile) | ||
|
||
isDir, err := noop.IsDir(ctx, "noop") | ||
assert.NoError(t, err) | ||
assert.False(t, isDir) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module github.com/go-fries/fries/filesystem/v3 | ||
|
||
go 1.23.0 | ||
|
||
require github.com/stretchr/testify v1.10.0 | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= | ||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Missing error handling signatures in interface methods
Several interface methods should include error return values for failed operations, but some path-related methods (like Path, Name, Basename, Dirname, Extension) don't return errors even though they could fail in real implementations.
Consider adding error return values to these methods for consistency and to allow implementations to properly handle errors.