def _load_service_requirement(dirname):
    project = Project(dirname)
    assert [] == project.problems
    for req in project.requirements(project.default_env_spec_name):
        if isinstance(req, ServiceRequirement):
            return req
    raise RuntimeError("no ServiceRequirement found")
Example #2
0
def _load_env_var_requirement(dirname, env_var):
    project = Project(dirname)

    for requirement in project.requirements(project.default_env_spec_name):
        if isinstance(requirement, EnvVarRequirement) and requirement.env_var == env_var:
            return requirement
    assert [] == project.problems
    raise RuntimeError("No requirement for %s was in the project file, only %r" % (env_var, project.requirements))
    def check(dirname):
        _monkeypatch_pwd(monkeypatch, dirname)

        code = _parse_args_and_run_subcommand(
            ['anaconda-project', 'remove-download', 'TEST_FILE'])
        project = Project(dirname)
        assert not project.downloads(project.default_env_spec_name)
        assert code == 1

        out, err = capsys.readouterr()
        assert ("Download requirement: TEST_FILE not found.\n") == err
        assert '' == out
    def check(dirname):
        _monkeypatch_pwd(monkeypatch, dirname)

        code = _parse_args_and_run_subcommand(
            ['anaconda-project', 'remove-download', 'TEST_FILE'])
        project = Project(dirname)
        assert not project.downloads(project.default_env_spec_name)
        assert code == 0

        out, err = capsys.readouterr()
        filename = os.path.join(dirname, 'foo')
        assert (
            "Removed downloaded file %s.\nRemoved TEST_FILE from the project file.\n"
            % filename) == out
        assert '' == err
    def check(dirname):
        def mock_is_interactive():
            return True

        monkeypatch.setattr('anaconda_project.internal.cli.console_utils.stdin_is_interactive', mock_is_interactive)

        def mock_console_input(prompt):
            return "c"

        monkeypatch.setattr('anaconda_project.internal.cli.console_utils.console_input', mock_console_input)

        def mock_system():
            return "Linux"

        monkeypatch.setattr('platform.system', mock_system)

        args = Args(None, 'test', 'echo hello', directory=dirname)
        res = main(args)
        assert res == 0

        project = Project(dirname)

        command = project.project_file.get_value(['commands', 'test'])
        assert len(command.keys()) == 2
        assert command['unix'] == 'echo hello'
        assert command['env_spec'] == 'default'
    def prepare_project_scoped_env_not_attempted(dirname):
        project = Project(dirname)
        environ = minimal_environ(PROJECT_DIR=dirname)
        result = prepare_without_interaction(project,
                                             environ=environ,
                                             mode=provide.PROVIDE_MODE_CHECK)
        assert not result
        # expected_env_path = os.path.join(dirname, "envs", "default")
        bootstrap_env_path = os.path.join(dirname, "envs", "bootstrap-env")
        for err in [
            ('missing requirement to run this project: ' +
             'The project needs a Conda bootstrap environment containing all required packages.'
             ),
                "  '%s' doesn't look like it contains a Conda environment yet."
                % bootstrap_env_path,
        ]:
            assert err in result.errors

        # unprepare should not have anything to do
        status = unprepare(project, result)
        assert status
        assert status.errors == []

        # todo: would be good to understand the different message got with a "normal" env
        assert status.status_description == ("Success.")
    def check_ask_type(dirname):
        def mock_is_interactive():
            return True

        monkeypatch.setattr('anaconda_project.internal.cli.console_utils.stdin_is_interactive', mock_is_interactive)

        calls = []

        def mock_console_input(prompt):
            res = ['-', 'b'][len(calls)]
            calls.append(True)
            return res

        monkeypatch.setattr('anaconda_project.internal.cli.console_utils.console_input', mock_console_input)

        args = Args(None, 'test', 'file.py', directory=dirname)
        res = main(args)
        assert res == 0
        assert len(calls) == 2

        project = Project(dirname)

        command = project.project_file.get_value(['commands', 'test'])
        assert len(command.keys()) == 2
        assert command['bokeh_app'] == 'file.py'
        assert command['env_spec'] == 'default'
        out, err = capsys.readouterr()
        assert out == ("Please enter 'b', 'n', or 'c'.\n" +
                       "    A Bokeh app is the project-relative path to a Bokeh script or app directory.\n" +
                       "    A notebook file is the project-relative path to a .ipynb file.\n"
                       "    A command line is any command you might type at the command prompt.\n"
                       "Added a command 'test' to the project. Run it with `anaconda-project run test`.\n")
    def check_ask_type(dirname):
        def mock_is_interactive():
            return True

        monkeypatch.setattr(
            'anaconda_project.internal.cli.console_utils.stdin_is_interactive',
            mock_is_interactive)

        def mock_console_input(prompt):
            return "b"

        monkeypatch.setattr(
            'anaconda_project.internal.cli.console_utils.console_input',
            mock_console_input)

        args = Args(None, 'test', 'file.py', directory=dirname)
        res = main(args)
        assert res == 0

        project = Project(dirname)

        command = project.project_file.get_value(['commands', 'test'])
        assert len(command.keys()) == 2
        assert command['bokeh_app'] == 'file.py'
        assert command['env_spec'] == 'default'
    def check(dirname):
        envs_dir = os.path.join(dirname, "envs")

        project = Project(dirname)
        environ = minimal_environ(PROJECT_DIR=dirname)
        stage = prepare_in_stages(project, environ=environ)

        prepare_context = stage.configure()

        status = _conda_env_status(prepare_context)
        req = status.requirement
        provider = status.provider

        # check initial config

        config = provider.read_config(req, prepare_context.environ,
                                      prepare_context.local_state_file,
                                      prepare_context.default_env_spec_name,
                                      prepare_context.overrides)

        assert dict(env_name='default',
                    source='project',
                    value=os.path.join(envs_dir, 'default')) == config

        # set inherited mode

        config['source'] = 'inherited'

        provider.set_config_values_as_strings(
            req, prepare_context.environ, prepare_context.local_state_file,
            prepare_context.default_env_spec_name, prepare_context.overrides,
            config)

        config = provider.read_config(req, prepare_context.environ,
                                      prepare_context.local_state_file,
                                      prepare_context.default_env_spec_name,
                                      prepare_context.overrides)

        assert dict(env_name='default',
                    source='inherited',
                    value=os.environ.get(req.env_var)) == config

        # disable inherited mode again

        config['source'] = 'project'
        config['env_name'] = 'default'

        provider.set_config_values_as_strings(
            req, prepare_context.environ, prepare_context.local_state_file,
            prepare_context.default_env_spec_name, prepare_context.overrides,
            config)

        config = provider.read_config(req, prepare_context.environ,
                                      prepare_context.local_state_file,
                                      prepare_context.default_env_spec_name,
                                      prepare_context.overrides)

        assert dict(env_name='default',
                    source='project',
                    value=os.path.join(envs_dir, 'default')) == config
