Skip to content

Commit

Permalink
add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kalefranz committed Apr 13, 2017
1 parent 89d1c21 commit f7cfa1c
Show file tree
Hide file tree
Showing 9 changed files with 422 additions and 56 deletions.
87 changes: 62 additions & 25 deletions conda/activate.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ def iteritems(d, **kw):
return iter(d.items(**kw))


def identity(x):
return x


def expand(path):
return abspath(expanduser(expandvars(path)))

Expand All @@ -36,13 +40,13 @@ def __init__(self, shell):
self.context = context

if shell == 'posix':
self.pathsep = os.pathsep
self.path_convert = lambda path: path
self.pathsep = ':'
self.path_convert = identity
self.script_extension = '.sh'

self.unset_var_tmpl = 'unset %s'
self.set_var_tmpl = 'export %s="%s"'
self.run_script_tmpl = 'source "%s"'
self.run_script_tmpl = '. "%s"'

else:
raise NotImplementedError()
Expand All @@ -57,21 +61,36 @@ def reactivate(self):
return '\n'.join(self._make_commands(self.build_reactivate()))

def build_activate(self, name_or_prefix):
from .base.context import locate_prefix_by_name
if isdir(expand(name_or_prefix)) or re.search(r'\\|/', name_or_prefix):
test_path = expand(name_or_prefix)
if isdir(test_path):
prefix = test_path
if not isdir(join(prefix, 'conda-meta')):
from .exceptions import EnvironmentLocationNotFound
raise EnvironmentLocationNotFound(prefix)
elif re.search(r'\\|/', name_or_prefix):
prefix = name_or_prefix
if not isdir(join(prefix, 'conda-meta')):
from .exceptions import EnvironmentLocationNotFound
raise EnvironmentLocationNotFound(prefix)
else:
from .base.context import locate_prefix_by_name
prefix = locate_prefix_by_name(self.context, name_or_prefix)
conda_default_env = self._default_env(prefix)
conda_prompt_modifier = self._prompt_modifier(conda_default_env)

# query environment
old_conda_shlvl = int(os.getenv('CONDA_SHLVL', 0))
old_conda_prefix = os.getenv('CONDA_PREFIX')
old_path = os.environ['PATH']

if old_conda_prefix == prefix:
return self.build_reactivate()
elif old_conda_shlvl == 2 and os.getenv('CONDA_PREFIX_1') == prefix:
return self.build_deactivate()

activate_scripts = glob(join(
prefix, 'etc', 'conda', 'activate.d', '*' + self.script_extension
))
conda_default_env = self._default_env(prefix)
conda_prompt_modifier = self._prompt_modifier(conda_default_env)

if old_conda_shlvl == 0:
set_vars = {
Expand Down Expand Up @@ -108,19 +127,21 @@ def build_activate(self, name_or_prefix):
raise NotImplementedError()

return {
'unset_vars': (),
'set_vars': set_vars,
'deactivate_scripts': deactivate_scripts,
'activate_scripts': activate_scripts,
}

def build_deactivate(self):
# query environment
old_conda_shlvl = int(os.getenv('CONDA_SHLVL', 0))
new_conda_shlvl = old_conda_shlvl - 1
old_path = os.environ['PATH']
old_conda_prefix = os.environ['CONDA_PREFIX']
new_path = self._remove_prefix_from_path(os.environ['PATH'], old_conda_prefix)
deactivate_scripts = glob(join(
old_conda_prefix, 'etc', 'conda', 'deactivate.d', '*' + self.script_extension
))
deactivate_scripts = self._get_deactivate_scripts(old_conda_prefix)

new_conda_shlvl = old_conda_shlvl - 1
new_path = self._remove_prefix_from_path(old_path, old_conda_prefix)

if old_conda_shlvl == 1:
# TODO: warn conda floor
Expand All @@ -134,6 +155,7 @@ def build_deactivate(self):
'PATH': new_path,
'CONDA_SHLVL': new_conda_shlvl,
}
activate_scripts = ()
elif old_conda_shlvl == 2:
new_prefix = os.getenv('CONDA_PREFIX_%d' % new_conda_shlvl)
conda_default_env = self._default_env(new_prefix)
Expand All @@ -149,26 +171,24 @@ def build_deactivate(self):
'CONDA_DEFAULT_ENV': conda_default_env,
'CONDA_PROMPT_MODIFIER': conda_prompt_modifier,
}
activate_scripts = self._get_activate_scripts(new_prefix)
else:
raise NotImplementedError()

return {
'unset_vars': unset_vars,
'set_vars': set_vars,
'deactivate_scripts': deactivate_scripts,
'activate_scripts': activate_scripts,
}

