Skip to content

Commit 514be00

Browse files
author
peter1000
committed
new__cp_function: inclusive documentation, tests and entry in NEWS.md.
1 parent 8689a50 commit 514be00

File tree

5 files changed

+360
-50
lines changed

5 files changed

+360
-50
lines changed

NEWS.md

+8
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,12 @@ Library improvements
243243

244244
* The `randexp` and `randexp!` functions are exported ([#9144])
245245

246+
* File
247+
248+
* Added function `readlink` which returns the value of a symbolic link "path" ([#10714]).
249+
250+
* The `cp` function now accepts keyword arguments `remove_destination` and `follow_symlinks` ([#10888]).
251+
246252
* Other improvements
247253

248254
* You can now tab-complete Emoji characters via their [short names](http://www.emoji-cheat-sheet.com/), using `\:name:<tab>` ([#10709]).
@@ -1374,9 +1380,11 @@ Too numerous to mention.
13741380
[#10659]: https://github.com/JuliaLang/julia/issues/10659
13751381
[#10679]: https://github.com/JuliaLang/julia/issues/10679
13761382
[#10709]: https://github.com/JuliaLang/julia/issues/10709
1383+
[#10714]: https://github.com/JuliaLang/julia/pull/10714
13771384
[#10747]: https://github.com/JuliaLang/julia/issues/10747
13781385
[#10844]: https://github.com/JuliaLang/julia/issues/10844
13791386
[#10870]: https://github.com/JuliaLang/julia/issues/10870
13801387
[#10885]: https://github.com/JuliaLang/julia/issues/10885
1388+
[#10888]: https://github.com/JuliaLang/julia/pull/10888
13811389
[#10893]: https://github.com/JuliaLang/julia/pull/10893
13821390
[#10914]: https://github.com/JuliaLang/julia/issues/10914

base/file.jl

+39-10
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,47 @@ end
7070

7171
# The following use Unix command line facilites
7272

73-
function cp(src::AbstractString, dst::AbstractString; recursive::Bool=false)
74-
if islink(src) || !isdir(src)
75-
FS.sendfile(src, dst)
76-
elseif recursive
77-
mkdir(dst)
78-
for p in readdir(src)
79-
cp(joinpath(src, p), joinpath(dst, p), recursive=recursive)
73+
function cptree(src::AbstractString, dst::AbstractString; remove_destination::Bool=false,
74+
follow_symlinks::Bool=false)
75+
isdir(src) || throw(ArgumentError("'$src' is not a directory. Use `cp(src, dst)`"))
76+
if ispath(dst)
77+
if remove_destination
78+
rm(dst; recursive=true)
79+
else
80+
throw(ArgumentError(string("'$dst' exists. `remove_destination=true` ",
81+
"is required to remove '$dst' before copying.")))
82+
end
83+
end
84+
mkdir(dst)
85+
for name in readdir(src)
86+
srcname = joinpath(src, name)
87+
if !follow_symlinks && islink(srcname)
88+
symlink(readlink(srcname), joinpath(dst, name))
89+
elseif isdir(srcname)
90+
cptree(srcname, joinpath(dst, name); remove_destination=remove_destination,
91+
follow_symlinks=follow_symlinks)
92+
else
93+
FS.sendfile(srcname, joinpath(dst, name))
8094
end
95+
end
96+
end
97+
98+
function cp(src::AbstractString, dst::AbstractString; remove_destination::Bool=false,
99+
follow_symlinks::Bool=false)
100+
if ispath(dst)
101+
if remove_destination
102+
rm(dst; recursive=true)
103+
else
104+
throw(ArgumentError(string("'$dst' exists. `remove_destination=true` ",
105+
"is required to remove '$dst' before copying.")))
106+
end
107+
end
108+
if !follow_symlinks && islink(src)
109+
symlink(readlink(src), dst)
110+
elseif isdir(src)
111+
cptree(src, dst; remove_destination=remove_destination, follow_symlinks=follow_symlinks)
81112
else
82-
throw(ArgumentError(string("'$src' is a directory. ",
83-
"Use `cp(src, dst, recursive=true)` ",
84-
"to copy directories recursively.")))
113+
FS.sendfile(src, dst)
85114
end
86115
end
87116
mv(src::AbstractString, dst::AbstractString) = FS.rename(src, dst)

doc/helpdb.jl

+7-3
Original file line numberDiff line numberDiff line change
@@ -5172,10 +5172,14 @@ Millisecond(v)
51725172
51735173
"),
51745174

5175-
("Base","cp","cp(src::AbstractString, dst::AbstractString; recursive=false)
5175+
("Base","cp","cp(src::AbstractString, dst::AbstractString; remove_destination::Bool=false, follow_symlinks::Bool=false)
51765176
5177-
Copy a file from *src* to *dest*. Passing \"recursive=true\" will
5178-
enable recursive copying of directories.
5177+
Copy the file, link, or directory from *src* to *dest*.
5178+
\"remove_destination=true\" will first remove an existing `dst`.
5179+
5180+
If `follow_symlinks=false`, and src is a symbolic link, dst will be created as a symbolic link.
5181+
If `follow_symlinks=true` and src is a symbolic link, dst will be a copy of the file or directory
5182+
`src` refers to.
51795183
51805184
"),
51815185

doc/stdlib/file.rst

+7-3
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,14 @@
109109
Like uperm but gets the permissions for people who neither own the file nor are a
110110
member of the group owning the file
111111

112-
.. function:: cp(src::AbstractString,dst::AbstractString; recursive=false)
112+
.. function:: cp(src::AbstractString, dst::AbstractString; remove_destination::Bool=false, follow_symlinks::Bool=false)
113113

114-
Copy a file from `src` to `dest`. Passing ``recursive=true`` will enable
115-
recursive copying of directories.
114+
Copy the file, link, or directory from *src* to *dest*.
115+
\"remove_destination=true\" will first remove an existing `dst`.
116+
117+
If `follow_symlinks=false`, and src is a symbolic link, dst will be created as a symbolic link.
118+
If `follow_symlinks=true` and src is a symbolic link, dst will be a copy of the file or directory
119+
`src` refers to.
116120

117121
.. function:: download(url,[localfile])
118122

0 commit comments

Comments
 (0)