Example #10
0
    def check(dirname):
        envs_dir = os.path.join(dirname, "envs")

        project = Project(dirname)
        environ = minimal_environ(PROJECT_DIR=dirname)
        stage = prepare_in_stages(project, environ=environ)

        prepare_context = stage.configure()

        status = _conda_bootstrap_env_status(prepare_context)
        req = status.requirement
        provider = status.provider

        config = provider.read_config(req, prepare_context.environ, prepare_context.local_state_file,
                                      prepare_context.default_env_spec_name, prepare_context.overrides)
        assert dict(env_name='bootstrap-env', source='project', value=os.path.join(envs_dir, 'bootstrap-env')) == config

        config['env_name'] = 'bar'

        provider.set_config_values_as_strings(req, prepare_context.environ, prepare_context.local_state_file,
                                              prepare_context.default_env_spec_name, prepare_context.overrides, config)

        config = provider.read_config(req, prepare_context.environ, prepare_context.local_state_file,
                                      prepare_context.default_env_spec_name, prepare_context.overrides)
        assert dict(env_name='bar', source='project', value=os.path.join(envs_dir, 'bar')) == config

        assert os.path.join(envs_dir, 'bar') == prepare_context.local_state_file.get_value(['variables', req.env_var])
Example #11
0
    def check(dirname):
        env_var = conda_api.conda_prefix_variable()

        try:
            _push_fake_env_creator()
            project = Project(dirname)
            environ = minimal_environ()
            result = prepare_without_interaction(project,
                                                 environ=environ,
                                                 env_spec_name='foo')
            expected_path = project.env_specs['foo'].path(
                project.directory_path)
            assert result.environ[env_var] == expected_path

            environ = minimal_environ()
            result = prepare_without_interaction(project,
                                                 environ=environ,
                                                 env_spec_name='bar')
            assert result.errors == []
            assert result
            expected_path = project.env_specs['bar'].path(
                project.directory_path)
            assert result.environ[env_var] == expected_path
        finally:
            _pop_fake_env_creator()
 def unprepare_empty(dirname):
     project = Project(dirname)
     environ = minimal_environ()
     result = prepare_without_interaction(project, environ=environ)
     assert result.errors == []
     assert result
     status = unprepare(project, result)
     assert status.errors == []
     assert status
 def prepare_empty(dirname):
     project = Project(dirname)
     environ = minimal_environ()
     result = prepare_without_interaction(project, environ=environ)
     assert result.errors == []
     assert result
     assert dict(PROJECT_DIR=project.directory_path) == strip_environ(result.environ)
     assert dict() == strip_environ(environ)
     assert result.command_exec_info is None
 def unprepare_nothing(dirname):
     project = Project(dirname)
     environ = minimal_environ()
     result = prepare_without_interaction(project, environ=environ)
     assert result.errors == []
     assert result
     status = unprepare(project, result, whitelist=[])
     assert status.errors == []
     assert status
     assert status.status_description == 'Nothing to clean up.'
