Skip to content

Commit 16efb93

Browse files
committed
Make sync behaviour closer to rsync.
- Check size and time - Provide optional function that specify whether to sync (e.g., checksums)
1 parent c65d55f commit 16efb93

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

src/path.jl

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -514,13 +514,22 @@ function Base.mv(src::AbstractPath, dst::AbstractPath; force=false)
514514
end
515515

516516
"""
517-
sync(src::AbstractPath, dst::AbstractPath; delete=false)
517+
sync([f::Function,] src::AbstractPath, dst::AbstractPath; delete=false, overwrite=true)
518518
519-
Recursively copy new and updated files from the source path to the
520-
destination. If delete is true then files at the destination that don't
521-
exist at the source will be removed.
519+
Recursively copy new and updated files from the source path to the destination.
520+
If delete is true then files at the destination that don't exist at the source will be removed.
521+
By default, source files are sent to the destination if they have different sizes or the source has newer
522+
last modified date.
523+
524+
Optionally, you can specify a function `f` which will take a `src` and `dst` path and return
525+
true if the `src` should be sent. This may be useful if you'd like to use a checksum for
526+
comparison.
522527
"""
523-
function sync(src::AbstractPath, dst::AbstractPath; delete=false)
528+
function sync(src::AbstractPath, dst::AbstractPath; kwargs...)
529+
sync(should_sync, src, dst; kwargs...)
530+
end
531+
532+
function sync(f::Function, src::AbstractPath, dst::AbstractPath; delete=false, overwrite=true)
524533
# Create an index of all of the source files
525534
src_paths = collect(walkpath(src))
526535
index = Dict(
@@ -533,7 +542,7 @@ function sync(src::AbstractPath, dst::AbstractPath; delete=false)
533542

534543
if haskey(index, k)
535544
src_path = src_paths[index[k]]
536-
if modified(src_path) > modified(p)
545+
if overwrite && f(src_path, p)
537546
cp(src_path, p; force=true)
538547
end
539548

@@ -556,6 +565,22 @@ function sync(src::AbstractPath, dst::AbstractPath; delete=false)
556565
end
557566
end
558567

568+
function should_sync(src::AbstractPath, dst::AbstractPath)
569+
src_stat = stat(src)
570+
dst_stat = stat(dst)
571+
572+
if src_stat.size != dst_stat.size || src_stat.mtime > dst_stat.mtime
573+
@debug(
574+
"syncing: $src -> $dst, " *
575+
"size: $(src_stat.size) -> $(dst_stat.size), " *
576+
"modified_time: $(src_stat.mtime) -> $(dst_stat.mtime)"
577+
)
578+
return true
579+
else
580+
return false
581+
end
582+
end
583+
559584
"""
560585
download(url::Union{AbstractString, AbstractPath}, localfile::AbstractPath)
561586

src/test.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ module TestPaths
621621
@test modified(ps.baz) < baz_t
622622

623623
# Don't cp unchanged files when a new file is added
624-
# NOTE: sleep before we make a new file, so it's clear tha the
624+
# NOTE: sleep before we make a new file, so it's clear that the
625625
# modified time has changed.
626626
sleep(1)
627627
write(ps.foo / "test.txt", "New File")

0 commit comments

Comments
 (0)