Skip to content

Commit

Permalink
Add addenv(); a way to add new mappings into Cmd environment bloc…
Browse files Browse the repository at this point in the history
  • Loading branch information
staticfloat committed Sep 9, 2020
1 parent 94249f4 commit 18198b1
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 7 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ New library functions
for writing `(f(args...) for args in zip(iterators...))`, i.e. a lazy `map` ([#34352]).
* New function `sincospi` for simultaneously computing `sinpi(x)` and `cospi(x)` more
efficiently ([#35816]).
* New function `addenv` for adding environment mappings into a `Cmd` object, returning the new `Cmd` object.

New library features
--------------------
Expand Down
42 changes: 35 additions & 7 deletions base/cmd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ while changing the settings of the optional keyword arguments:
already open or on non-Windows systems.
* `env`: Set environment variables to use when running the `Cmd`. `env` is either a
dictionary mapping strings to strings, an array of strings of the form `"var=val"`, an
array or tuple of `"var"=>val` pairs, or `nothing`. In order to modify (rather than
replace) the existing environment, create `env` by `copy(ENV)` and then set
`env["var"]=val` as desired.
array or tuple of `"var"=>val` pairs. In order to modify (rather than replace) the
existing environment, initialize `env` with `copy(ENV)` and then set `env["var"]=val` as
desired. To add to an environment block within a `Cmd` object without replacing all
elements, use `addenv()` which will return a `Cmd` object with the updated environment.
* `dir::AbstractString`: Specify a working directory for the command (instead
of the current directory).
Expand Down Expand Up @@ -230,10 +231,10 @@ byteenv(env::Union{AbstractVector{Pair{T,V}}, Tuple{Vararg{Pair{T,V}}}}) where {
setenv(command::Cmd, env; dir="")
Set environment variables to use when running the given `command`. `env` is either a
dictionary mapping strings to strings, an array of strings of the form `"var=val"`, or zero
or more `"var"=>val` pair arguments. In order to modify (rather than replace) the existing
environment, create `env` by `copy(ENV)` and then setting `env["var"]=val` as desired, or
use `withenv`.
dictionary mapping strings to strings, an array of strings of the form `"var=val"`, or
zero or more `"var"=>val` pair arguments. In order to modify (rather than replace) the
existing environment, create `env` through `copy(ENV)` and then setting `env["var"]=val`
as desired, or use `addenv`.
The `dir` keyword argument can be used to specify a working directory for the command.
"""
Expand All @@ -242,6 +243,33 @@ setenv(cmd::Cmd, env::Pair{<:AbstractString}...; dir="") =
setenv(cmd, env; dir=dir)
setenv(cmd::Cmd; dir="") = Cmd(cmd; dir=dir)

"""
addenv(command::Cmd, env...)
Merge new environment mappings into the given `Cmd` object, returning a new `Cmd` object.
Duplicate keys are replaced.
"""
function addenv(cmd::Cmd, env::Dict)
new_env = Dict{String,String}()
if cmd.env !== nothing
for (k, v) in split.(cmd.env, "=")
new_env[string(k)::String] = string(v)::String
end
end
for (k, v) in env
new_env[string(k)::String] = string(v)::String
end
return setenv(cmd, new_env)
end

function addenv(cmd::Cmd, pairs::Pair{<:AbstractString}...)
return addenv(cmd, Dict(k => v for (k, v) in pairs))
end

function addenv(cmd::Cmd, env::Vector{<:AbstractString})
return addenv(cmd, Dict(k => v for (k, v) in split.(env, "=")))
end

(&)(left::AbstractCmd, right::AbstractCmd) = AndCmds(left, right)
redir_out(src::AbstractCmd, dest::AbstractCmd) = OrCmds(src, dest)
redir_err(src::AbstractCmd, dest::AbstractCmd) = ErrOrCmds(src, dest)
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,7 @@ export
process_running,
run,
setenv,
addenv,
success,
withenv,

Expand Down
13 changes: 13 additions & 0 deletions test/spawn.jl
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,19 @@ end
@test repr(Base.CmdRedirect(``, devnull, 11, true)) == "pipeline(``, 11<Base.DevNull())"


# Issue #37070
@testset "addenv()" begin
cmd = Cmd(`$shcmd -c "echo \$FOO \$BAR"`, env=Dict("FOO" => "foo"))
@test strip(String(read(cmd))) == "foo"
cmd = addenv(cmd, "BAR" => "bar")
@test strip(String(read(cmd))) == "foo bar"
cmd = addenv(cmd, Dict("FOO" => "bar"))
@test strip(String(read(cmd))) == "bar bar"
cmd = addenv(cmd, ["FOO=baz"])
@test strip(String(read(cmd))) == "baz bar"
end


# clean up busybox download
if Sys.iswindows()
rm(busybox, force=true)
Expand Down

0 comments on commit 18198b1

Please sign in to comment.