def check_conda_env_in_path_windows_trailing_slashes(dirname):
        _windows_monkeypatch(monkeypatch)

        scripts = "Scripts"
        library = "Library\\bin"

        env1 = os.path.join(dirname, "env1")
        os.makedirs(os.path.join(env1, "conda-meta"))
        env1scripts = os.path.join(env1, scripts)
        os.makedirs(env1scripts)
        env1lib = os.path.join(env1, library)
        os.makedirs(env1lib)

        env1path = "%s\\;%s\\;%s\\" % (env1, env1scripts, env1lib)
        env1path_no_slashes = "%s;%s;%s" % (env1, env1scripts, env1lib)

        env2 = os.path.join(dirname, "env2")
        os.makedirs(os.path.join(env2, "conda-meta"))
        env2scripts = os.path.join(env2, scripts)
        os.makedirs(env2scripts)
        env2lib = os.path.join(env2, library)
        os.makedirs(env2lib)

        env2path = "%s\\;%s\\;%s\\" % (env2, env2scripts, env2lib)
        env2path_no_slashes = "%s;%s;%s" % (env2, env2scripts, env2lib)

        notenv = os.path.join(dirname, "notenv\\")
        notenvscripts = os.path.join(notenv, scripts)
        os.makedirs(notenvscripts)
        notenvlib = os.path.join(notenv, library)
        os.makedirs(notenvlib)

        notenvpath = "%s\\;%s\\;%s\\" % (notenv, notenvscripts, notenvlib)
        notenvpath_no_slashes = "%s;%s;%s" % (notenv, notenvscripts, notenvlib)

        # add env to empty path
        path = conda_api.set_conda_env_in_path("", env1)
        assert env1path_no_slashes == path
        # add env that's already there
        path = conda_api.set_conda_env_in_path(env1path, env1)
        assert env1path_no_slashes == path
        # we can set a non-env because we don't waste time checking it
        path = conda_api.set_conda_env_in_path("", notenv)
        assert notenvpath_no_slashes == path
        # add an env to a non-env
        path = conda_api.set_conda_env_in_path(notenvpath, env1)
        assert (env1path_no_slashes + os.pathsep + notenvpath) == path
        # add an env to another env
        path = conda_api.set_conda_env_in_path(env1path, env2)
        assert env2path_no_slashes == path
        # replace an env that wasn't at the front
        path = conda_api.set_conda_env_in_path(
            notenvpath + os.pathsep + env2path, env1)
        assert (env1path_no_slashes + os.pathsep + notenvpath) == path
        # keep a bunch of random stuff
        random_stuff = "foo;bar;/baz/boo"
        path = conda_api.set_conda_env_in_path(random_stuff, env1)
        assert (env1path_no_slashes + os.pathsep + random_stuff) == path
