rmdirs: add --leave-root flag - fixes #1874

This commit is contained in:
lewapm 2017-12-13 11:23:54 +01:00 committed by Nick Craig-Wood
parent 0914ec316c
commit 9c242edc10
4 changed files with 53 additions and 6 deletions

View file

@ -6,8 +6,13 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var (
leaveRoot = false
)
func init() { func init() {
cmd.Root.AddCommand(rmdirsCmd) cmd.Root.AddCommand(rmdirsCmd)
rmdirsCmd.Flags().BoolVarP(&leaveRoot, "leave-root", "", leaveRoot, "Do not remove root directory if empty")
} }
var rmdirsCmd = &cobra.Command{ var rmdirsCmd = &cobra.Command{
@ -17,6 +22,8 @@ var rmdirsCmd = &cobra.Command{
empty directories) under the path that it finds, including the path if empty directories) under the path that it finds, including the path if
it has nothing in. it has nothing in.
If you supply the --leave-root flag, it will not remove the root directory.
This is useful for tidying up remotes that rclone has left a lot of This is useful for tidying up remotes that rclone has left a lot of
empty directories in. empty directories in.
@ -25,7 +32,7 @@ empty directories in.
cmd.CheckArgs(1, 1, command, args) cmd.CheckArgs(1, 1, command, args)
fdst := cmd.NewFsDst(args) fdst := cmd.NewFsDst(args)
cmd.Run(true, false, command, func() error { cmd.Run(true, false, command, func() error {
return fs.Rmdirs(fdst, "") return fs.Rmdirs(fdst, "", leaveRoot)
}) })
}, },
} }

View file

@ -457,6 +457,10 @@ This can be useful as an additional layer of protection for immutable
or append-only data sets (notably backup archives), where modification or append-only data sets (notably backup archives), where modification
implies corruption and should not be propagated. implies corruption and should not be propagated.
## --leave-root ###
During rmdirs it will not remove root directory, even if it's empty.
### --log-file=FILE ### ### --log-file=FILE ###
Log all of rclone's output to FILE. This is not active by default. Log all of rclone's output to FILE. This is not active by default.

View file

@ -1183,7 +1183,7 @@ func Purge(f Fs) error {
if err != nil { if err != nil {
return err return err
} }
err = Rmdirs(f, "") err = Rmdirs(f, "", false)
} }
if err != nil { if err != nil {
Stats.Error(err) Stats.Error(err)
@ -1672,9 +1672,9 @@ func Rcat(fdst Fs, dstFileName string, in io.ReadCloser, modTime time.Time) (dst
// Rmdirs removes any empty directories (or directories only // Rmdirs removes any empty directories (or directories only
// containing empty directories) under f, including f. // containing empty directories) under f, including f.
func Rmdirs(f Fs, dir string) error { func Rmdirs(f Fs, dir string, leaveRoot bool) error {
dirEmpty := make(map[string]bool) dirEmpty := make(map[string]bool)
dirEmpty[""] = true dirEmpty[""] = !leaveRoot
err := Walk(f, dir, true, Config.MaxDepth, func(dirPath string, entries DirEntries, err error) error { err := Walk(f, dir, true, Config.MaxDepth, func(dirPath string, entries DirEntries, err error) error {
if err != nil { if err != nil {
Stats.Error(err) Stats.Error(err)

View file

@ -522,7 +522,7 @@ func TestRcat(t *testing.T) {
check(false) check(false)
} }
func TestRmdirs(t *testing.T) { func TestRmdirsNoLeaveRoot(t *testing.T) {
r := fstest.NewRun(t) r := fstest.NewRun(t)
defer r.Finalise() defer r.Finalise()
r.Mkdir(r.Fremote) r.Mkdir(r.Fremote)
@ -562,7 +562,7 @@ func TestRmdirs(t *testing.T) {
fs.Config.ModifyWindow, fs.Config.ModifyWindow,
) )
require.NoError(t, fs.Rmdirs(r.Fremote, "")) require.NoError(t, fs.Rmdirs(r.Fremote, "", false))
fstest.CheckListingWithPrecision( fstest.CheckListingWithPrecision(
t, t,
@ -580,6 +580,42 @@ func TestRmdirs(t *testing.T) {
} }
func TestRmdirsLeaveRoot(t *testing.T) {
r := fstest.NewRun(t)
defer r.Finalise()
r.Mkdir(r.Fremote)
r.ForceMkdir(r.Fremote)
require.NoError(t, fs.Mkdir(r.Fremote, "A1"))
require.NoError(t, fs.Mkdir(r.Fremote, "A1/B1"))
require.NoError(t, fs.Mkdir(r.Fremote, "A1/B1/C1"))
fstest.CheckListingWithPrecision(
t,
r.Fremote,
[]fstest.Item{},
[]string{
"A1",
"A1/B1",
"A1/B1/C1",
},
fs.Config.ModifyWindow,
)
require.NoError(t, fs.Rmdirs(r.Fremote, "/A1", true))
fstest.CheckListingWithPrecision(
t,
r.Fremote,
[]fstest.Item{},
[]string{
"A1",
},
fs.Config.ModifyWindow,
)
}
func TestMoveFile(t *testing.T) { func TestMoveFile(t *testing.T) {
r := fstest.NewRun(t) r := fstest.NewRun(t)
defer r.Finalise() defer r.Finalise()