Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Editor temporary/working/backup files #
#########################################
env/
.#*
[#]*#
*~
Expand Down Expand Up @@ -108,4 +109,4 @@ examples/*/envs
cov.xml
coverage.xml
junit.xml
/fake_project
/fake_project
2 changes: 1 addition & 1 deletion anaconda_project/env_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ def _load_environment_yml(filename):
name = os.path.basename(yaml['prefix'])

if not name:
name = os.path.basename(filename)
name = 'default'

# We don't do too much validation here because we end up doing it
# later if we import this into the project, and then load it from
Expand Down
2 changes: 1 addition & 1 deletion anaconda_project/internal/cli/activate.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def activate(dirname, ui_mode, conda_environment, command_name):
Returns:
None on failure or a list of lines to print.
"""
project = load_project(dirname)
project = load_project(dirname, save=False)
result = prepare_with_ui_mode_printing_errors(project,
ui_mode=ui_mode,
env_spec_name=conda_environment,
Expand Down
2 changes: 1 addition & 1 deletion anaconda_project/internal/cli/archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def archive_command(project_dir, archive_filename, pack_envs):
if not prepare_status:
return 1

project = load_project(project_dir)
project = load_project(project_dir, save=False)

status = project_ops.archive(project, archive_filename, pack_envs)
if status:
Expand Down
2 changes: 1 addition & 1 deletion anaconda_project/internal/cli/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def clean_command(project_dir):
Returns:
exit code
"""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
# we don't want to print errors during this prepare, clean
# can proceed even though the prepare fails.
with project.null_frontend():
Expand Down
4 changes: 2 additions & 2 deletions anaconda_project/internal/cli/command_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def list_commands(project_dir):
Returns:
int exit code
"""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1

Expand All @@ -111,7 +111,7 @@ def list_default_command(project_dir):
Returns:
int exit code
"""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1

Expand Down
2 changes: 1 addition & 1 deletion anaconda_project/internal/cli/dockerize.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def dockerize_command(project_dir, tag, command, builder_image, build_args):
Returns:
exit code
"""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
status = project_ops.dockerize(project,
tag=tag,
command=command,
Expand Down
2 changes: 1 addition & 1 deletion anaconda_project/internal/cli/download_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def remove_download(project_dir, env_spec_name, filename_variable):

def list_downloads(project_dir, env_spec_name):
"""List the downloads present in project."""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1

Expand Down
14 changes: 7 additions & 7 deletions anaconda_project/internal/cli/environment_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def remove_env_spec(project_dir, name):

def export_env_spec(project_dir, name, filename):
"""Save an environment.yml file."""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
status = project_ops.export_env_spec(project, name=name, filename=filename)
return _handle_status(status)

Expand Down Expand Up @@ -101,7 +101,7 @@ def remove_platforms(project, environment, platforms):

def list_env_specs(project_dir):
"""List environments in the project."""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1
print("Environments for project: {}\n".format(project_dir))
Expand All @@ -111,7 +111,7 @@ def list_env_specs(project_dir):

def list_packages(project_dir, environment):
"""List the packages for an environment in the project."""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1
if environment is None:
Expand All @@ -132,7 +132,7 @@ def list_packages(project_dir, environment):

def list_platforms(project_dir, environment):
"""List the platforms for an environment in the project."""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1
if environment is None:
Expand All @@ -148,7 +148,7 @@ def list_platforms(project_dir, environment):

def lock(project_dir, env_spec_name):
"""Lock dependency versions."""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1
status = project_ops.lock(project, env_spec_name=env_spec_name)
Expand All @@ -157,7 +157,7 @@ def lock(project_dir, env_spec_name):

def update(project_dir, env_spec_name):
"""Update dependency versions."""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1
status = project_ops.update(project, env_spec_name=env_spec_name)
Expand All @@ -166,7 +166,7 @@ def update(project_dir, env_spec_name):

def unlock(project_dir, env_spec_name):
"""Unlock dependency versions."""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1
status = project_ops.unlock(project, env_spec_name=env_spec_name)
Expand Down
17 changes: 9 additions & 8 deletions anaconda_project/internal/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@


def _parse_args_and_run_subcommand(argv):
parser = ArgumentParser(prog="anaconda-project", description="Actions on projects (runnable projects).")
parser = ArgumentParser(prog="conda-project", description="Actions on projects (runnable projects).")

subparsers = parser.add_subparsers(help="Sub-commands")

Expand All @@ -59,7 +59,7 @@ def add_env_spec_arg(preset):
metavar='ENVIRONMENT_SPEC_NAME',
default=None,
action='store',
help="An environment spec name from anaconda-project.yml")
help="An environment spec name from conda-project.yml")

def add_prepare_args(preset, include_command=True):
add_directory_arg(preset)
Expand All @@ -79,15 +79,15 @@ def add_prepare_args(preset, include_command=True):
metavar='COMMAND_NAME',
default=None,
action='store',
help="A command name from anaconda-project.yml (env spec for this command will be used)")
help="A command name from conda-project.yml (env spec for this command will be used)")

def add_env_spec_name_arg(preset, required):
preset.add_argument('-n',
'--name',
metavar='ENVIRONMENT_SPEC_NAME',
required=required,
action='store',
help="Name of the environment spec from anaconda-project.yml")
help="Name of the environment spec from conda-project.yml")

preset = subparsers.add_parser('init', help="Initialize a directory with default project configuration")
add_directory_arg(preset)
Expand All @@ -108,13 +108,14 @@ def add_env_spec_name_arg(preset, required):
metavar='COMMAND_NAME',
default=None,
nargs='?',
help="A command name from anaconda-project.yml")
help="A command name from conda-project.yml")
preset.add_argument('extra_args_for_command', metavar='EXTRA_ARGS_FOR_COMMAND', default=None, nargs=REMAINDER)
preset.set_defaults(main=run.main)

preset = subparsers.add_parser('prepare', help="Set up the project requirements, but does not run the project")
preset.add_argument('--all', action='store_true', help="Prepare all environments", default=None)
preset.add_argument('--refresh', action='store_true', help='Remove and recreate the environment', default=None)
preset.add_argument('--python', type=str, help='Specify Python version if using requirements.txt', default=None)
add_prepare_args(preset)
preset.set_defaults(main=prepare.main)

Expand Down Expand Up @@ -223,14 +224,14 @@ def add_env_spec_name_arg(preset, required):
preset.set_defaults(main=variable_commands.main_list)

preset = subparsers.add_parser('set-variable',
help="Set an environment variable value in anaconda-project-local.yml")
help="Set an environment variable value in conda-project-local.yml")
add_env_spec_arg(preset)
preset.add_argument('vars_and_values', metavar='VARS_AND_VALUES', default=None, nargs=REMAINDER)
add_directory_arg(preset)
preset.set_defaults(main=variable_commands.main_set)

preset = subparsers.add_parser('unset-variable',
help="Unset an environment variable value from anaconda-project-local.yml")
help="Unset an environment variable value from conda-project-local.yml")
add_env_spec_arg(preset)
add_directory_arg(preset)
preset.add_argument('vars_to_unset', metavar='VARS_TO_UNSET', default=None, nargs=REMAINDER)
Expand Down Expand Up @@ -441,4 +442,4 @@ def main():
Conda expects us to take no args and return an exit code.
"""
details = {'version': version}
return handle_bugs(_main_without_bug_handler, program_name='anaconda-project', details_dict=details)
return handle_bugs(_main_without_bug_handler, program_name='conda-project', details_dict=details)
14 changes: 10 additions & 4 deletions anaconda_project/internal/cli/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@
# -----------------------------------------------------------------------------
"""The ``prepare`` command configures a project to run, asking the user questions if necessary."""
from __future__ import absolute_import, print_function
from os import path

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


def prepare_command(project_dir, ui_mode, conda_environment, command_name, all=False, refresh=False):
def prepare_command(project_dir, ui_mode, conda_environment, command_name, all=False, refresh=False, python=None):
"""Configure the project to run.

Returns:
Prepare result (can be treated as True on success).
"""
project = load_project(project_dir)
project_dir = project.directory_path
project = load_project(project_dir, save=False)

if path.isfile(path.join(project_dir, 'requirements.txt')):
default = project.env_specs[project.default_env_spec_name]
if not default.conda_packages and (python is not None):
default._conda_packages = [f'python={python}']

if console_utils.print_project_problems(project):
return False
if all:
Expand All @@ -37,7 +43,7 @@ def prepare_command(project_dir, ui_mode, conda_environment, command_name, all=F

def main(args):
"""Start the prepare command and return exit status code."""
if prepare_command(args.directory, args.mode, args.env_spec, args.command, args.all, args.refresh):
if prepare_command(args.directory, args.mode, args.env_spec, args.command, args.all, args.refresh, args.python):
print("The project is ready to run commands.")
print("Use `anaconda-project list-commands` to see what's available.")
return 0
Expand Down
5 changes: 3 additions & 2 deletions anaconda_project/internal/cli/project_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def partial_error(self, data):
sys.stderr.flush()


def load_project(dirname):
def load_project(dirname, save=True):
"""Load a Project, fixing it if needed and possible."""
project = Project(dirname, frontend=CliFrontend(), must_exist=True)

Expand Down Expand Up @@ -65,6 +65,7 @@ def load_project(dirname):
# this happen 3 times before we give up.
regressions += (len(problems) >= len(o_problems))
if not problems:
project.save()
if save:
project.save()

return project
2 changes: 1 addition & 1 deletion anaconda_project/internal/cli/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def run_command(project_dir, ui_mode, conda_environment, command_name, extra_com
Returns:
Does not return if successful.
"""
project = load_project(project_dir)
project = load_project(project_dir, save=False)

if project.has_bootstrap_env_spec() and not project.is_running_in_bootstrap_env():
print("Project should be ran by bootstrap env... fixing.")
Expand Down
2 changes: 1 addition & 1 deletion anaconda_project/internal/cli/service_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def remove_service(project_dir, env_spec_name, variable_name):

def list_services(project_dir, env_spec_name):
"""List the services listed on the project."""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1

Expand Down
47 changes: 47 additions & 0 deletions anaconda_project/internal/cli/test/test_environment_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,53 @@ def test_list_packages_from_env_default(capsys):
_test_list_packages(capsys, None, '\nflask\nmandatory_package\nrequests\n\n', '\nmandatory_pip_package\n\n')


def _test_list_packages_with_pip(capsys, env, expected_deps, expected_pip_deps):
def check_list_not_empty(dirname):
params = ['anaconda-project', 'list-packages', '--directory', dirname]
if env is not None:
params.extend(['--env-spec', env])

code = _parse_args_and_run_subcommand(params)

assert code == 0
out, err = capsys.readouterr()

project = Project(dirname)
assert project.default_env_spec_name == 'foo'
expected_out = "Conda Packages for environment '{}':\n{}".format(env or project.default_env_spec_name, expected_deps)
expected_out += "Pip Packages for environment '{}':\n{}".format(env or project.default_env_spec_name, expected_pip_deps)
assert out == expected_out

project_contents = ('env_specs:\n'
' foo:\n'
' packages:\n'
' - requests\n'
' - flask\n'
' - pip:\n'
' - barfoo\n'
' bar:\n'
' packages:\n'
' - httplib\n'
' - django\n'
' - pip:\n'
' - foobar\n\n'
'packages:\n'
' - mandatory_package\n'
' - pip:\n'
' - foo\n')

with_directory_contents_completing_project_file({DEFAULT_PROJECT_FILENAME: project_contents}, check_list_not_empty)


def test_list_packages_with_pip_from_env(capsys):
_test_list_packages_with_pip(capsys, 'bar', '\ndjango\nhttplib\nmandatory_package\n\n', '\nfoo\nfoobar\n\n')
_test_list_packages_with_pip(capsys, 'foo', '\nflask\nmandatory_package\nrequests\n\n', '\nbarfoo\nfoo\n\n')


def test_list_packages_with_pip_from_env_default(capsys):
_test_list_packages_with_pip(capsys, None, '\nflask\nmandatory_package\nrequests\n\n', '\nbarfoo\nfoo\n\n')


def test_list_packages_with_project_file_problems(capsys, monkeypatch):
_test_environment_command_with_project_file_problems(capsys,
monkeypatch,
Expand Down
2 changes: 1 addition & 1 deletion anaconda_project/internal/cli/test/test_prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def _mock_prepare_do_not_keep_going(project,

def main_redis_url(dirname):
project_dir_disable_dedicated_env(dirname)
code = main(Args(directory=dirname, all=False, refresh=False))
code = main(Args(directory=dirname, all=False, refresh=False, python=None))
assert 1 == code

with_directory_contents_completing_project_file({DEFAULT_PROJECT_FILENAME: """
Expand Down
2 changes: 1 addition & 1 deletion anaconda_project/internal/cli/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def upload_command(project_dir, private, site, username, token, suffix):
Returns:
exit code
"""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
status = project_ops.upload(project, private=private, site=site, username=username, token=token, suffix=suffix)
if status:
print(status.status_description)
Expand Down
6 changes: 3 additions & 3 deletions anaconda_project/internal/cli/variable_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def remove_variables(project_dir, env_spec_name, vars_to_remove):

def list_variables(project_dir, env_spec_name):
"""List variables present in project."""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
if console_utils.print_project_problems(project):
return 1
print("Variables for project: {}\n".format(project_dir))
Expand All @@ -75,7 +75,7 @@ def set_variables(project_dir, env_spec_name, vars_and_values):
return 1
# maxsplit=1 -- no maxsplit keywork in py27
fixed_vars.append(tuple(var.split('=', 1)))
project = load_project(project_dir)
project = load_project(project_dir, save=False)
status = project_ops.set_variables(project, env_spec_name, fixed_vars)
if status:
print(status.status_description)
Expand All @@ -91,7 +91,7 @@ def unset_variables(project_dir, env_spec_name, vars_to_unset):
Returns:
Returns exit code
"""
project = load_project(project_dir)
project = load_project(project_dir, save=False)
status = project_ops.unset_variables(project, env_spec_name, vars_to_unset)
if status:
print(status.status_description)
Expand Down
Loading