Skip to content

Commit

Permalink
Merge pull request #297 from Anaconda-Platform/refresh
Browse files Browse the repository at this point in the history
Move the refresh logic deeper into prepare
  • Loading branch information
mcg1969 committed Dec 8, 2020
2 parents 4c1726d + 9904dc8 commit 63c65dc
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 43 deletions.
25 changes: 8 additions & 17 deletions anaconda_project/internal/cli/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import anaconda_project.internal.cli.console_utils as console_utils
from anaconda_project.internal.cli.prepare_with_mode import prepare_with_ui_mode_printing_errors
from anaconda_project.internal.cli.project_load import load_project
from anaconda_project.requirements_registry.providers.conda_env import _remove_env_path


def prepare_command(project_dir, ui_mode, conda_environment, command_name, all=False, refresh=False):
Expand All @@ -21,26 +20,18 @@ def prepare_command(project_dir, ui_mode, conda_environment, command_name, all=F
Prepare result (can be treated as True on success).
"""
project = load_project(project_dir)
project_dir = project.directory_path
if console_utils.print_project_problems(project):
return False
if all:
result = []
for k, v in project.env_specs.items():
if refresh:
_remove_env_path(v.path(project.directory_path))
result = prepare_with_ui_mode_printing_errors(project,
env_spec_name=k,
ui_mode=ui_mode,
command_name=command_name)
specs = project.env_specs
else:
if refresh:
conda_environment = 'default' if conda_environment is None else conda_environment
_remove_env_path(project.env_specs[conda_environment].path(project.directory_path))
result = prepare_with_ui_mode_printing_errors(project,
env_spec_name=conda_environment,
ui_mode=ui_mode,
command_name=command_name)

specs = {conda_environment: project.env_specs.get(conda_environment)}
result = True
for k, v in specs.items():
if not prepare_with_ui_mode_printing_errors(
project, env_spec_name=k, ui_mode=ui_mode, command_name=command_name, refresh=refresh):
result = False
return result


Expand Down
6 changes: 4 additions & 2 deletions anaconda_project/internal/cli/prepare_with_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ def prepare_with_ui_mode_printing_errors(project,
env_spec_name=None,
command_name=None,
command=None,
extra_command_args=None):
extra_command_args=None,
refresh=False):
"""Perform all steps needed to get a project ready to execute.
This may need to ask the user questions, may start services,
Expand Down Expand Up @@ -140,7 +141,8 @@ def prepare_with_ui_mode_printing_errors(project,
env_spec_name=env_spec_name,
command_name=command_name,
command=command,
extra_command_args=extra_command_args)
extra_command_args=extra_command_args,
refresh=refresh)

if result.failed:
if ask and _interactively_fix_missing_variables(project, result):
Expand Down
29 changes: 22 additions & 7 deletions anaconda_project/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from anaconda_project.requirements_registry.provider import ProvideContext
from anaconda_project.requirements_registry.requirement import Requirement, EnvVarRequirement, UserConfigOverrides
from anaconda_project.requirements_registry.requirements.conda_env import CondaEnvRequirement
from anaconda_project.requirements_registry.providers.conda_env import _remove_env_path


def _update_environ(dest, src):
Expand Down Expand Up @@ -702,7 +703,7 @@ def _prepare_environ_and_overrides(project, environ=None, env_spec_name=None):


