Skip to content

Commit

Permalink
Improve conda_init script
Browse files Browse the repository at this point in the history
Implement more robust method for extracting conda install
location from interactive subshells. Redo order of logic for
places to search. Add '-v' flag for printing debug info.
  • Loading branch information
tsj5 committed Apr 24, 2020
1 parent 563886b commit 3cf9820
Showing 1 changed file with 92 additions and 39 deletions.
131 changes: 92 additions & 39 deletions src/conda/conda_init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,74 +4,127 @@
# non-interactive shell.
# The script is what's placed in ~/.bashrc by 'conda init bash';
# this doesn't get sourced by bash in non-interactive mode so we have to
# do it manually.
# do it manually. See https://github.com/conda/conda/issues/7980 .

# NOTE this has only been tested with conda 4.7.10 and later; I know earlier
# versions had things in different places.

# Try to determine where conda is
function find_conda {
_MDTF_CONDA_ROOT="$( conda info --base 2> /dev/null )"
if [[ $? -ne 0 || -z "$_MDTF_CONDA_ROOT" ]]; then
# see if env vars tell us anything
if [[ -n "$CONDA_EXE" ]]; then
_MDTF_CONDA_ROOT="$( cd "$(dirname "$CONDA_EXE")/.."; pwd -P )"
elif [[ -n "$_CONDA_ROOT" ]]; then
_MDTF_CONDA_ROOT="$_CONDA_ROOT"
else
_MDTF_CONDA_ROOT="" # failure
fi
fi
}

# parse aruments manually
_MDTF_CONDA_ROOT=""
_quiet=""
_TEMP_CONDA_ROOT=""
_TEMP_CONDA_EXE=""
_v=1
while (( "$#" )); do
case "$1" in
-v)
_v=2 # verbose output for debugging
shift 1
;;
-q)
_quiet="0" # suppress output
_v=0 # suppress output
shift 1
;;
-?*)
# passed the path to use on command line
_MDTF_CONDA_ROOT="$1"
?*)
# Assume nonempty input is user-specified CONDA_ROOT
if [ ! -d "$1" ]; then
echo "ERROR: \"$1\" not a directory" 1>&2
exit 1
fi
_TEMP_CONDA_ROOT="$1"
shift 1
;;
*) # Default case: No more options, so break out of the loop.
break
esac
done

