diff --git a/fs/sync.go b/fs/sync.go index d2dfe18ea..71ab58e62 100644 --- a/fs/sync.go +++ b/fs/sync.go @@ -36,6 +36,8 @@ type syncCopyMove struct { dstFilesResult chan error // error result of dst listing dstEmptyDirsMu sync.Mutex // protect dstEmptyDirs dstEmptyDirs []DirEntry // potentially empty directories + srcEmptyDirsMu sync.Mutex // protect srcEmptyDirs + srcEmptyDirs []DirEntry // potentially empty directories checkerWg sync.WaitGroup // wait for checkers toBeChecked ObjectPairChan // checkers channel transfersWg sync.WaitGroup // wait for transfers @@ -694,6 +696,20 @@ func (s *syncCopyMove) run() error { s.processError(deleteEmptyDirectories(s.fdst, s.dstEmptyDirs)) } } + + // if DoMove, delete fsrc directory after + if s.DoMove { + //first delete any subdirectories in fsrc + s.processError(deleteEmptyDirectories(s.fsrc, s.srcEmptyDirs)) + //delete fsrc dir + s.processError(func() error { + err := TryRmdir(s.fsrc, "") + if err != nil { + Debugf(logDirName(s.fsrc, ""), "Failed to Rmdir: %v", err) + } + return nil + }()) + } return s.currentError() } @@ -747,6 +763,10 @@ func (s *syncCopyMove) SrcOnly(src DirEntry) (recurse bool) { } case Directory: // Do the same thing to the entire contents of the directory + // Record the directory for deletion + s.srcEmptyDirsMu.Lock() + s.srcEmptyDirs = append(s.srcEmptyDirs, src) + s.srcEmptyDirsMu.Unlock() return true default: panic("Bad object in DirEntries") @@ -774,6 +794,10 @@ func (s *syncCopyMove) Match(dst, src DirEntry) (recurse bool) { // Do the same thing to the entire contents of the directory _, ok := dst.(Directory) if ok { + // Record the src directory for deletion + s.srcEmptyDirsMu.Lock() + s.srcEmptyDirs = append(s.srcEmptyDirs, src) + s.srcEmptyDirsMu.Unlock() return true } // FIXME src is dir, dst is file diff --git a/fs/sync_test.go b/fs/sync_test.go index da34a6d22..b9247cca5 100644 --- a/fs/sync_test.go +++ b/fs/sync_test.go @@ -824,7 +824,7 @@ func testServerSideMove(t *testing.T, r *fstest.Run, withFilter bool) { if withFilter { fstest.CheckItems(t, r.Fremote, file2) } else { - fstest.CheckItems(t, r.Fremote) + fstest.CheckRootDir(t, r.Fremote, false) } fstest.CheckItems(t, FremoteMove, file2, file1, file3u) @@ -843,7 +843,7 @@ func testServerSideMove(t *testing.T, r *fstest.Run, withFilter bool) { fstest.CheckItems(t, FremoteMove, file2) } else { fstest.CheckItems(t, FremoteMove2, file2, file1, file3u) - fstest.CheckItems(t, FremoteMove) + fstest.CheckRootDir(t, FremoteMove, false) } } diff --git a/fstest/fstest.go b/fstest/fstest.go index e30bd9613..de39a3227 100644 --- a/fstest/fstest.go +++ b/fstest/fstest.go @@ -262,6 +262,7 @@ func CheckListingWithPrecision(t *testing.T, f fs.Fs, items []Item, expectedDirs if err != nil && err != fs.ErrorDirNotFound { t.Fatalf("Error listing: %v", err) } + gotListing = makeListingFromObjects(objs) listingOK = wantListing1 == gotListing || wantListing2 == gotListing if listingOK && (expectedDirs == nil || len(dirs) == len(expectedDirs)) { @@ -320,6 +321,16 @@ func CheckItems(t *testing.T, f fs.Fs, items ...Item) { CheckListingWithPrecision(t, f, items, nil, fs.Config.ModifyWindow) } +// CheckRootDir checks the fs to see if the root dir exists or not +func CheckRootDir(t *testing.T, f fs.Fs, shouldExist bool) { + _, _, err := fs.WalkGetAll(f, "", true, -1) + if shouldExist { + require.NoError(t, err) + } else { + assert.EqualError(t, err, fs.ErrorDirNotFound.Error()) + } +} + // Time parses a time string or logs a fatal error func Time(timeString string) time.Time { t, err := time.Parse(time.RFC3339Nano, timeString)