Skip to content

Commit

Permalink
Implement JuliaLang#24353 - Propegate cmd flags in interpolation (Jul…
Browse files Browse the repository at this point in the history
…iaLang#31768)

Too late for 1.2 for which this was originally marked, but nevertheless,
it's a quick change, so might as well get it in now and have it be available
in 1.3.

Fixes JuliaLang#24353
  • Loading branch information
Keno committed Apr 22, 2019
1 parent b8b6c20 commit f2fadb3
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ New library functions
Standard library changes
------------------------

* Cmd interpolation (``` `$(x::Cmd) a b c` ``` where) now propagates `x`'s process flags (environment, flags, working directory, etc) if `x` is the first interpolant and errors otherwise ([#24353]).

#### LinearAlgebra


Expand Down
29 changes: 25 additions & 4 deletions base/process.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ struct Cmd <: AbstractCmd
end
end

has_nondefault_cmd_flags(c::Cmd) =
c.ignorestatus ||
c.flags != 0x00 ||
c.env !== nothing ||
c.dir !== ""

"""
Cmd(cmd::Cmd; ignorestatus, detach, windows_verbatim, windows_hide, env, dir)
Expand Down Expand Up @@ -901,7 +907,12 @@ end

arg_gen() = String[]
arg_gen(x::AbstractString) = String[cstr(x)]
arg_gen(cmd::Cmd) = cmd.exec
function arg_gen(cmd::Cmd)
if has_nondefault_cmd_flags(cmd)
throw(ArgumentError("Non-default environment behavior is only permitted for the first interpolant."))
end
cmd.exec
end

function arg_gen(head)
if isiterable(typeof(head))
Expand All @@ -927,10 +938,20 @@ end

function cmd_gen(parsed)
args = String[]
for arg in parsed
append!(args, arg_gen(arg...))
if length(parsed) >= 1 && isa(parsed[1], Tuple{Cmd})
cmd = parsed[1][1]
(ignorestatus, flags, env, dir) = (cmd.ignorestatus, cmd.flags, cmd.env, cmd.dir)
append!(args, cmd.exec)
for arg in tail(parsed)
append!(args, arg_gen(arg...))
end
return Cmd(Cmd(args), ignorestatus, flags, env, dir)
else
for arg in parsed
append!(args, arg_gen(arg...))
end
return Cmd(args)
end
return Cmd(args)
end

"""
Expand Down
9 changes: 9 additions & 0 deletions test/spawn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,15 @@ end
@test Set([``, echocmd]) != Set([``, ``])
@test Set([echocmd, ``, ``, echocmd]) == Set([echocmd, ``])

# test for interpolation of Cmd
let c = setenv(`x`, "A"=>true)
@test (`$c a`).env == String["A=true"]
@test (`"$c" a`).env == String["A=true"]
@test_throws ArgumentError `a $c`
@test (`$(c.exec) a`).env === nothing
@test_throws ArgumentError `"$c "`
end

# equality tests for AndCmds
@test Base.AndCmds(`$echocmd abc`, `$echocmd def`) == Base.AndCmds(`$echocmd abc`, `$echocmd def`)
@test Base.AndCmds(`$echocmd abc`, `$echocmd def`) != Base.AndCmds(`$echocmd abc`, `$echocmd xyz`)
Expand Down

0 comments on commit f2fadb3

Please sign in to comment.