if [[ -z "$_MDTF_CONDA_ROOT" ]]; then
find_conda
# if we got _TEMP_CONDA_ROOT from command line, see if that works
if [ -d "$_TEMP_CONDA_ROOT" ]; then
# let command line value override pre-existing _CONDA_ROOT, in case user
# is specifying personal vs. site installation of conda
if [[ $_v -eq 2 && -d "$_CONDA_ROOT" ]]; then
echo "WARNING: overriding ${_CONDA_ROOT} with ${_TEMP_CONDA_ROOT}" 1>&2
fi
_CONDA_ROOT="$_TEMP_CONDA_ROOT"
if [[ $_v -eq 2 && -x "$CONDA_EXE" ]]; then
echo "WARNING: user supplied CONDA_ROOT so unsetting existing CONDA_EXE" 1>&2
fi
CONDA_EXE=""
if [ $_v -eq 2 ]; then echo "CONDA_ROOT set from command line"; fi
fi
# if not, maybe we were run from an interactive shell and inherited the info
if [ ! -d "$_CONDA_ROOT" ]; then
if [ -x "$CONDA_EXE" ]; then
if [ $_v -eq 2 ]; then echo "CONDA_EXE set from environment"; fi
_TEMP_CONDA_ROOT="$( "$CONDA_EXE" info --base 2> /dev/null )"
else
_TEMP_CONDA_ROOT="$( conda info --base 2> /dev/null )"
fi
if [ -d "$_TEMP_CONDA_ROOT" ]; then
_CONDA_ROOT="$_TEMP_CONDA_ROOT"
if [ $_v -eq 2 ]; then echo "CONDA_ROOT set from environment"; fi
fi
fi
if [[ -z "$_MDTF_CONDA_ROOT" ]]; then
if [[ -z "$_quiet" ]]; then
echo "conda not found, sourcing ~/.bashrc"
# if not, run user's shell in interactive mode. Subshell output could have
# arbitrary text output in it, since user's init scripts may be setting prompt
# and generating output in any number of ways. We try to extract the paths by
# delimiting them with (hopefully uncommon) vertical tab characters (\v) and
# using awk to extract whatever text is found between those two field separators.
if [ ! -d "$_CONDA_ROOT" ]; then
if [ $_v -eq 2 ]; then echo "Setting conda from $SHELL -i"; fi
_TEMP_CONDA_ROOT=$( "$SHELL" -i -c "_temp=\$( conda info --base ) && echo \"\v\${_temp}\v\"" | awk 'BEGIN { FS = "\v" } ; { print $2 }' )
if [ $_v -eq 2 ]; then echo "Received CONDA_ROOT=\"${_TEMP_CONDA_ROOT}\""; fi
if [[ -d "$_TEMP_CONDA_ROOT" ]]; then
_CONDA_ROOT="$_TEMP_CONDA_ROOT"
if [ $_v -eq 2 ]; then echo "Found CONDA_ROOT"; fi
fi
if [[ -f "$HOME/.bashrc" ]]; then
source "$HOME/.bashrc"
_TEMP_CONDA_EXE="$( "$SHELL" -i -c "echo \"\v\${CONDA_EXE}\v\"" | awk 'BEGIN { FS = "\v" } ; { print $2 }' )"
if [ $_v -eq 2 ]; then echo "Received CONDA_EXE=\"${_TEMP_CONDA_EXE}\""; fi
if [[ ! -x "$CONDA_EXE" && -x "$_TEMP_CONDA_EXE" ]]; then
CONDA_EXE="$_TEMP_CONDA_EXE"
if [ $_v -eq 2 ]; then echo "Found CONDA_EXE"; fi
fi
fi
# found root but not exe
if [[ -d "$_CONDA_ROOT" && ! -x "$CONDA_EXE" ]]; then
if [ $_v -eq 2 ]; then echo "Looking for conda executable in ${_CONDA_ROOT}"; fi
if [ -x "${_CONDA_ROOT}/bin/conda" ]; then
CONDA_EXE="${_CONDA_ROOT}/bin/conda"
if [ $_v -eq 2 ]; then echo "Found CONDA_EXE"; fi
elif [ -x "${_CONDA_ROOT}/condabin/conda" ]; then
CONDA_EXE="${_CONDA_ROOT}/condabin/conda"
if [ $_v -eq 2 ]; then echo "Found CONDA_EXE"; fi
fi
find_conda
fi
if [[ -z "$_MDTF_CONDA_ROOT" ]]; then
echo "ERROR: still can't find conda"
# found exe but not root
if [[ -x "$CONDA_EXE" && ! -d "$_CONDA_ROOT" ]]; then
if [ $_v -eq 2 ]; then echo "Running $CONDA_EXE to find conda root"; fi
_TEMP_CONDA_ROOT="$( "$CONDA_EXE" info --base 2> /dev/null )"
if [ -d "$_TEMP_CONDA_ROOT" ]; then
_CONDA_ROOT="$_TEMP_CONDA_ROOT"
if [ $_v -eq 2 ]; then echo "Found CONDA_ROOT"; fi
fi
fi
export _CONDA_ROOT="$_MDTF_CONDA_ROOT"
export CONDA_EXE="${_CONDA_ROOT}/bin/conda"
export _CONDA_EXE="$CONDA_EXE"
if [[ -x "$CONDA_EXE" ]]; then
if [[ -z "$_quiet" ]]; then

if [[ -x "$CONDA_EXE" && -d "$_CONDA_ROOT" ]]; then
if [ $_v -ne 0 ]; then
# Conda env manager reads this output
echo "_CONDA_EXE=${CONDA_EXE}"
echo "_CONDA_ROOT=${_CONDA_ROOT}"
fi
# in case these weren't exported already
export _CONDA_ROOT="$_CONDA_ROOT"
export CONDA_EXE="$CONDA_EXE"
else
echo "ERROR: no conda executable at $CONDA_EXE"
if [ ! -d "$_CONDA_ROOT" ]; then
echo "ERROR: search for conda base dir failed (${_CONDA_ROOT})" 1>&2
fi
if [ ! -x "$CONDA_EXE" ]; then
echo "ERROR: search for conda executable failed (${CONDA_EXE})" 1>&2
fi
exit 1
fi

# assume we've found conda, now run Anaconda's init script
# finally run conda's init script
__conda_setup="$( $CONDA_EXE 'shell.bash' 'hook' 2> /dev/null )"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
Expand Down

0 comments on commit 3cf9820

Please sign in to comment.