Skip to content

Commit

Permalink
go 1.23 and added File.ListDirIter
Browse files Browse the repository at this point in the history
  • Loading branch information
ungerik committed Aug 29, 2024
1 parent 3ecb673 commit c252eb3
Show file tree
Hide file tree
Showing 16 changed files with 146 additions and 99 deletions.
4 changes: 2 additions & 2 deletions dropboxfs/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/ungerik/go-fs/dropboxfs

go 1.21
go 1.23

replace github.com/ungerik/go-fs => ..

Expand All @@ -13,5 +13,5 @@ require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/segmentio/go-env v1.1.0 // indirect
github.com/ungerik/go-dry v0.0.0-20231011182423-d9a07fd18c5f // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/sys v0.24.0 // indirect
)
14 changes: 4 additions & 10 deletions dropboxfs/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,13 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/segmentio/go-env v1.1.0 h1:AGJ7OnCx9M5NWpkYPGYELS6III/pFSnAs1GvKWStiEo=
github.com/segmentio/go-env v1.1.0/go.mod h1:pEKO2ieHe8zF098OMaAHw21SajMuONlnI/vJNB3pB7I=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tj/go-dropbox v0.0.0-20171107035848-42dd2be3662d h1:kc+jLVc4Ivy9I77bYXJ1f2ZTAPInUxw7W/bqKW43g6Q=
github.com/tj/go-dropbox v0.0.0-20171107035848-42dd2be3662d/go.mod h1:+zP9ykDCb5wHDCWHCuLZ2YhDAiy42yV+HAmI2BIocBI=
github.com/ungerik/go-dry v0.0.0-20230805093253-df9da4cd3437 h1:dQYWi16lkE/DZeZxJzyfQlgLzXJQ2cChrty8VZjmoIc=
github.com/ungerik/go-dry v0.0.0-20230805093253-df9da4cd3437/go.mod h1:g61b/Pvp64yQ4oYVbcdA7qqzn1RcQIHZQuhWOVG1VHk=
github.com/ungerik/go-dry v0.0.0-20231011182423-d9a07fd18c5f h1:E3yCdqCqIGLij7oti0hhLQGpABevY3ex+1UAPhDqMuc=
github.com/ungerik/go-dry v0.0.0-20231011182423-d9a07fd18c5f/go.mod h1:g61b/Pvp64yQ4oYVbcdA7qqzn1RcQIHZQuhWOVG1VHk=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func RemoveErrDoesNotExist(err error) error {
}

// ErrEmptyPath indications an empty file path
var ErrEmptyPath = NewErrDoesNotExist("")
var ErrEmptyPath = NewErrDoesNotExist(InvalidFile)

// ErrDoesNotExist is returned when a file does not exist
// and wraps os.ErrNotExist.
Expand Down
40 changes: 38 additions & 2 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"fmt"
"io"
iofs "io/fs"
"iter"
"strings"
"time"

Expand Down Expand Up @@ -436,16 +437,18 @@ func (file File) SetPermissions(perm Permissions) error {
return NewErrUnsupported(fileSystem, "SetPermissions")
}

// ListDir calls the passed callback function for every file and directory in dirPath.
// ListDir calls the passed callback function for every file and directory.
// If any patterns are passed, then only files with a name that matches
// at least one of the patterns are returned.
func (file File) ListDir(callback func(File) error, patterns ...string) error {
return file.ListDirContext(context.Background(), callback, patterns...)
}

