Skip to content

Commit

Permalink
feat: List PyPI packages in environment export (#3623)
Browse files Browse the repository at this point in the history
Signed-off-by: Julien Jerphanion <git@jjerphan.xyz>
Co-authored-by: Johan Mabille <johan.mabille@gmail.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 21, 2024
1 parent d4de99b commit 7b0a957
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
30 changes: 28 additions & 2 deletions micromamba/src/env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ set_env_command(CLI::App* com, Configuration& config)
History& hist = pd.history();

const auto& versions_map = pd.records();
const auto& pip_versions_map = pd.pip_records();
auto requested_specs_map = hist.get_requested_specs_map();
std::stringstream dependencies;
std::set<std::string> channels;
Expand Down Expand Up @@ -227,6 +228,21 @@ set_env_command(CLI::App* com, Configuration& config)
channels.insert(chan.display_name());
}
}

// Add a `pip` subsection in `dependencies` listing wheels installed from PyPI
if (!pip_versions_map.empty())
{
dependencies << (first_dependency_printed ? ",\n" : "") << " { \"pip\": [\n";
first_dependency_printed = false;
for (const auto& [k, v] : pip_versions_map)
{
dependencies << (first_dependency_printed ? ",\n" : "") << " \""
<< v.name << "==" << v.version << "\"";
first_dependency_printed = true;
}
dependencies << "\n ]\n }";
}

dependencies << (first_dependency_printed ? "\n" : "");

std::cout << "{\n";
Expand Down Expand Up @@ -255,6 +271,7 @@ set_env_command(CLI::App* com, Configuration& config)
History& hist = pd.history();

const auto& versions_map = pd.records();
const auto& pip_versions_map = pd.pip_records();

std::cout << "name: " << get_env_name(ctx, ctx.prefix_params.target_prefix) << "\n";
std::cout << "channels:\n";
Expand All @@ -278,7 +295,7 @@ set_env_command(CLI::App* com, Configuration& config)
}
else
{
dependencies << "- ";
dependencies << " - ";
if (channel_subdir)
{
dependencies
Expand All @@ -303,10 +320,19 @@ set_env_command(CLI::App* com, Configuration& config)
channels.insert(chan.display_name());
}
}
// Add a `pip` subsection in `dependencies` listing wheels installed from PyPI
if (!pip_versions_map.empty())
{
dependencies << " - pip:\n";
for (const auto& [k, v] : pip_versions_map)
{
dependencies << " - " << v.name << "==" << v.version << "\n";
}
}

for (const auto& c : channels)
{
std::cout << "- " << c << "\n";
std::cout << " - " << c << "\n";
}
std::cout << "dependencies:\n" << dependencies.str() << std::endl;

Expand Down
35 changes: 35 additions & 0 deletions micromamba/tests/test_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,3 +484,38 @@ def test_env_update_empty_base(tmp_home, tmp_root_prefix, tmp_path):
packages = helpers.umamba_list("-p", env_prefix, "--json")
assert any(package["name"] == "xtensor" for package in packages)
assert any(package["name"] == "python" for package in packages)


env_yaml_content_env_export_with_pip = """
channels:
- conda-forge
dependencies:
- pip
- pip:
- requests==2.32.3
"""


@pytest.mark.parametrize("json_flag", [None, "--json"])
def test_env_export_with_pip(tmp_path, json_flag):
env_name = "env_export_with_pip"

env_file_yml = tmp_path / "test_env_yaml_content_to_install_requests_with_pip.yaml"
env_file_yml.write_text(env_yaml_content_env_export_with_pip)

flags = list(filter(None, [json_flag]))
helpers.create("-n", env_name, "-f", env_file_yml, no_dry_run=True)

output = helpers.run_env("export", "-n", env_name, *flags)

# JSON is already parsed
ret = output if json_flag else yaml.safe_load(output)

assert ret["name"] == env_name
assert env_name in ret["prefix"]
assert set(ret["channels"]) == {"conda-forge"}

pip_section = next(
dep for dep in ret["dependencies"] if isinstance(dep, dict) and ["pip"] == [*dep]
)
assert pip_section["pip"] == ["requests==2.32.3"]

0 comments on commit 7b0a957

Please sign in to comment.