forked from TrueCloudLab/rclone
Add ListDirSorted function to list a directory
* fix error return of readFilesFn also
This commit is contained in:
parent
85f05c57d1
commit
c3b2b89473
2 changed files with 124 additions and 1 deletions
|
@ -504,7 +504,72 @@ func readFilesFn(fs Fs, includeAll bool, dir string, add func(Object) error) (er
|
||||||
Debug(o, "Excluded from sync (and deletion)")
|
Debug(o, "Excluded from sync (and deletion)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return list.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DirEntries is a slice of Object or *Dir
|
||||||
|
type DirEntries []BasicInfo
|
||||||
|
|
||||||
|
// Len is part of sort.Interface.
|
||||||
|
func (ds DirEntries) Len() int {
|
||||||
|
return len(ds)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap is part of sort.Interface.
|
||||||
|
func (ds DirEntries) Swap(i, j int) {
|
||||||
|
ds[i], ds[j] = ds[j], ds[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Less is part of sort.Interface.
|
||||||
|
func (ds DirEntries) Less(i, j int) bool {
|
||||||
|
return ds[i].Remote() < ds[j].Remote()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME can use this in Mount
|
||||||
|
|
||||||
|
// ListDirSorted reads Object and *Dir into entries for the given Fs.
|
||||||
|
//
|
||||||
|
// dir is the start directory, "" for root
|
||||||
|
//
|
||||||
|
// If includeAll is specified all files will be added, otherwise only
|
||||||
|
// files passing the filter will be added.
|
||||||
|
//
|
||||||
|
// Files will be returned in sorted order
|
||||||
|
func ListDirSorted(fs Fs, includeAll bool, dir string) (entries DirEntries, err error) {
|
||||||
|
list := NewLister().SetLevel(1)
|
||||||
|
if !includeAll {
|
||||||
|
list.SetFilter(Config.Filter)
|
||||||
|
}
|
||||||
|
list.Start(fs, dir)
|
||||||
|
for {
|
||||||
|
o, dir, err := list.Get()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if o != nil {
|
||||||
|
// Make sure we don't delete excluded files if not required
|
||||||
|
if includeAll || Config.Filter.IncludeObject(o) {
|
||||||
|
entries = append(entries, o)
|
||||||
|
} else {
|
||||||
|
Debug(o, "Excluded from sync (and deletion)")
|
||||||
|
}
|
||||||
|
} else if dir != nil {
|
||||||
|
if includeAll || Config.Filter.IncludeDirectory(dir.Remote()) {
|
||||||
|
entries = append(entries, dir)
|
||||||
|
} else {
|
||||||
|
Debug(dir, "Excluded from sync (and deletion)")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// finishd since err, o, dir == nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = list.Error()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// sort the directory entries by Remote
|
||||||
|
sort.Sort(entries)
|
||||||
|
return entries, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a map of Object.Remote to Object for the given Fs.
|
// Read a map of Object.Remote to Object for the given Fs.
|
||||||
|
|
|
@ -883,3 +883,61 @@ func TestOverlapping(t *testing.T) {
|
||||||
assert.Equal(t, test.expected, actual, what)
|
assert.Equal(t, test.expected, actual, what)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListDirSorted(t *testing.T) {
|
||||||
|
r := NewRun(t)
|
||||||
|
defer r.Finalise()
|
||||||
|
|
||||||
|
fs.Config.Filter.MaxSize = 10
|
||||||
|
defer func() {
|
||||||
|
fs.Config.Filter.MaxSize = -1
|
||||||
|
}()
|
||||||
|
|
||||||
|
r.WriteObject("a.txt", "hello world", t1)
|
||||||
|
r.WriteObject("zend.txt", "hello", t1)
|
||||||
|
r.WriteObject("sub dir/hello world", "hello world", t1)
|
||||||
|
r.WriteObject("sub dir/hello world2", "hello world", t1)
|
||||||
|
r.WriteObject("sub dir/sub sub dir/hello world3", "hello world", t1)
|
||||||
|
var items fs.DirEntries
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Turn the BasicInfo into a name, ending with a / if it is a
|
||||||
|
// dir
|
||||||
|
str := func(i int) string {
|
||||||
|
item := items[i]
|
||||||
|
name := item.Remote()
|
||||||
|
switch item.(type) {
|
||||||
|
case fs.Object:
|
||||||
|
case *fs.Dir:
|
||||||
|
name += "/"
|
||||||
|
default:
|
||||||
|
t.Fatalf("Unknown type %+v", item)
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
items, err = fs.ListDirSorted(r.fremote, true, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, items, 3)
|
||||||
|
assert.Equal(t, "a.txt", str(0))
|
||||||
|
assert.Equal(t, "sub dir/", str(1))
|
||||||
|
assert.Equal(t, "zend.txt", str(2))
|
||||||
|
|
||||||
|
items, err = fs.ListDirSorted(r.fremote, false, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, items, 2)
|
||||||
|
assert.Equal(t, "sub dir/", str(0))
|
||||||
|
assert.Equal(t, "zend.txt", str(1))
|
||||||
|
|
||||||
|
items, err = fs.ListDirSorted(r.fremote, true, "sub dir")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, items, 3)
|
||||||
|
assert.Equal(t, "sub dir/hello world", str(0))
|
||||||
|
assert.Equal(t, "sub dir/hello world2", str(1))
|
||||||
|
assert.Equal(t, "sub dir/sub sub dir/", str(2))
|
||||||
|
|
||||||
|
items, err = fs.ListDirSorted(r.fremote, false, "sub dir")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, items, 1)
|
||||||
|
assert.Equal(t, "sub dir/sub sub dir/", str(0))
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue