New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sync: overlap check is now filter-sensitive #6025
base: master
Are you sure you want to change the base?
sync: overlap check is now filter-sensitive #6025
Conversation
Previously, the overlap check was based on simple prefix checks of the source and destination paths. Now it actually checks whether the destination is excluded via any filter rule or a "--exclude-if-present"-file.
I've noticed some initially unwanted (but maybe reasonable) behavior. Because of the way I implemented the recursive checks, the sync command is only allowed to be executed when the destination directory already exists (in contrast to sync commands under normal circumstances where the destination directory is created automatically). What are your thoughts on this? @ncw |
This is because you are listing the directory I think. It should be possible to do these checks without actually calling
I'm not sure I understood the problem there! Can you give some examples please? I will give the code a quick first review now. |
@@ -796,6 +796,53 @@ func Overlapping(fdst, fsrc fs.Info) bool { | |||
return strings.HasPrefix(fdstRoot, fsrcRoot) || strings.HasPrefix(fsrcRoot, fdstRoot) | |||
} | |||
|
|||
// OverlappingFilterCheck returns true if fdst and fsrc point to the same | |||
// underlying Fs and they overlap without fdst being excluded by any filter rule. | |||
func OverlappingFilterCheck(ctx context.Context, fdst fs.Fs, fsrc fs.Fs) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs testing in operations_test.go
fs/operations/operations.go
Outdated
} | ||
|
||
// FilterCheckR checks if fdst would be included in the sync | ||
func FilterCheckR(ctx context.Context, fdstRelative string, inputPath string, fsrc fs.Fs) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs testing in operations_test.go
also
fs/operations/operations.go
Outdated
include := true | ||
fi := filter.GetConfig(ctx) | ||
includeDirectory := fi.IncludeDirectory(ctx, fsrc) | ||
entries, _ := fsrc.List(ctx, inputPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really don't like calling List
here. We should be able to do this just by examining the filter and paths shouldn't we?
fs/sync/sync_test.go
Outdated
|
||
subRemoteName := r.FremoteName + "/rclone-sync-test" | ||
FremoteSync, err := fs.NewFs(ctx, subRemoteName) | ||
FremoteSync.Mkdir(ctx, "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error for this needs to be checked.
require.NoError(t, FremoteSync.Mkdir(ctx, ""))
is fine
After the rewrite I essentially got the automatic directory creation for free, so I just decided to keep it to be consistent with the standard sync behavior. If you're satisfied with the implementation, I can continue to look into how to properly write the tests for |
I think this looks much better now.
I don't think you need to call Mkdir
either.
Can you write a table driven test for FilterCheckR
testing all the corner cases - it is quite complicated that function and I'd like to be sure it is correct!
A test for OverlappingFilterCheck
would be nice too.
Thank you :-)
fs/operations/operations.go
Outdated
fdstRoot := fixRoot(fdst) | ||
fsrcRoot := fixRoot(fsrc) | ||
if strings.HasPrefix(fdstRoot, fsrcRoot) { | ||
fdstRelative := strings.ReplaceAll(fdstRoot, fsrcRoot, "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably better written something like this (ReplaceAll
could replace stuff it isn't supposed to).
fdstRelative := fdstRoot[len(fsrcRoot):]
fs/operations/operations.go
Outdated
} | ||
|
||
if !include { | ||
err := fsrc.Mkdir(ctx, fdstRelative) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be necessary to run Mkdir
here - the sync will do it for you.
fs/operations/operations.go
Outdated
for i := 0; i <= pos; i++ { | ||
newPath += dirs[i] | ||
} | ||
dir := fs.NewDir(newPath, time.Now()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this dir
gets used anywhere does it? How about currentPath := newPath
?
I used the existing |
It might be that |
I renamed the function because it should not be used outside the package. As you might have already guessed, I am new to programming with go and didn't know about this concept. Thank you for your time and patience! |
What is the purpose of this change?
Previously, the overlap check was based on simple prefix checks of the source and destination paths. Now it actually checks whether the destination is excluded via any filter rule or a "--exclude-if-present"-file.
Was the change discussed in an issue or in the forum before?
Forum Post
Checklist