def build_reactivate(self):
conda_prefix = os.environ['CONDA_PREFIX']
deactivate_scripts = glob(join(
conda_prefix, 'etc', 'conda', 'deactivate.d', '*' + self.script_extension
))
activate_scripts = glob(join(
conda_prefix, 'etc', 'conda', 'activate.d', '*' + self.script_extension
))
return {
'deactivate_scripts': deactivate_scripts,
'activate_scripts': activate_scripts,
'unset_vars': (),
'set_vars': {},
'deactivate_scripts': self._get_deactivate_scripts(conda_prefix),
'activate_scripts': self._get_activate_scripts(conda_prefix),
}

def _get_path_dirs(self, prefix):
Expand All @@ -189,13 +209,17 @@ def _add_prefix_to_path(self, old_path, prefix):
))

def _remove_prefix_from_path(self, current_path, prefix):
_prefix_paths = re.escape(self.pathsep.join(self._get_path_dirs(prefix)))
_prefix_paths = (re.escape(self.pathsep.join(self._get_path_dirs(prefix)))
+ r'%s?' % re.escape(self.pathsep))
return re.sub(_prefix_paths, r'', current_path, 1)

def _replace_prefix_in_path(self, current_path, old_prefix, new_prefix):
_old_prefix_paths = re.escape(self.pathsep.join(self._get_path_dirs(old_prefix)))
_new_prefix_paths = re.escape(self.pathsep.join(self._get_path_dirs(new_prefix)))
return re.sub(_old_prefix_paths, _new_prefix_paths, current_path, 1)
old_prefix_paths = self.pathsep.join(self._get_path_dirs(old_prefix))
if old_prefix_paths in current_path:
new_prefix_paths = self.pathsep.join(self._get_path_dirs(new_prefix))
return re.sub(re.escape(old_prefix_paths), new_prefix_paths, current_path, 1)
else:
return self._add_prefix_to_path(current_path, new_prefix)

def _default_env(self, prefix):
if prefix == self.context.root_prefix:
Expand All @@ -205,6 +229,16 @@ def _default_env(self, prefix):
def _prompt_modifier(self, conda_default_env):
return "(%s) " % conda_default_env if self.context.changeps1 else ""

def _get_activate_scripts(self, prefix):
return glob(join(
prefix, 'etc', 'conda', 'activate.d', '*' + self.script_extension
))

def _get_deactivate_scripts(self, prefix):
return glob(join(
prefix, 'etc', 'conda', 'deactivate.d', '*' + self.script_extension
))

def _make_commands(self, cmds_dict):
for key in cmds_dict.get('unset_vars', ()):
yield self.unset_var_tmpl % key
Expand All @@ -223,7 +257,10 @@ def main():
command = sys.argv[1]
shell = sys.argv[2]
activator = Activator(shell)
if command == 'shell.activate':
remainder_args = sys.argv[3:] if len(sys.argv[4]) else ()
if '-h' in remainder_args or '--help' in remainder_args:
pass
elif command == 'shell.activate':
name_or_prefix = sys.argv[3]
print(activator.activate(name_or_prefix))
elif command == 'shell.deactivate':
Expand Down
4 changes: 2 additions & 2 deletions conda/base/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
SequenceParameter, ValidationError)
from ..common.disk import conda_bld_ensure_dir
from ..common.url import has_scheme, path_to_url, split_scheme_auth_token
from ..exceptions import CondaEnvironmentNotFoundError, CondaValueError
from ..exceptions import CondaValueError, EnvironmentNameNotFound

try:
from cytoolz.itertoolz import concat, concatv, unique
Expand Down Expand Up @@ -740,7 +740,7 @@ def locate_prefix_by_name(ctx, name):
if isdir(prefix):
return prefix

raise CondaEnvironmentNotFoundError(name)
raise EnvironmentNameNotFound(name)


