0

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
7
  • Suggestions? Yeah: Any time you write "everything I tried has failed" when asking people for help, it helps to go back and show at least some of those things you have tried, and what went wrong with each of them. It in people not having to suggest the same things again, and you in not having to read suggestions of the same things you've already tried. Also, I'm not exactly sure what is you're trying to achieve here? ${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...?
    – ilkkachu
    Mar 8, 2023 at 20:17
  • Another thing to look at is what ${MAMBA_EXE} shell hook --shell=bash outputs. That eval command would run that output in the shell, so if it e.g. prints a modified PATH, that would take effect there.
    – ilkkachu
    Mar 8, 2023 at 20:29
  • Added an example of something I've tried as well as the output (from within a fish shell) of the output from the shell hook command.
    – zoof
    Mar 8, 2023 at 21:59
  • 1
    Right, it installs a function, because it makes changes to the shell itself. Which is also why running $MAMBA_EXE doesn't work, if the var contains the path to the external executable. So, you said "if I change line 8 from micromamba activate ${env_name} to ${MAMBA_EXE} activate ${env_name}", but is there some reason to make that change? If it works with micromamba, and that looks better, then shouldn't that do?
    – ilkkachu
    Mar 9, 2023 at 8:05
  • Though noting there's some autocompletion related stuff there, I don't think a Bash script can install those into your fish shell (if I got it right that your interactive shell is fish, but the tool here is in Bash). Well, as you note, I'm not that familiar with direnv or micromamba, even if I know something about the shell, so feel free to ignore me if I'm completely lost...
    – ilkkachu
    Mar 9, 2023 at 8:07

0

You must log in to answer this question.

Browse other questions tagged .