// ListDirContext calls the passed callback function for every file and directory in dirPath.
// ListDirContext calls the passed callback function for every file and directory in the directory.
// If any patterns are passed, then only files with a name that matches
// at least one of the patterns are returned.
// Canceling the context or returning an error from the callback
// will stop the listing and return the context or callback error.
func (file File) ListDirContext(ctx context.Context, callback func(File) error, patterns ...string) error {
if file == "" {
return ErrEmptyPath
Expand All @@ -454,6 +457,39 @@ func (file File) ListDirContext(ctx context.Context, callback func(File) error,
return fileSystem.ListDirInfo(ctx, path, FileInfoToFileCallback(callback), patterns)
}

// ListDirIter returns an iterator that yields every file and directory in the directory.
// If any patterns are passed, then only files with a name that matches
// at least one of the patterns are returned.
// In case of an error, the iterator will yield InvalidFile and the error
// as last key and value and then stop the iteration.
func (file File) ListDirIter(patterns ...string) iter.Seq2[File, error] {
return file.ListDirIterContext(context.Background(), patterns...)
}

// ListDirIterContext returns an iterator that yields every file and directory in the directory.
// If any patterns are passed, then only files with a name that matches
// at least one of the patterns are returned.
// In case of an error, the iterator will yield InvalidFile and the error
// as last key and value and then stop the iteration.
// Canceling the context will stop the iteration and yield the context error.
func (file File) ListDirIterContext(ctx context.Context, patterns ...string) iter.Seq2[File, error] {
return func(yield func(File, error) bool) {
const cancel SentinelError = "cancel"
err := file.ListDirContext(ctx,
func(listedFile File) error {
if !yield(listedFile, nil) {
return cancel
}
return nil
},
patterns...,
)
if err != nil && !errors.Is(err, cancel) {
yield(InvalidFile, err)
}
}
}

// ListDirInfo calls the passed callback function for every file and directory in dirPath.
// If any patterns are passed, then only files with a name that matches
// at least one of the patterns are returned.
Expand Down
91 changes: 72 additions & 19 deletions file_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fs

import (
"context"
"errors"
"fmt"
"path/filepath"
Expand Down Expand Up @@ -203,27 +202,81 @@ func TestFile_Watch(t *testing.T) {
assert.NoError(t, err, "cancel watch")
}

func TestFile_ListDirInfoRecursiveContext(t *testing.T) {
type args struct {
ctx context.Context
callback func(*FileInfo) error
patterns []string
// func TestFile_ListDirInfoRecursiveContext(t *testing.T) {
// type args struct {
// ctx context.Context
// callback func(*FileInfo) error
// patterns []string
// }
// tests := []struct {
// name string
// file File
// args args
// wantErr bool
// }{
// // TODO: Add test cases.
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// if err := tt.file.ListDirInfoRecursiveContext(tt.args.ctx, tt.args.callback, tt.args.patterns...); (err != nil) != tt.wantErr {
// t.Errorf("File.ListDirInfoRecursiveContext() error = %v, wantErr %v", err, tt.wantErr)
// }
// })
// }
// }

func TestFile_ListDir(t *testing.T) {
dir, err := MakeTempDir()
require.NoError(t, err, "MakeTempDir")
t.Cleanup(func() { dir.RemoveRecursive() })

files := map[File]bool{
dir.Join("a"): true,
dir.Join("b"): true,
dir.Join("c"): true,
}
tests := []struct {
name string
file File
args args
wantErr bool
}{
// TODO: Add test cases.

for file := range files {
err := file.Touch()
require.NoError(t, err)
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.file.ListDirInfoRecursiveContext(tt.args.ctx, tt.args.callback, tt.args.patterns...); (err != nil) != tt.wantErr {
t.Errorf("File.ListDirInfoRecursiveContext() error = %v, wantErr %v", err, tt.wantErr)
}
})

err = dir.ListDir(func(file File) error {
if !files[file] {
t.Errorf("unexpected file: %s", file)
}
delete(files, file)
return nil
})
require.NoError(t, err)
require.Empty(t, files, "not all files listed")
}

func TestFile_ListDirIter(t *testing.T) {
dir, err := MakeTempDir()
require.NoError(t, err, "MakeTempDir")
t.Cleanup(func() { dir.RemoveRecursive() })

files := map[File]bool{
dir.Join("a"): true,
dir.Join("b"): true,
dir.Join("c"): true,
}

for file := range files {
err := file.Touch()
require.NoError(t, err)
}

for file, err := range dir.ListDirIter() {
require.NoError(t, err, "ListDirIter should not return an error")
if !files[file] {
t.Errorf("unexpected file: %s", file)
}
delete(files, file)
}
require.NoError(t, err)
require.Empty(t, files, "not all files listed")
}

func TestFile_String(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ type FileSystem interface {
// ListDirInfo calls the passed callback function for every file and directory in dirPath.
// If any patterns are passed, then only files or directores with a name that matches
// at least one of the patterns are returned.
// Canceling the context or returning an error from the callback
// will stop the listing and return the context or callback error.
ListDirInfo(ctx context.Context, dirPath string, callback func(*FileInfo) error, patterns []string) error

MakeDir(dirPath string, perm []Permissions) error
Expand Down
4 changes: 2 additions & 2 deletions ftpfs/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/ungerik/go-fs/ftpfs

go 1.21
go 1.23

replace github.com/ungerik/go-fs => ..

Expand All @@ -17,6 +17,6 @@ require (
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/sys v0.24.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
6 changes: 2 additions & 4 deletions ftpfs/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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=
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/ungerik/go-fs

go 1.21
go 1.23

require (
github.com/fsnotify/fsnotify v1.7.0
Expand All @@ -10,6 +10,6 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/sys v0.24.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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=
Expand Down
2 changes: 1 addition & 1 deletion go.work
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
go 1.21.0
go 1.23

use (
.
Expand Down
4 changes: 4 additions & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
6 changes: 3 additions & 3 deletions s3fs/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/ungerik/go-fs/s3fs

go 1.21
go 1.23

replace github.com/ungerik/go-fs => ..

Expand All @@ -26,7 +26,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/sso v1.20.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 // indirect
github.com/aws/smithy-go v1.20.2 // indirect
github.com/aws/smithy-go v1.20.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/sys v0.24.0 // indirect
)
Loading

0 comments on commit c252eb3

Please sign in to comment.