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
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