mirror of https://github.com/rclone/rclone.git
local: obey file filters in listing to fix errors on excluded files
Fixes #6376
This commit is contained in:
parent
2c5923ab1a
commit
8d1fff9a82
|
@ -22,6 +22,7 @@ import (
|
||||||
"github.com/rclone/rclone/fs/config"
|
"github.com/rclone/rclone/fs/config"
|
||||||
"github.com/rclone/rclone/fs/config/configmap"
|
"github.com/rclone/rclone/fs/config/configmap"
|
||||||
"github.com/rclone/rclone/fs/config/configstruct"
|
"github.com/rclone/rclone/fs/config/configstruct"
|
||||||
|
"github.com/rclone/rclone/fs/filter"
|
||||||
"github.com/rclone/rclone/fs/fserrors"
|
"github.com/rclone/rclone/fs/fserrors"
|
||||||
"github.com/rclone/rclone/fs/hash"
|
"github.com/rclone/rclone/fs/hash"
|
||||||
"github.com/rclone/rclone/lib/encoder"
|
"github.com/rclone/rclone/lib/encoder"
|
||||||
|
@ -443,6 +444,8 @@ func (f *Fs) NewObject(ctx context.Context, remote string) (fs.Object, error) {
|
||||||
// This should return ErrDirNotFound if the directory isn't
|
// This should return ErrDirNotFound if the directory isn't
|
||||||
// found.
|
// found.
|
||||||
func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) {
|
func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) {
|
||||||
|
filter, useFilter := filter.GetConfig(ctx), filter.GetUseFilter(ctx)
|
||||||
|
|
||||||
fsDirPath := f.localPath(dir)
|
fsDirPath := f.localPath(dir)
|
||||||
_, err = os.Stat(fsDirPath)
|
_, err = os.Stat(fsDirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -493,6 +496,13 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if fierr != nil {
|
if fierr != nil {
|
||||||
|
// Don't report errors on any file names that are excluded
|
||||||
|
if useFilter {
|
||||||
|
newRemote := f.cleanRemote(dir, name)
|
||||||
|
if !filter.IncludeRemote(newRemote) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
err = fmt.Errorf("failed to read directory %q: %w", namepath, err)
|
err = fmt.Errorf("failed to read directory %q: %w", namepath, err)
|
||||||
fs.Errorf(dir, "%v", fierr)
|
fs.Errorf(dir, "%v", fierr)
|
||||||
_ = accounting.Stats(ctx).Error(fserrors.NoRetryError(fierr)) // fail the sync
|
_ = accounting.Stats(ctx).Error(fserrors.NoRetryError(fierr)) // fail the sync
|
||||||
|
@ -510,6 +520,11 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e
|
||||||
name := fi.Name()
|
name := fi.Name()
|
||||||
mode := fi.Mode()
|
mode := fi.Mode()
|
||||||
newRemote := f.cleanRemote(dir, name)
|
newRemote := f.cleanRemote(dir, name)
|
||||||
|
// Don't include non directory if not included
|
||||||
|
// we leave directory filtering to the layer above
|
||||||
|
if useFilter && !fi.IsDir() && !filter.IncludeRemote(newRemote) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// Follow symlinks if required
|
// Follow symlinks if required
|
||||||
if f.opt.FollowSymlinks && (mode&os.ModeSymlink) != 0 {
|
if f.opt.FollowSymlinks && (mode&os.ModeSymlink) != 0 {
|
||||||
localPath := filepath.Join(fsDirPath, name)
|
localPath := filepath.Join(fsDirPath, name)
|
||||||
|
|
|
@ -9,11 +9,13 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/config/configmap"
|
"github.com/rclone/rclone/fs/config/configmap"
|
||||||
|
"github.com/rclone/rclone/fs/filter"
|
||||||
"github.com/rclone/rclone/fs/hash"
|
"github.com/rclone/rclone/fs/hash"
|
||||||
"github.com/rclone/rclone/fs/object"
|
"github.com/rclone/rclone/fs/object"
|
||||||
"github.com/rclone/rclone/fstest"
|
"github.com/rclone/rclone/fstest"
|
||||||
|
@ -366,3 +368,33 @@ func TestMetadata(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFilter(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
r := fstest.NewRun(t)
|
||||||
|
defer r.Finalise()
|
||||||
|
when := time.Now()
|
||||||
|
r.WriteFile("included", "included file", when)
|
||||||
|
r.WriteFile("excluded", "excluded file", when)
|
||||||
|
f := r.Flocal.(*Fs)
|
||||||
|
|
||||||
|
// Add a filter
|
||||||
|
ctx, fi := filter.AddConfig(ctx)
|
||||||
|
require.NoError(t, fi.AddRule("+ included"))
|
||||||
|
require.NoError(t, fi.AddRule("- *"))
|
||||||
|
|
||||||
|
// Check listing without use filter flag
|
||||||
|
entries, err := f.List(ctx, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
sort.Sort(entries)
|
||||||
|
require.Equal(t, "[excluded included]", fmt.Sprint(entries))
|
||||||
|
|
||||||
|
// Add user filter flag
|
||||||
|
ctx = filter.SetUseFilter(ctx, true)
|
||||||
|
|
||||||
|
// Check listing with use filter flag
|
||||||
|
entries, err = f.List(ctx, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
sort.Sort(entries)
|
||||||
|
require.Equal(t, "[included]", fmt.Sprint(entries))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue