Skip to content

Commit

Permalink
Add Sys.which and Sys.isexecutable (#552)
Browse files Browse the repository at this point in the history
  • Loading branch information
ararslan authored and martinholters committed Jun 5, 2018
1 parent 0cf4d7c commit 52b8a29
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 8 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ Currently, the `@compat` macro supports the following syntaxes:

* `Compat.qr` takes `pivot` as a `Val` _instance_ ([#22475]).

* `Compat.Sys.which` and `Compat.Sys.isexecutable` ([#26559], [#27298]).

* `Compat.rmul!` provides a subset of the functionality of `LinearAlgebra.rmul!` for
use with Julia 0.6 ([#25701], [#25812]).

Expand Down Expand Up @@ -633,8 +635,10 @@ includes this fix. Find the minimum version from there.
[#26436]: https://github.com/JuliaLang/julia/issues/26436
[#26442]: https://github.com/JuliaLang/julia/issues/26442
[#26486]: https://github.com/JuliaLang/julia/issues/26486
[#26559]: https://github.com/JuliaLang/julia/issues/26559
[#26660]: https://github.com/JuliaLang/julia/issues/26660
[#26670]: https://github.com/JuliaLang/julia/issues/26670
[#26850]: https://github.com/JuliaLang/julia/issues/26850
[#27077]: https://github.com/JuliaLang/julia/issues/27077
[#27258]: https://github.com/JuliaLang/julia/issues/27258
[#27258]: https://github.com/JuliaLang/julia/issues/27258
[#27298]: https://github.com/JuliaLang/julia/issues/27298
64 changes: 57 additions & 7 deletions src/Compat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,13 @@ end
# https://github.com/JuliaLang/julia/pull/21746
const macros_have_sourceloc = VERSION >= v"0.7-" && length(:(@test).args) == 2

# 0.7.0-DEV.3155
@static if !isdefined(Base, :pushfirst!)
const pushfirst! = unshift!
const popfirst! = shift!
export pushfirst!, popfirst!
end

# https://github.com/JuliaLang/julia/pull/22182
module Sys
const KERNEL = Base.Sys.KERNEL
Expand All @@ -455,6 +462,56 @@ module Sys
import Base.Sys: isapple, isbsd, islinux, isunix, iswindows
end

@static if VERSION < v"0.7.0-DEV.5171"
using ..Compat: pushfirst!

function isexecutable(path::AbstractString)
if iswindows()
isfile(path)
else
ccall(:access, Cint, (Ptr{UInt8}, Cint), path, 0x01) == 0
end
end

function which(program::AbstractString)
progs = String[]
base = basename(program)
if iswindows()
isempty(last(splitext(base))) || push!(progs, base)
for p = [".exe", ".com"]
push!(progs, base * p)
end
else
push!(progs, base)
end
dirs = String[]
dir = dirname(program)
if isempty(dir)
pathsep = iswindows() ? ';' : ':'
append!(dirs, map(abspath, split(get(ENV, "PATH", ""), pathsep)))
iswindows() && pushfirst!(dirs, pwd())
else
push!(dirs, abspath(dir))
end
for d in dirs, p in progs
path = joinpath(d, p)
isexecutable(path) && return realpath(path)
end
nothing
end
elseif VERSION < v"0.7.0-alpha.6"
import Base.Sys: isexecutable

which(program::AbstractString) = try
Base.Sys.which(program)
catch err
err isa ErrorException || rethrow(err)
nothing
end
else
import Base.Sys: which, isexecutable
end

# https://github.com/JuliaLang/julia/pull/25102
# NOTE: This needs to be in an __init__ because JULIA_HOME is not
# defined when building system images.
Expand Down Expand Up @@ -1130,13 +1187,6 @@ else
import Base: notnothing
end

# 0.7.0-DEV.3155
@static if !isdefined(Base, :pushfirst!)
const pushfirst! = unshift!
const popfirst! = shift!
export pushfirst!, popfirst!
end

# 0.7.0-DEV.3309
@static if VERSION < v"0.7.0-DEV.3309"
const IteratorSize = Base.iteratorsize
Expand Down
10 changes: 10 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1756,4 +1756,14 @@ end
@test something(Some(2), 1) === 2
@test something(nothing, Some(1)) === 1

# 0.7.0-DEV.5171
let sep = Compat.Sys.iswindows() ? ';' : ':'
withenv("PATH" => string(Compat.Sys.BINDIR, sep, get(ENV, "PATH", ""))) do
jl = joinpath(Compat.Sys.BINDIR, "julia") * (Compat.Sys.iswindows() ? ".exe" : "")
@test Compat.Sys.which("julia") == realpath(jl)
@test Compat.Sys.isexecutable(jl)
@test Compat.Sys.which("reallyseriouslynotathingyoushouldhave") === nothing
end
end

nothing

0 comments on commit 52b8a29

Please sign in to comment.