Exemple #2
0
    def provide(self, requirement, context):
        """Override superclass to create or update our environment."""
        assert 'PATH' in context.environ
        conda = new_conda_manager(context.frontend)

        # set from the inherited vale if necessary
        if context.status.analysis.config['source'] == 'inherited':
            context.environ[
                requirement.env_var] = context.status.analysis.config['value']

        # set the env var (but not PATH, etc. to fully activate, that's done below)
        super_result = super(CondaBootstrapEnvProvider,
                             self).provide(requirement, context)

        project_dir = context.environ['PROJECT_DIR']

        env_name = context.status.analysis.config.get(
            'env_name', context.default_env_spec_name)
        env_spec = requirement.env_specs.get(env_name)

        prefix = os.path.join(project_dir, 'envs', 'bootstrap-env')

        # if the value has changed, choose the matching env spec
        # (something feels wrong here; should this be in read_config?
        # or not at all?)
        for env in requirement.env_specs.values():
            if env.path(project_dir) == prefix:
                env_spec = env
                break

        if context.mode != PROVIDE_MODE_CHECK:
            # we update the environment in both prod and dev mode

            # TODO if not creating a named env, we could use the
            # shared packages, but for now we leave it alone
            assert env_spec is not None
            try:
                conda.fix_environment_deviations(prefix, env_spec, create=True)
            except CondaManagerError as e:
                return super_result.copy_with_additions(errors=[str(e)])

        conda_api.environ_set_prefix(context.environ,
                                     prefix,
                                     varname=requirement.env_var)

        path = context.environ.get("PATH", "")

        context.environ["PATH"] = conda_api.set_conda_env_in_path(path, prefix)
        # Some stuff can only be done when a shell is launched:
        #  - we can't set PS1 because it shouldn't be exported.
        #  - we can't run conda activate scripts because they are sourced.
        # We can do these in the output of our activate command, but not here.

        return super_result
    def check_conda_env_in_path_unix(dirname):
        env1 = os.path.join(dirname, "env1")
        os.makedirs(os.path.join(env1, "conda-meta"))
        env1bin = os.path.join(env1, "bin")
        os.makedirs(env1bin)
        env2 = os.path.join(dirname, "env2")
        os.makedirs(os.path.join(env2, "conda-meta"))
        env2bin = os.path.join(env2, "bin")
        os.makedirs(env2bin)
        notenv = os.path.join(dirname, "notenv")
        notenvbin = os.path.join(notenv, "bin")
        os.makedirs(notenvbin)

        # add env to empty path
        path = conda_api.set_conda_env_in_path("", env1)
        assert env1bin == path
        # add env that's already there
        path = conda_api.set_conda_env_in_path(env1bin, env1)
        assert env1bin == path
        # we can set a non-env because we don't waste time checking it
        path = conda_api.set_conda_env_in_path("", notenv)
        assert notenvbin == path
        # add an env to a non-env
        path = conda_api.set_conda_env_in_path(notenvbin, env1)
        assert (env1bin + os.pathsep + notenvbin) == path
        # add an env to another env
        path = conda_api.set_conda_env_in_path(env1bin, env2)
        assert env2bin == path
        # replace an env that wasn't at the front
        path = conda_api.set_conda_env_in_path(
            notenvbin + os.pathsep + env2bin, env1)
        assert (env1bin + os.pathsep + notenvbin) == path
        # keep a bunch of random stuff
        random_stuff = "foo:bar/:/baz/boo/"
        path = conda_api.set_conda_env_in_path(random_stuff, env1)
        assert (env1bin + os.pathsep + random_stuff) == path
    def provide(self, requirement, context):
        """Override superclass to create or update our environment."""
        assert 'PATH' in context.environ

        conda = new_conda_manager(context.frontend)

        # set from the inherited vale if necessary
        if context.status.analysis.config['source'] == 'inherited':
            context.environ[
                requirement.env_var] = context.status.analysis.config['value']

        # set the env var (but not PATH, etc. to fully activate, that's done below)
        super_result = super(CondaEnvProvider,
                             self).provide(requirement, context)

        project_dir = context.environ['PROJECT_DIR']

        env_name = context.status.analysis.config.get(
            'env_name', context.default_env_spec_name)
        env_spec = requirement.env_specs.get(env_name)

        if env_name == 'bootstrap-env':
            # The bootstrap environment is always stored in the project directory
            # TODO: have this respect ANACONDA_PROJECT_ENVS_PATH
            prefix = os.path.join(project_dir, 'envs', 'bootstrap-env')
        elif context.status.analysis.config['source'] == 'inherited':
            prefix = context.environ.get(requirement.env_var, None)
            inherited = True
        else:
            prefix = None
            inherited = False

        if prefix is None:
            # use the default environment
            prefix = env_spec.path(project_dir)

        assert prefix is not None

        # if the value has changed, choose the matching env spec
        # (something feels wrong here; should this be in read_config?
        # or not at all?)
        for env in requirement.env_specs.values():
            if env.path(project_dir) == prefix:
                env_spec = env
                break

        if context.mode != PROVIDE_MODE_CHECK:
            # we update the environment in both prod and dev mode
            # TODO if not creating a named env, we could use the
            # shared packages, but for now we leave it alone
            assert env_spec is not None

            deviations = conda.find_environment_deviations(prefix, env_spec)

            readonly_policy = os.environ.get(
                'ANACONDA_PROJECT_READONLY_ENVS_POLICY', 'fail').lower()

            if deviations.unfixable and readonly_policy in ('clone',
                                                            'replace'):
                # scan for writable path
                destination = env_spec.path(project_dir,
                                            reset=True,
                                            force_writable=True)
                if destination != prefix:
                    if readonly_policy == 'replace':
                        print('Replacing the readonly environment {}'.format(
                            prefix))
                        deviations = conda.find_environment_deviations(
                            destination, env_spec)
                    else:
                        print('Cloning the readonly environment {}'.format(
                            prefix))
                        conda_api.clone(
                            destination,
                            prefix,
                            stdout_callback=context.frontend.partial_info,
                            stderr_callback=context.frontend.partial_error)
                    prefix = destination

            try:
                conda.fix_environment_deviations(prefix,
                                                 env_spec,
                                                 create=(not inherited))
            except CondaManagerError as e:
                return super_result.copy_with_additions(errors=[str(e)])

        conda_api.environ_set_prefix(context.environ,
                                     prefix,
                                     varname=requirement.env_var)

        path = context.environ.get("PATH", "")

        context.environ["PATH"] = conda_api.set_conda_env_in_path(path, prefix)
        # Some stuff can only be done when a shell is launched:
        #  - we can't set PS1 because it shouldn't be exported.
        #  - we can't run conda activate scripts because they are sourced.
        # We can do these in the output of our activate command, but not here.

        return super_result