def load_project(dirname):
    """Load a Project, fixing it if needed and possible."""
    project = Project(dirname, frontend=CliFrontend())

    if console_utils.stdin_is_interactive():
        had_fixable = len(project.fixable_problems) > 0
        for problem in project.fixable_problems:
            print(problem.text)
            should_fix = console_utils.console_ask_yes_or_no(problem.fix_prompt, default=False)
            if should_fix:
                problem.fix(project)
            else:
                problem.no_fix(project)

        # both fix() and no_fix() can modify project_file, if no changes
        # were made this is a no-op.
        if had_fixable:
            project.save()

    return project
    def check_guessing_notebook(dirname):
        args = Args(None, 'test', 'file.ipynb', directory=dirname)
        res = main(args)
        assert res == 0

        project = Project(dirname)

        command = project.project_file.get_value(['commands', 'test'])
        assert command['notebook'] == 'file.ipynb'
        assert command['env_spec'] == 'default'
        assert len(command.keys()) == 2
    def check(dirname):
        code = _parse_args_and_run_subcommand(['anaconda-project', 'add-command', '--directory', dirname, '--env-spec',
                                               'foo', '--type', 'notebook', 'test', 'file.ipynb'])
        assert code == 0

        project = Project(dirname)

        command = project.project_file.get_value(['commands', 'test'])
        assert command['notebook'] == 'file.ipynb'
        assert command['env_spec'] == 'foo'
        assert len(command.keys()) == 2
    def check(dirname):
        code = _parse_args_and_run_subcommand(['anaconda-project', 'remove-command', 'test', '--directory', dirname])
        assert code == 0

        project = Project(dirname)

        command = project.project_file.get_value(['commands', 'test'])
        assert command is None

        out, err = capsys.readouterr()
        assert out == "Removed the command 'test' from the project.\n"
        assert err == ''
    def check(dirname):
        code = _parse_args_and_run_subcommand(['anaconda-project', 'add-command', '--directory', dirname,
                                               '--supports-http-options', '--type', 'notebook', 'test', 'file.ipynb'])
        assert code == 0

        project = Project(dirname)

        command = project.project_file.get_value(['commands', 'test'])
        assert command['notebook'] == 'file.ipynb'
        assert command['env_spec'] == 'default'
        assert command['supports_http_options'] is True
        assert len(command.keys()) == 3
Example #20
0
def load_project(dirname):
    """Load a Project, fixing it if needed and possible."""
    project = Project(dirname, frontend=CliFrontend(), must_exist=True)

    # No sense in engaging the user if we cannot achieve a fixed state.
    if project.unfixable_problems:
        return project

    if console_utils.stdin_is_interactive():
        regressions = 0
        problems = project.fixable_problems
        while problems and regressions < 3:
            # Instead of looping through the problems in the list, we
            # fix only the first one and refresh the list. This allows
            # us to detect when fixing one problem impacts another,
            # positively or negatively.
            problem = problems[0]
            print(problem.text)
            should_fix = console_utils.console_ask_yes_or_no(problem.fix_prompt, default=False)
            if not should_fix:
                break
            problem.fix(project)
            project.use_changes_without_saving()
            o_problems, problems = problems, project.fixable_problems
            # If the number of problems doesn't decrease as a result of
            # fixing a problem, it suggests some sort of negative cycle.
            # We can't reliably detect a cycle, so instead we simply let
            # this happen 3 times before we give up.
            regressions += (len(problems) >= len(o_problems))
        if not problems:
            project.save()

    return project
