Skip to content

Commit

Permalink
Add the :execute method to activate! and withenv
Browse files Browse the repository at this point in the history
  • Loading branch information
frankier committed Dec 25, 2024
1 parent e27d20e commit a9bde31
Showing 1 changed file with 66 additions and 23 deletions.
89 changes: 66 additions & 23 deletions src/env.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,83 @@ This file defines functions for interacting with the environment, such as `withe
"""

"""
activate!(env)
activate!(env; method=:simple)
"Activate" the Conda environment by modifying the given dict of environment variables.
"Activate" the Conda environment by modifying the given dict of environment variables. When `method` is `:simple`, the environment variables corresponding to meaning any activation hooks provided by conda packages will not be run.
An experimental `method` of `:execute` is available. In this case, the Conda environment will be activated in a bash subshell, meaning all the activation hooks will be run. All environment variables updated or created in this subshell are then changed in the current process. This method requires `bash` to be available, and has only been tested on Linux.
"""
function activate!(e)
function activate!(e; method=:simple)
backend() in (:Null, :Current) && return e
old_path = get(e, "PATH", "")
d = envdir()
path_sep = Sys.iswindows() ? ';' : ':'
new_path = join(bindirs(), path_sep)
if backend() == :MicroMamba
e["MAMBA_ROOT_PREFIX"] = MicroMamba.root_dir()
new_path = "$(new_path)$(path_sep)$(dirname(MicroMamba.executable()))"
end
if old_path != ""
new_path = "$(new_path)$(path_sep)$(old_path)"
if method == :simple
old_path = get(e, "PATH", "")
d = envdir()
path_sep = Sys.iswindows() ? ';' : ':'
new_path = join(bindirs(), path_sep)
if backend() == :MicroMamba
e["MAMBA_ROOT_PREFIX"] = MicroMamba.root_dir()
new_path = "$(new_path)$(path_sep)$(dirname(MicroMamba.executable()))"
end
if old_path != ""
new_path = "$(new_path)$(path_sep)$(old_path)"
end
e["PATH"] = new_path
e["CONDA_PREFIX"] = d
e["CONDA_DEFAULT_ENV"] = d
e["CONDA_SHLVL"] = "1"
e["CONDA_PROMPT_MODIFIER"] = "($d) "
e
elseif method == :execute
d = envdir()
hook = join(conda_cmd(`shell hook -s bash -r $d`).exec, " ")
activate = join(conda_cmd(`shell activate -s bash -p $d`).exec, " ")
steps = [
"env",
"echo __65ab376884d7456ca97187d18a182250__",
"eval \"\$($hook)\"",
"eval \"\$($activate)\"",
"env"
]
steps = join(steps, " && ")
cmd = `bash --norc --noprofile -c $steps`
out = read(cmd, String)
before_env = []
after_env = []
is_before = true
for line in split(out, '\n')
if line == "__65ab376884d7456ca97187d18a182250__"
is_before = false
end
if occursin("=", line)
bits = split(line, '=', limit=2)
if is_before
push!(before_env, bits)
else
push!(after_env, bits)
end
end
end
for (k, v) in after_env
if haskey(e, k)
if e[k] != v
e[k] = v
end
else
e[k] = v
end
end
end
e["PATH"] = new_path
e["CONDA_PREFIX"] = d
e["CONDA_DEFAULT_ENV"] = d
e["CONDA_SHLVL"] = "1"
e["CONDA_PROMPT_MODIFIER"] = "($d) "
e
end

"""
withenv(f::Function)
withenv(f::Function, method=:simple)
Call `f()` while the Conda environment is active.
Call `f()` while the Conda environment is active. See `activate!()` for details of the `method` argument.
"""
function withenv(f::Function)
function withenv(f::Function; method=:simple)
old_env = copy(ENV)
# shell("activate")
activate!(ENV)
activate!(ENV; method=method)
frozen = STATE.frozen
STATE.frozen = true
try
Expand Down

0 comments on commit a9bde31

Please sign in to comment.