Fixed create/install requiring pip install failing when the prefix have whitespaces on Windows (#1838)

* micromamba: add tests creating/installing with pip in prefix with whitespaces
* Fixed installing with pip when prefix have whitespaces on Windows

Co-authored-by: Jonas Haag <jonas@lophus.org>
This commit is contained in:
Klaim (Joël Lamotte) 2022-08-08 19:36:46 +02:00 committed by GitHub
parent 452a80187a
commit 0b8b9a7aab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 17 deletions

View File

@ -28,15 +28,17 @@ namespace mamba
{
namespace
{
tl::expected<std::string, std::runtime_error> get_other_pkg_mgr_install_instructions(
const std::string& name, const std::string& target_prefix)
using command_args = std::vector<std::string>;
tl::expected<command_args, std::runtime_error> get_other_pkg_mgr_install_instructions(
const std::string& name, const std::string& target_prefix, fs::path spec_file)
{
const auto get_python_path
= [&] { return env::which("python", get_path_dirs(target_prefix)).u8string(); };
const std::unordered_map<std::string, std::string> other_pkg_mgr_install_instructions{
const std::unordered_map<std::string, command_args> other_pkg_mgr_install_instructions{
{ "pip",
fmt::format("{} {}", get_python_path(), "-m pip install -r {0} --no-input") }
{ get_python_path(), "-m", "pip", "install", "-r", spec_file, "--no-input" } }
};
auto found_it = other_pkg_mgr_install_instructions.find(name);
@ -90,26 +92,25 @@ namespace mamba
const auto& ctx = Context::instance();
std::string install_instructions = [&]
TemporaryFile specs;
{
std::ofstream specs_f = open_ofstream(specs.path());
for (auto& d : deps)
specs_f << d.c_str() << '\n';
}
command_args install_instructions = [&]
{
const auto maybe_instructions
= get_other_pkg_mgr_install_instructions(pkg_mgr, ctx.target_prefix);
= get_other_pkg_mgr_install_instructions(pkg_mgr, ctx.target_prefix, specs.path());
if (maybe_instructions)
return maybe_instructions.value();
else
throw maybe_instructions.error();
}();
TemporaryFile specs;
std::ofstream specs_f = open_ofstream(specs.path());
for (auto& d : deps)
specs_f << d.c_str() << '\n';
specs_f.close();
replace_all(install_instructions, "{0}", specs.path());
std::vector<std::string> install_args = split(install_instructions, " ");
auto [wrapped_command, tmpfile] = prepare_wrapped_call(ctx.target_prefix, install_args);
auto [wrapped_command, tmpfile]
= prepare_wrapped_call(ctx.target_prefix, install_instructions);
reproc::options options;
options.redirect.parent = true;
@ -118,7 +119,7 @@ namespace mamba
Console::stream() << "\n"
<< termcolor::cyan << "Installing " << pkg_mgr
<< " packages: " << join(", ", deps) << termcolor::reset;
LOG_INFO << "Calling: " << join(" ", install_args);
LOG_INFO << "Calling: " << join(" ", install_instructions);
auto [status, ec] = reproc::run(wrapped_command, options);
assert_reproc_success(options, status, ec);

View File

@ -0,0 +1,8 @@
name: test env with spaces
channels:
- conda-forge
dependencies:
- python=3.9
- pip
- pip:
- pydantic

View File

@ -0,0 +1,8 @@
name: test_env
channels:
- conda-forge
dependencies:
- python=3.9
- pip
- pip:
- pydantic

View File

@ -13,6 +13,21 @@ from .helpers import *
source_dir_path = os.path.dirname(os.path.realpath(__file__))
this_source_file_dir_path = Path(__file__).parent.resolve()
test_env_requires_pip_install_path = os.path.join(
this_source_file_dir_path, "env-requires-pip-install.yaml"
)
test_env_requires_pip_install_path_with_whitespaces = os.path.join(
this_source_file_dir_path, "env-requires-pip-install-with-spaces.yaml"
)
test_envs = [
test_env_requires_pip_install_path,
test_env_requires_pip_install_path_with_whitespaces,
]
class TestCreate:
@ -641,3 +656,15 @@ class TestCreate:
create(*cmd)
assert (site_packages / pyc_fn).exists()
assert pyc_fn.name in six_meta
@pytest.mark.parametrize("env_file", test_envs)
def test_requires_pip_install(self, env_file):
prefix = Path(TestCreate.prefix)
cmd = ["-p", f"{prefix}", "-f", env_file]
create(*cmd)
@pytest.mark.parametrize("env_file", test_envs)
def test_requires_pip_install_prefix_spaces(self, env_file):
prefix = Path(f"{TestCreate.prefix} with space")
cmd = ["-p", f"{prefix}", "-f", env_file]
create(*cmd)