Skip to content

Commit

Permalink
Merge pull request #116 from Anaconda-Platform/config_envs_path
Browse files Browse the repository at this point in the history
Config envs path
  • Loading branch information
fpliger committed Oct 3, 2017
2 parents a804767 + 2fb8648 commit 3edfd4e
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 13 deletions.
4 changes: 3 additions & 1 deletion anaconda_project/env_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,9 @@ def inherit_from_names(self):

def path(self, project_dir):
"""The filesystem path to the default conda env containing our packages."""
return os.path.join(project_dir, "envs", self.name)
envs_path = os.environ.get('ANACONDA_PROJECT_ENVS_PATH', os.path.join(project_dir, "envs"))

return os.path.join(envs_path, self.name)

def diff_from(self, old):
"""A string showing the comparison between this env spec and another one."""
Expand Down
4 changes: 3 additions & 1 deletion anaconda_project/project_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -1664,7 +1664,9 @@ def cleanup_dir(dirname):
errors.append("Error removing %s: %s." % (dirname, str(e)))

cleanup_dir(os.path.join(project.directory_path, "services"))
cleanup_dir(os.path.join(project.directory_path, "envs"))

envs_path = os.environ.get('ANACONDA_PROJECT_ENVS_PATH', os.path.join(project.directory_path, "envs"))
cleanup_dir(envs_path)