try:
Expand Down
13 changes: 6 additions & 7 deletions conda/cli/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@
from ..common.compat import on_win, text_type
from ..core.index import get_index
from ..core.linked_data import linked as install_linked
from ..exceptions import (CondaEnvironmentNotFoundError,
CondaIOError, CondaImportError, CondaOSError,
CondaRuntimeError, CondaSystemExit, CondaValueError,
DirectoryNotFoundError, DryRunExit, LockError, NoPackagesFoundError,
PackageNotFoundError, TooManyArgumentsError, UnsatisfiableError,
PackageNotInstalledError)
from ..exceptions import (CondaIOError, CondaImportError, CondaOSError, CondaRuntimeError,
CondaSystemExit, CondaValueError, DirectoryNotFoundError, DryRunExit,
EnvironmentLocationNotFound, LockError, NoPackagesFoundError,
PackageNotFoundError, PackageNotInstalledError, TooManyArgumentsError,
UnsatisfiableError)
from ..misc import append_env, clone_env, explicit, touch_nonadmin
from ..models.channel import prioritize_channels
from ..plan import (display_actions, execute_actions, get_pinned_specs, install_actions_list,
Expand Down Expand Up @@ -236,7 +235,7 @@ def install(args, parser, command='install'):
except OSError:
raise CondaOSError("Error: could not create directory: %s" % prefix)
else:
raise CondaEnvironmentNotFoundError(prefix)
raise EnvironmentLocationNotFound(prefix)

try:
if isinstall and args.revision:
Expand Down
6 changes: 3 additions & 3 deletions conda/cli/main_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from ..common.compat import text_type
from ..core.linked_data import is_linked, linked, linked_data
from ..egg_info import get_egg_info
from ..exceptions import CondaEnvironmentNotFoundError, CondaFileNotFoundError
from ..exceptions import CondaFileNotFoundError, EnvironmentLocationNotFound

descr = "List linked packages in a conda environment."

Expand Down Expand Up @@ -154,7 +154,7 @@ def list_packages(prefix, installed, regex=None, format='human',
def print_packages(prefix, regex=None, format='human', piplist=False,
json=False, show_channel_urls=context.show_channel_urls):
if not isdir(prefix):
raise CondaEnvironmentNotFoundError(prefix)
raise EnvironmentLocationNotFound(prefix)

if not json:
if format == 'human':
Expand All @@ -181,7 +181,7 @@ def print_packages(prefix, regex=None, format='human', piplist=False,

def print_explicit(prefix, add_md5=False):
if not isdir(prefix):
raise CondaEnvironmentNotFoundError(prefix)
raise EnvironmentLocationNotFound(prefix)
print_export_header()
print("@EXPLICIT")
for meta in sorted(linked_data(prefix).values(), key=lambda x: x['name']):
Expand Down
23 changes: 12 additions & 11 deletions conda/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,18 +202,19 @@ def __init__(self, directory):
super(DirectoryNotFoundError, self).__init__(msg)


class CondaEnvironmentNotFoundError(CondaError, EnvironmentError):
""" Raised when a requested environment cannot be found.
class EnvironmentLocationNotFound(CondaError):
def __init__(self, location):
message = "Not a conda environment: %(location)s"
super(EnvironmentLocationNotFound, self).__init__(message, location=location)

args:
environment_name_or_prefix (str): either the name or location of an environment
"""
def __init__(self, environment_name_or_prefix, *args, **kwargs):
msg = ("Could not find environment: %s .\n"
"You can list all discoverable environments with `conda info --envs`."
% environment_name_or_prefix)
self.environment_name_or_prefix = environment_name_or_prefix
super(CondaEnvironmentNotFoundError, self).__init__(msg, *args, **kwargs)

class EnvironmentNameNotFound(CondaError):
def __init__(self, environment_name):
message = dals("""
Could not find conda environment: %(environment_name)s
You can list all discoverable environments with `conda info --envs`.
""")
super(EnvironmentNameNotFound, self).__init__(message, environment_name=environment_name)


class CondaEnvironmentError(CondaError, EnvironmentError):
Expand Down
1 change: 1 addition & 0 deletions conda/gateways/disk/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ def mkdir_p(path):
log.trace('making directory %s', path)
if path:
makedirs(path)
return isdir(path) and path
except OSError as e:
if e.errno == EEXIST and isdir(path):
return path
Expand Down
22 changes: 16 additions & 6 deletions shell/conda.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
if [[ -n $BASH_VERSION ]]; then
_SCRIPT_LOCATION=${BASH_SOURCE[0]}
elif [[ -n $ZSH_VERSION ]]; then
_SCRIPT_LOCATION=${funcstack[1]}
# Ensure that this script is sourced, not executed
if [ "$_" = "$0" ]; then
(>&2 echo "This script must be sourced, not executed.")
exit 1
fi

if [ -n "$BASH_VERSION" ]; then
_SCRIPT_DIR="$(dirname ${BASH_SOURCE[0]})"
elif [ -n "$ZSH_VERSION" ]; then
_SCRIPT_DIR="$(dirname ${funcstack[1]})"
elif [ -n "$KSH_VERSION" ]; then
_SCRIPT_DIR="$(cd $(dirname $_) && echo $PWD)"
else
echo "Only bash and zsh are supported"
return 1
fi
_SCRIPT_DIR="$(dirname $_SCRIPT_LOCATION)"
_CONDA_EXE="$_SCRIPT_DIR/../../bin/conda"


Expand All @@ -17,7 +24,10 @@ _conda_hashr() {


_conda_activate() {
eval "$($_CONDA_EXE shell.activate posix "$@")"
local ask_conda="$($_CONDA_EXE shell.activate posix "$@")"
if not $?; then
return $?
fi

if [ "$(echo "$PS1" | awk '{ string=substr($0, 1, 22); print string; }')" != '$CONDA_PROMPT_MODIFIER' ]; then
PS1='$CONDA_PROMPT_MODIFIER'"$PS1"
Expand Down
Loading

0 comments on commit f7cfa1c

Please sign in to comment.