Skip to content
This repository was archived by the owner on Aug 16, 2023. It is now read-only.

Commit 799dc4d

Browse files
committed
Add withenv(), remove activate() and deactivate()
1 parent e6cfe4c commit 799dc4d

File tree

3 files changed

+37
-90
lines changed

3 files changed

+37
-90
lines changed

src/BinaryProvider.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ function __init__()
2323

2424
# Initialize our global_prefix
2525
global_prefix = Prefix(joinpath(dirname(@__FILE__), "../", "global_prefix"))
26-
activate(global_prefix)
2726

2827
# Find the right download/compression engines for this platform
2928
probe_platform_engines!()

src/Prefix.jl

Lines changed: 23 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## This file contains functionality related to the actual layout of the files
22
# on disk. Things like the name of where downloads are stored, and what
33
# environment variables must be updated to, etc...
4-
import Base: convert, joinpath, show
4+
import Base: convert, joinpath, show, withenv
55
using SHA
66

77
export Prefix, bindir, libdir, includedir, logdir, activate, deactivate,
@@ -92,33 +92,35 @@ joinpath(s::AbstractString, prefix::Prefix, args...) = joinpath(s, prefix.path,
9292
convert(::Type{AbstractString}, prefix::Prefix) = prefix.path
9393
show(io::IO, prefix::Prefix) = show(io, "Prefix($(prefix.path))")
9494

95-
"""
96-
split_PATH(PATH::AbstractString = ENV["PATH"])
9795

98-
Splits a string such as the `PATH` environment variable into a list of strings
99-
according to the path separation rules for the current platform.
10096
"""
101-
function split_PATH(PATH::AbstractString = ENV["PATH"])
102-
@static if Sys.iswindows()
103-
return split(PATH, ";")
104-
else
105-
return split(PATH, ":")
106-
end
107-
end
97+
withenv(f::Function, prefixes::Vector{Prefix})
10898
99+
Wrapper function designed to help executables find dynamic libraries and child
100+
binaries by wrapping PATH and (DY)LD_LIBRARY_PATH.
109101
"""
110-
join_PATH(PATH::Vector{AbstractString})
102+
function withenv(f::Function, prefixes::Vector{Prefix})
103+
# Join `dirs` to ENV[key], removing duplicates and nonexistent directories
104+
# as we go, normalizing directory names, splitting and joining by `sep`.
105+
function joinenv(key, dirs, sep)
106+
value = [dirs..., split(get(ENV, key, ""), sep)...]
107+
return join([abspath(d) for d in value if isdir(d)], sep)
108+
end
109+
# We're going to build up PATH and {DY,}LD_LIBRARY_PATH such that binaries
110+
# that use things from the given prefixes can function properly.
111+
sep = Sys.iswindows() ? ";" : ":"
112+
mapping = ["PATH" => joinenv("PATH", bindir.(prefixes), sep)]
111113

112-
Given a list of strings, return a joined string suitable for the `PATH`
113-
environment variable appropriate for the current platform.
114-
"""
115-
function join_PATH(paths::Vector{S}) where S<:AbstractString
116-
@static if Sys.iswindows()
117-
return join(paths, ";")
118-
else
119-
return join(paths, ":")
114+
# {DY,}LD_LIBRARY_PATH only makes sense on non-windows
115+
if !Sys.iswindows()
116+
envname = Sys.isapple() ? "DYLD_LIBRARY_PATH" : "LD_LIBRARY_PATH"
117+
push!(mapping, envname => joinenv(envname, libdir.(prefixes), ":"))
120118
end
119+
120+
# Use withenv to apply the calculated environment mappings to f.
121+
return withenv(f, mapping...)
121122
end
123+
withenv(f::Function, prefix::Prefix) = withenv(f, [prefix])
122124

123125
"""
124126
bindir(prefix::Prefix)
@@ -161,56 +163,6 @@ function logdir(prefix::Prefix)
161163
return joinpath(prefix, "logs")
162164
end
163165

164-
"""
165-
activate(prefix::Prefix)
166-
167-
Prepends paths to environment variables so that binaries and libraries are
168-
available to Julia.
169-
"""
170-
function activate(prefix::Prefix)
171-
# Add to PATH
172-
paths = split_PATH()
173-
if !(bindir(prefix) in paths)
174-
prepend!(paths, [bindir(prefix)])
175-
end
176-
ENV["PATH"] = join_PATH(paths)
177-
178-
# Add to DL_LOAD_PATH
179-
if !(libdir(prefix) in Libdl.DL_LOAD_PATH)
180-
prepend!(Libdl.DL_LOAD_PATH, [libdir(prefix)])
181-
end
182-
return nothing
183-
end
184-
185-
"""
186-
activate(func::Function, prefix::Prefix)
187-
188-
Prepends paths to environment variables so that binaries and libraries are
189-
available to Julia, calls the user function `func`, then `deactivate()`'s
190-
the `prefix`` again.
191-
"""
192-
function activate(func::Function, prefix::Prefix)
193-
activate(prefix)
194-
func()
195-
deactivate(prefix)
196-
end
197-
198-
"""
199-
deactivate(prefix::Prefix)
200-
201-
Removes paths added to environment variables by `activate()`
202-
"""
203-
function deactivate(prefix::Prefix)
204-
# Remove from PATH
205-
paths = split_PATH()
206-
filter!(p -> p != bindir(prefix), paths)
207-
ENV["PATH"] = join_PATH(paths)
208-
209-
# Remove from DL_LOAD_PATH
210-
filter!(p -> p != libdir(prefix), Libdl.DL_LOAD_PATH)
211-
return nothing
212-
end
213-
214166
"""
215167
extract_platform_key(path::AbstractString)
216168

test/runtests.jl

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -343,25 +343,21 @@ end
343343
end
344344
chmod(ppt_path, 0o775)
345345

346-
# Test that activation adds certain paths to our environment variables
347-
activate(prefix)
348-
349-
# PATH[1] should be "<prefix>/bin" now
350-
@test BinaryProvider.split_PATH()[1] == bindir(prefix)
351-
@test Libdl.DL_LOAD_PATH[1] == libdir(prefix)
352-
353-
# Test we can run the script we dropped within this prefix. Once again,
354-
# something about Windows | busybox | Julia won't pick this up even though
355-
# the path clearly points to the file. :(
356-
@static if !Sys.iswindows()
357-
@test success(sh(`$(ppt_path)`))
358-
@test success(sh(`prefix_path_test.sh`))
346+
# Test that our `withenv()` stuff works. :D
347+
withenv(prefix) do
348+
@test startswith(ENV["PATH"], bindir(prefix))
349+
350+
if !Sys.iswindows()
351+
envname = Sys.isapple() ? "DYLD_LIBRARY_PATH" : "LD_LIBRARY_PATH"
352+
@test startswith(ENV[envname], libdir(prefix))
353+
354+
# Test we can run the script we dropped within this prefix.
355+
# Once again, something about Windows | busybox | Julia won't
356+
# pick this up even though the path clearly points to the file.
357+
@test success(sh(`$(ppt_path)`))
358+
@test success(sh(`prefix_path_test.sh`))
359+
end
359360
end
360-
361-
# Now deactivate and make sure that all traces are gone
362-
deactivate(prefix)
363-
@test BinaryProvider.split_PATH()[1] != bindir(prefix)
364-
@test Libdl.DL_LOAD_PATH[1] != libdir(prefix)
365361

366362
# Test that we can control libdir() via platform arguments
367363
@test libdir(prefix, Linux(:x86_64)) == joinpath(prefix, "lib")

0 commit comments

Comments
 (0)