if status and len(errors) == 0:
return SimpleStatus(success=True, description="Cleaned.", errors=errors)
Expand Down
102 changes: 91 additions & 11 deletions anaconda_project/test/test_project_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -3345,12 +3345,78 @@ def check(dirname):
"""}, check)


def check_cleaned(dirname, envs_dirname="envs"):
project = Project(dirname, frontend=FakeFrontend())

result = prepare.prepare_without_interaction(project, env_spec_name='foo')

assert result
envs_dir = os.path.join(dirname, envs_dirname)
assert os.path.isdir(os.path.join(envs_dir, "foo"))

# prepare again with 'bar' this time
result = prepare.prepare_without_interaction(project, env_spec_name='bar')
assert result
bar_dir = os.path.join(dirname, envs_dirname, "bar")
assert os.path.isdir(bar_dir)

# we don't really have a service in the test project file because
# redis-server doesn't work on Windows and it's good to run this
# test on Windows. So create some fake junk in services dir.
services_dir = os.path.join(dirname, "services")
os.makedirs(os.path.join(services_dir, "leftover-debris"))

status = project_ops.clean(project, result)
assert status
assert status.status_description == "Cleaned."
assert project.frontend.logs == [("Deleted environment files in %s." % bar_dir), ("Removing %s." % services_dir),
("Removing %s." % envs_dir)]
assert status.errors == []

assert not os.path.isdir(os.path.join(dirname, envs_dirname))
assert not os.path.isdir(os.path.join(dirname, "services"))


def test_clean(monkeypatch):
def mock_create(prefix, pkgs, channels, stdout_callback, stderr_callback):
os.makedirs(os.path.join(prefix, "conda-meta"))

monkeypatch.setattr('anaconda_project.internal.conda_api.create', mock_create)

with_directory_contents_completing_project_file(
{DEFAULT_PROJECT_FILENAME: """
env_specs:
foo: {}
bar: {}
"""}, check_cleaned)


def test_clean_from_environ(monkeypatch):
def mock_create(prefix, pkgs, channels, stdout_callback, stderr_callback):
os.makedirs(os.path.join(prefix, "conda-meta"))

monkeypatch.setattr('anaconda_project.internal.conda_api.create', mock_create)

def check(dirname):
os.environ['ANACONDA_PROJECT_ENVS_PATH'] = os.path.join(dirname, "some_random_path")
res = check_cleaned(dirname, "some_random_path")
os.environ.pop('ANACONDA_PROJECT_ENVS_PATH')
return res

with_directory_contents_completing_project_file(
{DEFAULT_PROJECT_FILENAME: """
env_specs:
foo: {}
bar: {}
"""}, check)


def test_clean_failed_delete(monkeypatch):
def mock_create(prefix, pkgs, channels, stdout_callback, stderr_callback):
os.makedirs(os.path.join(prefix, "conda-meta"))

monkeypatch.setattr('anaconda_project.internal.conda_api.create', mock_create)

def check(dirname):
project = Project(dirname, frontend=FakeFrontend())

Expand All @@ -3361,6 +3427,7 @@ def check(dirname):
assert os.path.isdir(os.path.join(envs_dir, "foo"))

# prepare again with 'bar' this time
project.frontend.reset()
result = prepare.prepare_without_interaction(project, env_spec_name='bar')
assert result
bar_dir = os.path.join(dirname, "envs", "bar")
Expand All @@ -3372,15 +3439,25 @@ def check(dirname):
services_dir = os.path.join(dirname, "services")
os.makedirs(os.path.join(services_dir, "leftover-debris"))

def mock_rmtree(path, onerror=None):
raise IOError("No rmtree here")

monkeypatch.setattr('shutil.rmtree', mock_rmtree)

project.frontend.reset()
status = project_ops.clean(project, result)
assert status
assert status.status_description == "Cleaned."
assert project.frontend.logs == [("Deleted environment files in %s." % bar_dir),
("Removing %s." % services_dir), ("Removing %s." % envs_dir)]
assert status.errors == []
assert not status
assert status.status_description == "Failed to clean everything up."
assert project.frontend.logs == [("Removing %s." % services_dir), ("Removing %s." % envs_dir)]
assert status.errors == [("Failed to remove environment files in %s: No rmtree here." % bar_dir),
("Error removing %s: No rmtree here." % services_dir),
("Error removing %s: No rmtree here." % envs_dir)]

assert not os.path.isdir(os.path.join(dirname, "envs"))
assert not os.path.isdir(os.path.join(dirname, "services"))
assert os.path.isdir(os.path.join(dirname, "envs"))
assert os.path.isdir(os.path.join(dirname, "services"))

# so with_directory_contents_completing_project_file can remove our tmp dir
monkeypatch.undo()

with_directory_contents_completing_project_file(
{DEFAULT_PROJECT_FILENAME: """
Expand All @@ -3390,26 +3467,27 @@ def check(dirname):
"""}, check)


def test_clean_failed_delete(monkeypatch):
def test_clean_environ_failed_delete(monkeypatch):
def mock_create(prefix, pkgs, channels, stdout_callback, stderr_callback):
os.makedirs(os.path.join(prefix, "conda-meta"))

monkeypatch.setattr('anaconda_project.internal.conda_api.create', mock_create)

def check(dirname):
envs_dir = os.environ['ANACONDA_PROJECT_ENVS_PATH'] = os.path.join(dirname, "some_random_failed_path")

project = Project(dirname, frontend=FakeFrontend())

result = prepare.prepare_without_interaction(project, env_spec_name='foo')

assert result
envs_dir = os.path.join(dirname, "envs")
assert os.path.isdir(os.path.join(envs_dir, "foo"))

# prepare again with 'bar' this time
project.frontend.reset()
result = prepare.prepare_without_interaction(project, env_spec_name='bar')
assert result
bar_dir = os.path.join(dirname, "envs", "bar")
bar_dir = os.path.join(envs_dir, "bar")
assert os.path.isdir(bar_dir)

# we don't really have a service in the test project file because
Expand All @@ -3432,11 +3510,13 @@ def mock_rmtree(path, onerror=None):
("Error removing %s: No rmtree here." % services_dir),
("Error removing %s: No rmtree here." % envs_dir)]

assert os.path.isdir(os.path.join(dirname, "envs"))
assert os.path.isdir(os.path.join(envs_dir))
assert os.path.isdir(os.path.join(dirname, "services"))

# so with_directory_contents_completing_project_file can remove our tmp dir
monkeypatch.undo()
# clean environ
os.environ.pop('ANACONDA_PROJECT_ENVS_PATH')

with_directory_contents_completing_project_file(
{DEFAULT_PROJECT_FILENAME: """
Expand Down

0 comments on commit 3edfd4e

Please sign in to comment.