Example #21
0
    def check(dirname):
        broken_project = Project(dirname)
        assert len(broken_project.fixable_problems) == 1

        _monkeypatch_input(monkeypatch, ["n"])

        project = load_project(dirname)
        first_line = "%s: The env_specs section is missing." % DEFAULT_PROJECT_FILENAME
        assert project.problems == [first_line]

        out, err = capsys.readouterr()
        assert out == "%s\nAdd an environment spec to anaconda-project.yml? " % first_line
        assert err == ""
    def prepare_project_scoped_env(dirname):
        project = Project(dirname)
        fake_old_path = "foo" + os.pathsep + "bar"
        environ = dict(PROJECT_DIR=dirname, PATH=fake_old_path)
        result = prepare_without_interaction(project, environ=environ)
        assert result
        expected_env = os.path.join(dirname, "envs", "bootstrap-env")
        if platform.system() == 'Windows':
            expected_new_path = expected_env + os.pathsep + os.path.join(
                expected_env, script_dir) + os.pathsep + os.path.join(
                    expected_env, "Library",
                    "bin") + os.pathsep + "foo" + os.pathsep + "bar"
        else:
            expected_new_path = os.path.join(
                expected_env,
                script_dir) + os.pathsep + "foo" + os.pathsep + "bar"
        expected = dict(PROJECT_DIR=project.directory_path,
                        PATH=expected_new_path,
                        BOOTSTRAP_ENV_PREFIX=expected_env)
        conda_api.environ_set_prefix(expected, expected_env)

        expected == result.environ
        assert os.path.exists(os.path.join(expected_env, "conda-meta"))
        conda_meta_mtime = os.path.getmtime(
            os.path.join(expected_env, "conda-meta"))

        # bare minimum bootstrap-env env shouldn't include these
        # (contrast with the test later where we list them in
        # requirements)
        installed = conda_api.installed(expected_env)
        assert 'ipython' not in installed
        assert 'numpy' not in installed

        # Prepare it again should no-op (use the already-existing environment)
        environ = dict(PROJECT_DIR=dirname, PATH=fake_old_path)
        result = prepare_without_interaction(project, environ=environ)
        assert result
        expected = dict(PROJECT_DIR=project.directory_path,
                        PATH=expected_new_path)
        conda_api.environ_set_prefix(expected, expected_env)
        assert conda_meta_mtime == os.path.getmtime(
            os.path.join(expected_env, "conda-meta"))

        # Now unprepare
        status = unprepare(project, result)
        assert status

        # todo: this differs from standard CondaEnvProvider
        assert status.status_description == 'Success.'
        assert status.errors == []
        assert not os.path.exists(expected_env)
def project_no_dedicated_env(*args, **kwargs):
    """Get a project that won't create envs/default as long as there's an env already."""
    if len(args) > 0:
        dirname = args[0]
    elif 'directory_path' in kwargs:
        dirname = kwargs['directory_path']
    else:
        raise RuntimeError("no directory_path for Project")

    project_dir_disable_dedicated_env(dirname)

    project = Project(*args, **kwargs)

    return project
    def prepare_project_scoped_env_fails(dirname):
        project = Project(dirname)
        environ = minimal_environ(PROJECT_DIR=dirname)
        result = prepare_without_interaction(project, environ=environ)
        assert not result

        assert 'CONDA_DEFAULT_ENV' not in result.environ
        assert 'CONDA_ENV_PATH' not in result.environ

        # unprepare should not have anything to do
        status = unprepare(project, result)
        assert status
        assert status.errors == []
        assert status.status_description == "Nothing to clean up for environment 'default'."
Example #25
0
    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 = "Packages for environment '{}':\n{}".format(env or project.default_env_spec_name, expected_deps)
        assert out == expected_out
    def check(dirname):
        env_var = conda_api.conda_prefix_variable()

        try:
            _push_fake_env_creator()
            project = Project(dirname)
            environ = minimal_environ()
            # we specify the command name but not the
            # env_spec_name but it should imply the proper env
            # spec name.
            result = prepare_without_interaction(project, environ=environ, command_name='hello')
            expected_path = project.env_specs['foo'].path(project.directory_path)
            assert result.environ[env_var] == expected_path
        finally:
            _pop_fake_env_creator()
