Delete command which does obey the filters - fixes #327

s3-about
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 ###
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 ###

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.
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.
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
}
// 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) {
r := NewRun(t)
defer r.Finalise()

View File

@ -206,7 +206,8 @@ var Commands = []Command{
Name: "purge",
ArgsHelp: "remote:path",
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 {
return fs.Purge(fdst)
},
@ -214,6 +215,18 @@ var Commands = []Command{
MaxArgs: 1,
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",
ArgsHelp: "source:path dest:path",