I'm trying to get autoactivation of conda/mamba environments working using direnv but I'm running across a problem that seems to be due to my lack of understanding of how bash scripts work with environment variables.
My shell is fish but direnv is bash based. I don't think my shell being fish has any bearing on the problem since I run the appropriate direnv hook for fish.
My .direnvrc
file is as follows:
layout_mamba() {
local MAMBA_EXE="${HOME}/bin/micromamba" # Make sure this points to path of your micromamba executable
# initialize micromamba
eval "$(${MAMBA_EXE} shell hook --shell=bash)"
if [ -n "$1" ]; then
# Explicit environment name from layout command.
local env_name="$1"
micromamba activate ${env_name}
elif (grep -q name: environment.yml); then
# Detect environment name from `environment.yml` file in `.envrc` directory
micromamba activate `grep name: environment.yml | sed -e 's/name: //'`
else
(>&2 echo No environment specified);
exit 1;
fi;
}
And it works as is but notice that in my eval
statement, I use the value of $MAMBA_EXE
but the remaining calls micromamba
directly. Everything that I've tried for substituting $MAMBA_EXE for micromamba has failed.
Any suggestions for making my .direnvrc
more general?
Edit: For example, if I change line 8 from micromamba activate ${env_name}
to ${MAMBA_EXE} activate ${env_name}
I get:
direnv: loading ~/test-env/.envrc
'micromamba' is running as a subprocess and can't modify the parent shell.
Thus you must initialize your shell before using activate and deactivate.
To initialize the current bash shell, run:
$ eval "$(micromamba shell hook --shell=bash)"
and then activate or deactivate with:
$ micromamba activate
To automatically initialize all future (bash) shells, run:
$ micromamba shell init --shell=bash --prefix=~/micromamba
Supported shells are {bash, zsh, csh, xonsh, cmd.exe, powershell, fish}.
critical libmamba Shell not initialized
Fish won't let me run ${MAMBA_EXE} shell hook --shell=bash
but running $MAMBA_EXE shell hook --shell=bash
produces:
# Copyright (C) 2012 Anaconda, Inc
# SPDX-License-Identifier: BSD-3-Clause
__mamba_exe() (
"$MAMBA_EXE" "$@"
)
__mamba_hashr() {
if [ -n "${ZSH_VERSION:+x}" ]; then
\rehash
elif [ -n "${POSH_VERSION:+x}" ]; then
: # pass
else
\hash -r
fi
}
__mamba_activate() {
\local ask_conda
ask_conda="$(PS1="${PS1:-}" __mamba_exe shell --shell bash "$@")" || \return
\eval "$ask_conda"
__mamba_hashr
}
__mamba_reactivate() {
\local ask_conda
ask_conda="$(PS1="${PS1:-}" __mamba_exe shell --shell bash reactivate)" || \return
\eval "$ask_conda"
__mamba_hashr
}
micromamba() {
\local cmd="${1-__missing__}"
case "$cmd" in
activate|deactivate)
__mamba_activate "$@"
;;
install|update|upgrade|remove|uninstall)
__mamba_exe "$@" || \return
__mamba_reactivate
;;
self-update)
__mamba_exe "$@" || \return
# remove leftover backup file on Windows
if [ -f "$MAMBA_EXE.bkup" ]; then
rm -f $MAMBA_EXE.bkup
fi
;;
*)
__mamba_exe "$@"
;;
esac
}
if [ -z "${CONDA_SHLVL+x}" ]; then
\export CONDA_SHLVL=0
# In dev-mode MAMBA_EXE is python.exe and on Windows
# it is in a different relative location to condabin.
if [ -n "${_CE_CONDA+x}" ] && [ -n "${WINDIR+x}" ]; then
PATH="${MAMBA_ROOT_PREFIX}/condabin:${PATH}"
else
PATH="${MAMBA_ROOT_PREFIX}/condabin:${PATH}"
fi
\export PATH
# We're not allowing PS1 to be unbound. It must at least be set.
# However, we're not exporting it, which can cause problems when starting a second shell
# via a first shell (i.e. starting zsh from bash).
if [ -z "${PS1+x}" ]; then
PS1=
fi
fi
if [ -n "${ZSH_VERSION:+x}" ]; then
if ! command -v compinit > /dev/null; then
autoload -U +X compinit && if [[ "${ZSH_DISABLE_COMPFIX-}" = true ]]; then
compinit -u
else
compinit
fi
fi
autoload -U +X bashcompinit && bashcompinit
_umamba_zsh_completions()
{
COMPREPLY=($(__mamba_exe completer "${(@s: :)${(@s: :)COMP_LINE}:1}"))
}
complete -o default -F _umamba_zsh_completions micromamba
fi
if [ -n "${BASH_VERSION:+x}" ]; then
_umamba_bash_completions()
{
COMPREPLY=($(__mamba_exe completer "${COMP_WORDS[@]:1}"))
}
complete -o default -F _umamba_bash_completions micromamba
fi
${HOME}/bin
isn't in$PATH
and you have to give the full path manually when running it? Except that you say it works in both cases, so...?${MAMBA_EXE} shell hook --shell=bash
outputs. Thateval
command would run that output in the shell, so if it e.g. prints a modifiedPATH
, that would take effect there.$MAMBA_EXE
doesn't work, if the var contains the path to the external executable. So, you said "if I change line 8 frommicromamba activate ${env_name}
to${MAMBA_EXE} activate ${env_name}
", but is there some reason to make that change? If it works withmicromamba
, and that looks better, then shouldn't that do?