Example #27
0
    def check(dirname):
        project = Project(dirname)
        environ = minimal_environ()
        result = prepare_without_interaction(project, environ=environ)
        assert result

        # now mimmick an unpacked project
        packed_file = os.path.join(dirname, 'envs', 'default', 'conda-meta',
                                   '.packed')
        with open(packed_file, 'wt') as f:
            f.write(conda_api.current_platform())

        # without a functional conda-unpack script it will rebuild the env
        result = prepare_without_interaction(project, environ=environ)
        assert result
        assert not os.path.exists(packed_file)
    def clone_readonly_and_prepare(dirname):
        with _readonly_env(env_name='default',
                           packages=('python=3.7', )) as ro_prefix:
            readonly = conda_api.installed(ro_prefix)
            assert 'python' in readonly
            assert 'requests' not in readonly

            ro_envs = os.path.dirname(ro_prefix)
            environ = minimal_environ(
                PROJECT_DIR=dirname,
                ANACONDA_PROJECT_ENVS_PATH=':{}'.format(ro_envs))
            monkeypatch.setattr('os.environ', environ)

            project = Project(dirname)
            result = prepare_without_interaction(project)
            assert result.failed
            assert '  Conda environment is missing packages: requests and the environment is read-only' in result.errors
    def do_test(dirname):
        io_loop = IOLoop()
        io_loop.make_current()

        events = []

        def event_handler(event):
            events.append(event)

        project = Project(dirname)
        local_state_file = LocalStateFile.load_for_directory(dirname)

        requirement = EnvVarRequirement(registry=project.plugin_registry, env_var="FOO")
        status = requirement.check_status(dict(), local_state_file, 'default', UserConfigOverrides())
        context = ConfigurePrepareContext(dict(), local_state_file, 'default', UserConfigOverrides(), [status])
        server = UIServer(project, _no_op_prepare(context), event_handler, io_loop)

        # do a get so that _requirements_by_id below exists
        get_response = http_get(io_loop, server.url)
        assert 200 == get_response.code

        req_id = list(server._application._requirements_by_id.keys())[0]
        if '%s' in name_template:
            name = name_template % req_id
        else:
            name = name_template

        encoder = MultipartEncoder({name: 'bloop'})
        body = encoder.to_string()
        headers = {'Content-Type': encoder.content_type}

        post_response = http_post(io_loop, server.url, body=body, headers=headers)
        # we just ignore bad form names, because they are assumed
        # to be some sort of hostile thing. we shouldn't ever
        # generate them on purpose.
        assert 200 == post_response.code

        server.unlisten()

        assert len(events) == 1
        assert isinstance(events[0], UIServerDoneEvent)

        out, err = capsys.readouterr()
        assert out == ""
        assert err == expected_err
    def prepare_project_scoped_env_with_packages(dirname):
        project = Project(dirname)
        environ = minimal_environ(PROJECT_DIR=dirname)
        result = prepare_without_interaction(project,
                                             environ=environ,
                                             env_spec_name='bootstrap-env')
        assert result

        envs_dir = os.path.join(dirname, "envs")
        env_name = 'bootstrap-env'
        prefix = os.path.join(envs_dir, env_name)
        installed = conda_api.installed(prefix)

        assert 'bokeh' not in installed

        deps = ['ipython', 'numpy', 'pip']
        for pkg in deps:
            assert pkg in installed

        deps += ['bokeh']

        # Preparing it again with new packages added should add those
        project.project_file.set_value('packages', deps)
        project.project_file.save()
        environ = minimal_environ(PROJECT_DIR=dirname)
        result = prepare_without_interaction(project, environ=environ)
        assert result

        prefix = result.environ[conda_env_var]
        installed = conda_api.installed(prefix)

        for pkg in deps:
            assert pkg in installed

        installed_pip = pip_api.installed(prefix)
        assert 'flake8' in installed_pip

        # Preparing it again with a bogus package should fail
        deps = project.project_file.get_value('packages')
        project.project_file.set_value(['packages'], deps + ['boguspackage'])
        project.project_file.save()
        environ = minimal_environ(PROJECT_DIR=dirname)
        result = prepare_without_interaction(project, environ=environ)
        assert not result