def _internal_prepare_in_stages(project, environ_copy, overrides, keep_going_until_success, mode, provide_whitelist,
command_name, command, extra_command_args):
command_name, command, extra_command_args, refresh):
assert not project.problems
if mode not in _all_provide_modes:
raise ValueError("invalid provide mode " + mode)
Expand All @@ -715,14 +716,23 @@ def _internal_prepare_in_stages(project, environ_copy, overrides, keep_going_unt
command = project.command_for_name(command_name)
# at this point, "command" is only None if there are no
# commands for this project.
default_env_name = project.default_env_spec_name_for_command(command)

local_state = LocalStateFile.load_for_directory(project.directory_path)
our_root = project.directory_path
local_state = LocalStateFile.load_for_directory(our_root)

if refresh:
# To do: move the refresh flag into the provider somehow. Thought: add
# the refresh flag to overrides, and have the conda env requirements
# engine interpret that and schedule a refresh and create.
env_name = overrides.env_spec_name or default_env_name
_remove_env_path(project.env_specs[env_name].path(our_root), our_root)

statuses = []
for requirement in project.requirements(overrides.env_spec_name):
status = requirement.check_status(environ_copy,
local_state,
project.default_env_spec_name_for_command(command),
default_env_name,
overrides,
latest_provide_result=None)
statuses.append(status)
Expand All @@ -739,7 +749,8 @@ def prepare_in_stages(project,
env_spec_name=None,
command_name=None,
command=None,
extra_command_args=None):
extra_command_args=None,
refresh=False):
"""Get a chain of all steps needed to get a project ready to execute.
This function does not immediately do anything; it returns a
Expand All @@ -766,6 +777,7 @@ def prepare_in_stages(project,
command_name (str): which named command to choose from the project, None for default
command (ProjectCommand): command object, None for default
extra_command_args (list of str): extra args for the command we prepare
refresh (bool): do a full reinstall of the environment
Returns:
The first ``PrepareStage`` in the chain of steps.
Expand All @@ -781,7 +793,8 @@ def prepare_in_stages(project,
provide_whitelist=provide_whitelist,
command_name=command_name,
command=command,
extra_command_args=extra_command_args)
extra_command_args=extra_command_args,
refresh=refresh)


def _project_problems_to_prepare_failure(project, environ, overrides, would_have_used_env_spec):
Expand Down Expand Up @@ -870,7 +883,8 @@ def prepare_without_interaction(project,
env_spec_name=None,
command_name=None,
command=None,
extra_command_args=None):
extra_command_args=None,
refresh=False):
"""Prepare a project to run one of its commands.
This method doesn't ask the user any questions, so the
Expand Down Expand Up @@ -930,7 +944,8 @@ def prepare_without_interaction(project,
provide_whitelist=provide_whitelist,
command_name=command_name,
command=command,
extra_command_args=extra_command_args)
extra_command_args=extra_command_args,
refresh=refresh)

return prepare_execute_without_interaction(stage)

Expand Down
2 changes: 1 addition & 1 deletion anaconda_project/project_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ def remove_env_spec(project, name):
# that was prepared. So instead we share some code with the
# CondaEnvProvider but don't try to go through the unprepare
# machinery.
status = _remove_env_path(env_path)
status = _remove_env_path(env_path, project.directory_path)
if status:
with _updating_project_lock_file(project) as status_holder:
project.project_file.unset_value(['env_specs', name])
Expand Down
27 changes: 12 additions & 15 deletions anaconda_project/requirements_registry/providers/conda_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,20 @@
from anaconda_project.provide import PROVIDE_MODE_CHECK


def _remove_env_path(env_path):
def _remove_env_path(env_path, project_dir):
"""Also used by project_ops.py to delete environment files."""
if os.path.exists(env_path):
try:
shutil.rmtree(env_path)
return SimpleStatus(success=True, description=("Deleted environment files in %s." % env_path))
except Exception as e:
problem = "Failed to remove environment files in {}: {}.".format(env_path, str(e))
return SimpleStatus(success=False, description=problem)
else:
if not os.path.isdir(env_path):
return SimpleStatus(success=True,
description=("Nothing to clean up for environment '%s'." % os.path.basename(env_path)))
if not env_path.startswith(project_dir + os.sep):
return SimpleStatus(success=True,
description=("Current environment is not in %s, no need to delete it." % project_dir))
try:
shutil.rmtree(env_path)
return SimpleStatus(success=True, description=("Deleted environment files in %s." % env_path))
except Exception as e:
problem = "Failed to remove environment files in {}: {}.".format(env_path, str(e))
return SimpleStatus(success=False, description=problem)


class CondaEnvProvider(EnvVarProvider):
Expand Down Expand Up @@ -229,9 +231,4 @@ def unprovide(self, requirement, environ, local_state_file, overrides, requireme

env_path = config.get('value', None)
assert env_path is not None
project_dir = environ['PROJECT_DIR']
if not env_path.startswith(project_dir):
return SimpleStatus(success=True,
description=("Current environment is not in %s, no need to delete it." % project_dir))

return _remove_env_path(env_path)
return _remove_env_path(env_path, environ['PROJECT_DIR'])
2 changes: 1 addition & 1 deletion anaconda_project/test/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def _test_prepare_without_interaction(monkeypatch, api_method, provide_mode):
from anaconda_project.prepare import prepare_without_interaction
_verify_args_match(getattr(api.AnacondaProject, api_method),
prepare_without_interaction,
ignored=['self', 'mode', 'provide_whitelist'])
ignored=['self', 'mode', 'provide_whitelist', 'refresh'])

params = _monkeypatch_prepare_without_interaction(monkeypatch)
p = api.AnacondaProject()
Expand Down

0 comments on commit 63c65dc

Please sign in to comment.