Skip to content

Commit f44c8a7

Browse files
authored
Merge pull request #13 from giordano/mg/directory-nofollow
Do not follow symlinks by default for `DirectorySource`
2 parents 184b03f + 77a66d3 commit f44c8a7

File tree

4 files changed

+49
-19
lines changed

4 files changed

+49
-19
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "BinaryBuilderBase"
22
uuid = "7f725544-6523-48cd-82d1-3fa08ff4056e"
33
authors = ["Elliot Saba <[email protected]>"]
4-
version = "0.3.0"
4+
version = "0.3.1"
55

66
[deps]
77
CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193"

src/Prefix.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,9 @@ function setup(source::SetupSource{DirectorySource}, targetdir, verbose)
302302
@info "Copying content of $(basename(srcpath)) in $(basename(targetdir))..."
303303
end
304304
for file_dir in readdir(srcpath)
305-
# Copy the content of the source directory to the destination. Note that we DO follow symlinks here!
306-
# This is to support symlink patchsets across multiple versions of GCC, etc...
307-
cp(joinpath(srcpath, file_dir), joinpath(targetdir, basename(file_dir)); follow_symlinks=true)
305+
# Copy the content of the source directory to the destination
306+
cp(joinpath(srcpath, file_dir), joinpath(targetdir, basename(file_dir));
307+
follow_symlinks=source.follow_symlinks)
308308
end
309309
end
310310

src/Sources.jl

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,37 @@ GitSource(url::String, hash::String; unpack_target::String = "") =
7676
GitSource(url, hash, unpack_target)
7777

7878
"""
79-
DirectorySource(path::String; target::String = basename(path))
79+
DirectorySource(path::String; target::String = basename(path), follow_symlinks=false)
8080
8181
Specify a local directory to mount from `path`.
8282
83-
The content of the directory will be mounted in `\${WORKSPACE}/srcdir`, or in its
84-
subdirectory pointed to by the optional keyword `target`, if provided.
83+
The content of the directory will be mounted in `\${WORKSPACE}/srcdir`, or in
84+
its subdirectory pointed to by the optional keyword `target`, if provided.
85+
Symbolic links are replaced by a copy of the target when `follow_symlinks` is
86+
`true`.
8587
"""
8688
struct DirectorySource <: AbstractSource
8789
path::String
8890
target::String
91+
follow_symlinks::Bool
8992
end
90-
DirectorySource(path::String; target::String = "") =
91-
DirectorySource(path, target)
93+
# When setting up the source, by default we won't follow symlinks. However,
94+
# there are cases where this is necessary, for example when we have symlink
95+
# patchsets across multiple versions of GCC, etc...
96+
DirectorySource(path::String; target::String = "", follow_symlinks::Bool=false) =
97+
DirectorySource(path, target, follow_symlinks)
9298

9399
# This is not meant to be used as source in the `build_tarballs.jl` scripts but
94100
# only to set up the source in the workspace.
95101
struct SetupSource{T<:AbstractSource}
96102
path::String
97103
hash::String
98104
target::String
105+
follow_symlinks::Bool
99106
end
107+
# `follow_symlinks` is used only for DirectorySource, let's have a method without it.
108+
SetupSource{T}(path::String, hash::String, target::String) where {T} =
109+
SetupSource{T}(path, hash, target, false)
100110
# This is used in wizard/obtain_source.jl to automatically guess the parameter
101111
# of SetupSource from the URL
102112
function SetupSource(url::String, path::String, hash::String, target::String)
@@ -167,7 +177,7 @@ function download_source(source::DirectorySource; verbose::Bool = false)
167177
error("Could not find directory \"$(source.path)\".")
168178
end
169179
@info "Directory \"$(source.path)\" found"
170-
return SetupSource{DirectorySource}(abspath(source.path), "", source.target)
180+
return SetupSource{DirectorySource}(abspath(source.path), "", source.target, source.follow_symlinks)
171181
end
172182

