Delete command which does obey the filters - fixes #327

This commit is contained in:
Nick Craig-Wood 2015-12-02 22:25:32 +00:00
parent 5c37b777fc
commit 1373efaa39
5 changed files with 74 additions and 3 deletions

View file

@ -107,7 +107,28 @@ objects in it, use purge for that.
### rclone purge remote:path ### ### rclone purge remote:path ###
Remove the path and all of its contents. Remove the path and all of its contents. Note that this does not obey
include/exclude filters - everything will be removed. Use `delete` if
you want to selectively delete files.
### rclone delete remote:path ###
Remove the contents of path. Unlike `purge` it obeys include/exclude
filters so can be used to selectively delete files.
Eg delete all files bigger than 100MBytes
Check what would be deleted first (use either)
rclone --min-size 100M lsl remote:path
rclone --dry-run --min-size 100M delete remote:path
Then delete
rclone --min-size 100M delete remote:path
That reads "delete everything with a minimum size of 100 MB", hence
delete all files bigger than 100MBytes.
### rclone check source:path dest:path ### ### rclone check source:path dest:path ###

View file

@ -10,7 +10,7 @@ Rclone has a sophisticated set of include and exclude rules. Some of
these are based on patterns and some on other things like file size. these are based on patterns and some on other things like file size.
The filters are applied for the `copy`, `sync`, `move`, `ls`, `lsl`, The filters are applied for the `copy`, `sync`, `move`, `ls`, `lsl`,
`md5sum`, `sha1sum`, `size` and `check` operations. `md5sum`, `sha1sum`, `size`, `delete` and `check` operations.
Note that `purge` does not obey the filters. Note that `purge` does not obey the filters.
Each path as it passes through rclone is matched against the include Each path as it passes through rclone is matched against the include

View file

@ -891,3 +891,20 @@ func Purge(f Fs) error {
} }
return nil return nil
} }
// Delete removes all the contents of a container. Unlike Purge, it
// obeys includes and excludes.
func Delete(f Fs) error {
wg := new(sync.WaitGroup)
delete := make(ObjectsChan, Config.Transfers)
wg.Add(1)
go func() {
defer wg.Done()
DeleteFiles(delete)
}()
err := ListFn(f, func(o Object) {
delete <- o
})
close(delete)
return err
}

View file

@ -868,6 +868,26 @@ func TestCount(t *testing.T) {
} }
} }
func TestDelete(t *testing.T) {
r := NewRun(t)
defer r.Finalise()
file1 := r.WriteObject("small", "1234567890", t2) // 10 bytes
file2 := r.WriteObject("medium", "------------------------------------------------------------", t1) // 60 bytes
file3 := r.WriteObject("large", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", t1) // 100 bytes
fstest.CheckItems(t, r.fremote, file1, file2, file3)
fs.Config.Filter.MaxSize = 60
defer func() {
fs.Config.Filter.MaxSize = 0
}()
err := fs.Delete(r.fremote)
if err != nil {
t.Fatalf("Sync failed: %v", err)
}
fstest.CheckItems(t, r.fremote, file3)
}
func TestCheck(t *testing.T) { func TestCheck(t *testing.T) {
r := NewRun(t) r := NewRun(t)
defer r.Finalise() defer r.Finalise()

View file

@ -206,7 +206,8 @@ var Commands = []Command{
Name: "purge", Name: "purge",
ArgsHelp: "remote:path", ArgsHelp: "remote:path",
Help: ` Help: `
Remove the path and all of its contents.`, Remove the path and all of its contents. Does not obey
filters - use remove for that.`,
Run: func(fdst, fsrc fs.Fs) error { Run: func(fdst, fsrc fs.Fs) error {
return fs.Purge(fdst) return fs.Purge(fdst)
}, },
@ -214,6 +215,18 @@ var Commands = []Command{
MaxArgs: 1, MaxArgs: 1,
Retry: true, Retry: true,
}, },
{
Name: "delete",
ArgsHelp: "remote:path",
Help: `
Remove the contents of path. Obeys include/exclude filters.`,
Run: func(fdst, fsrc fs.Fs) error {
return fs.Delete(fdst)
},
MinArgs: 1,
MaxArgs: 1,
Retry: true,
},
{ {
Name: "check", Name: "check",
ArgsHelp: "source:path dest:path", ArgsHelp: "source:path dest:path",