173183
"""

test/sources.jl

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,27 @@ using JSON
3737
# Fetch again the repo to make sure cache works
3838
@test @test_logs (:info, r"^Cached repository found in") download_source(gs; verbose = true, downloads_dir = dir) == sgs
3939
# Fetch the temp directory as a `DirectorySource`
40-
ds = DirectorySource("./bundled")
41-
patchdir = abspath(joinpath(dir, ds.path, "patches"))
40+
ds_follow = DirectorySource("./bundled_follow"; follow_symlinks=true)
41+
patchdir = abspath(joinpath(dir, ds_follow.path, "patches_follow"))
4242
mkpath(patchdir)
4343
write(abspath(joinpath(patchdir, "fix-windows-headers.patch")), "This is a patch file")
4444
# Create a symlink. We'll want to check that `setup` follows symlinks
4545
link = joinpath(patchdir, "link.patch")
4646
symlink("fix-windows-headers.patch", link)
4747
@test islink(link)
48-
sds = @test_logs (:info, r"^Directory .* found") download_source(ds; verbose = true)
48+
sds_follow = @test_logs (:info, r"^Directory .* found") download_source(ds_follow; verbose = true)
49+
# Try to fetch a non-existing directory
50+
@test_throws ErrorException download_source(DirectorySource(joinpath(dir, "does_not_exist")); verbose = true)
51+
# Another directory source, which doesn't follow symlinks
52+
ds_nofollow = DirectorySource("./bundled_nofollow")
53+
patchdir = abspath(joinpath(dir, ds_nofollow.path, "patches_nofollow"))
54+
mkpath(patchdir)
55+
write(abspath(joinpath(patchdir, "fix-windows-headers.patch")), "This is a patch file")
56+
# Create a symlink. We'll want to check that `setup` follows symlinks
57+
link = joinpath(patchdir, "link.patch")
58+
symlink("fix-windows-headers.patch", link)
59+
@test islink(link)
60+
sds_nofollow = @test_logs (:info, r"^Directory .* found") download_source(ds_nofollow; verbose = true)
4961
# Try to fetch a non-existing directory
5062
@test_throws ErrorException download_source(DirectorySource(joinpath(dir, "does_not_exist")); verbose = true)
5163

@@ -60,21 +72,29 @@ using JSON
6072
target = joinpath(srcdir, gs.unpack_target)
6173
@test_logs (:info, "Cloning ARCHDefs.git to ARCHDefs...") setup(sgs, target, true)
6274
@test isdir(target)
63-
target = abspath(joinpath(srcdir, "patches"))
64-
@test_logs (:info, "Copying content of bundled in srcdir...") setup(sds, srcdir, true)
75+
# Setup directory source with links to follow
76+
target = abspath(joinpath(srcdir, "patches_follow"))
77+
@test_logs (:info, "Copying content of bundled_follow in srcdir...") setup(sds_follow, srcdir, true)
6578
@test isdir(target)
6679
# Make sure that the symlinks are followed
6780
@test isfile(joinpath(target, "link.patch"))
6881
@test !islink(joinpath(target, "link.patch"))
82+
# Setup directory source with links to not follow
83+
target = abspath(joinpath(srcdir, "patches_nofollow"))
84+
@test_logs (:info, "Copying content of bundled_nofollow in srcdir...") setup(sds_nofollow, srcdir, true)
85+
@test isdir(target)
86+
# Make sure that the symlinks are not followed
87+
@test isfile(joinpath(target, "link.patch"))
88+
@test islink(joinpath(target, "link.patch"))
6989

7090
# Make sure in srcdir there are all files and directories we expect
71-
@test Set(readdir(srcdir)) == Set(["ARCHDefs", "ARCHDefs-2.0.3x", fs.filename, "patches"])
91+
@test Set(readdir(srcdir)) == Set(["ARCHDefs", "ARCHDefs-2.0.3x", fs.filename, "patches_follow", "patches_nofollow"])
7292

7393
# Setup the sources with `setup_workspace`
7494
workspace = joinpath(dir, "workspace")
7595
mkpath(workspace)
76-
prefix = @test_logs (:info, r"^Copying") (:info, r"^Copying") (:info, r"^Cloning") setup_workspace(workspace, [sfs, sds, sgs]; verbose=true)
77-
@test Set(readdir(joinpath(prefix.path, "srcdir"))) == Set(["ARCHDefs", "file-source.tar.gz", "patches"])
96+
prefix = @test_logs (:info, r"^Copying") (:info, r"^Copying") (:info, r"^Copying") (:info, r"^Cloning") setup_workspace(workspace, [sfs, sds_follow, sds_nofollow, sgs]; verbose=true)
97+
@test Set(readdir(joinpath(prefix.path, "srcdir"))) == Set(["ARCHDefs", "file-source.tar.gz", "patches_follow", "patches_nofollow"])
7898
end
7999
end
80100
end
@@ -95,7 +115,7 @@ using JSON
95115
@test jgs == Dict("type" => "git", "url" => gs.url, "hash" => gs.hash, "unpack_target" => gs.unpack_target)
96116
@test sourcify(jgs) == gs
97117
jds = JSON.lower(ds)
98-
@test jds == Dict("type" => "directory", "path" => ds.path, "target" => "")
118+
@test jds == Dict("type" => "directory", "path" => ds.path, "target" => "", "follow_symlinks" => false)
99119
@test sourcify(jds) == ds
100120

101121
@test_throws ErrorException sourcify(Dict("type" => "error"))

0 commit comments

Comments
 (0)