Merge pull request #1048 from adriendelsalle/freeze-installed

This commit is contained in:
Wolf Vollprecht 2021-06-30 22:48:58 +02:00 committed by GitHub
commit 5908630dcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 65 additions and 10 deletions

View File

@ -4,6 +4,7 @@
New features
- remove orphaned packages such as dependencies of explicitely installed packages (@adriendelsalle) #1040
- add a diff character before package name in transaction table to improve readability without coloration (@adriendelsalle) #1040
- add capability to freeze installed packages during `install` operation using `--freeze-installed` flag (@adriendelsalle) #1048
0.14.1 (June 25, 2021)
======================

View File

@ -189,6 +189,7 @@ namespace mamba
bool override_channels_enabled = true;
std::vector<std::string> pinned_packages = {};
bool freeze_installed = false;
bool use_only_tar_bz2 = false;

View File

@ -497,9 +497,8 @@ def install(args, parser, command="install"):
repos = []
if use_mamba_experimental or context.force_reinstall:
prefix_data = api.PrefixData(context.target_prefix)
prefix_data.load()
prefix_data = api.PrefixData(context.target_prefix)
prefix_data.load()
# add installed
if use_mamba_experimental:
@ -534,6 +533,10 @@ def install(args, parser, command="install"):
(api.MAMBA_FORCE_REINSTALL, context.force_reinstall),
]
)
if context.update_modifier is UpdateModifier.FREEZE_INSTALLED:
solver.add_jobs([p for p in prefix_data.package_records], api.SOLVER_LOCK)
solver.add_jobs(mamba_solve_specs, solver_task)
if not context.force_reinstall:

View File

@ -650,6 +650,10 @@ namespace mamba
.set_env_var_name()
.description("A list of package specs to pin for every environment resolution"));
insert(Configurable("freeze_installed", &ctx.freeze_installed)
.group("Solver")
.description("Freeze already installed dependencies"));
insert(Configurable("retry_clean_cache", false)
.group("Solver")
.set_env_var_name()

View File

@ -395,6 +395,11 @@ namespace mamba
}
PrefixData prefix_data(ctx.target_prefix);
prefix_data.load();
std::vector<std::string> prefix_pkgs;
for (auto& it : prefix_data.m_package_records)
prefix_pkgs.push_back(it.first);
prefix_data.add_virtual_packages(get_virtual_packages());
auto repo = MRepo(pool, prefix_data);
@ -453,6 +458,13 @@ namespace mamba
}
MSolver solver(pool, { { SOLVER_FLAG_ALLOW_DOWNGRADE, 1 } });
if (ctx.freeze_installed && !prefix_pkgs.empty())
{
LOG_INFO << "Locking environment: " << prefix_pkgs.size() << " packages freezed";
solver.add_jobs(prefix_pkgs, SOLVER_LOCK);
}
solver.add_jobs(specs, solver_flag);
if (!no_pin)
@ -486,6 +498,9 @@ namespace mamba
ctx.local_repodata_ttl = 2;
return install_specs(specs, create_env, solver_flag, is_retry | RETRY_SOLVE_ERROR);
}
if (ctx.freeze_installed)
Console::print("Possible hints:\n - 'freeze_installed' is turned on\n");
throw std::runtime_error("Could not solve for environment specs");
}

View File

@ -153,13 +153,13 @@ namespace mamba
{
m_install_specs.emplace_back(job);
}
else if (job_flag & SOLVER_ERASE)
else if (((job_flag & SOLVER_ERASE) ^ SOLVER_ERASE) != 0)
{
if (((job_flag & SOLVER_USERINSTALLED) ^ SOLVER_USERINSTALLED) == 0)
m_neuter_specs.emplace_back(job);
else
m_remove_specs.emplace_back(job);
m_remove_specs.emplace_back(job);
}
else if (((job_flag & SOLVER_LOCK) ^ SOLVER_LOCK) == 0)
m_neuter_specs.emplace_back(job);
if (!ms.channel.empty())
{
if (job_flag & SOLVER_ERASE)

View File

@ -219,8 +219,15 @@ PYBIND11_MODULE(mamba_api, m)
py::class_<PrefixData>(m, "PrefixData")
.def(py::init<const std::string&>())
.def_readwrite("package_records", &PrefixData::m_package_records)
.def("load", &PrefixData::load);
py::class_<PackageInfo>(m, "PackageInfo")
.def(py::init<Solvable*>())
.def(py::init<const std::string&>())
.def(py::init<const std::string&, const std::string&, const std::string&, std::size_t>())
.def_readwrite("name", &PackageInfo::name);
py::class_<Channel>(m, "Channel")
.def(py::init([](const std::string& value) { return &(make_channel(value)); }))
.def_property_readonly("scheme", &Channel::scheme)

View File

@ -1,5 +1,6 @@
#include "common_options.hpp"
#include "mamba/api/configuration.hpp"
#include "mamba/api/install.hpp"
@ -11,5 +12,11 @@ set_install_command(CLI::App* subcom)
{
init_install_options(subcom);
auto& config = Configuration::instance();
auto& freeze_installed = config.at("freeze_installed").get_wrapped<bool>();
subcom->add_flag(
"--freeze-installed", freeze_installed.set_cli_config(0), freeze_installed.description());
subcom->callback([&]() { install(); });
}

View File

@ -454,8 +454,6 @@ class TestInstall:
install("python=3.9", no_dry_run=True)
res = install("setuptools=28.4.0", "--no-py-pin", "--json")
print(res["actions"].keys())
print(res["actions"]["UNLINK"])
keys = {"success", "prefix", "actions", "dry_run"}
assert keys.issubset(set(res.keys()))
@ -473,3 +471,22 @@ class TestInstall:
py_pkg = [pkg for pkg in res["actions"]["UNLINK"] if pkg["name"] == "python"][0]
assert py_pkg["version"].startswith("3.9")
@pytest.mark.skipif(
dry_run_tests is DryRun.ULTRA_DRY, reason="Running only ultra-dry tests"
)
def test_freeze_installed(self):
install("xtensor=0.20", no_dry_run=True)
res = install("xframe", "--freeze-installed", "--json")
# without freeze installed, xframe 0.3.0 should be installed and xtensor updated to 0.21
keys = {"success", "prefix", "actions", "dry_run"}
assert keys.issubset(set(res.keys()))
action_keys = {"LINK", "PREFIX"}
assert action_keys.issubset(set(res["actions"].keys()))
expected_packages = {"xframe"}
link_packages = {pkg["name"] for pkg in res["actions"]["LINK"]}
assert expected_packages == link_packages
assert res["actions"]["LINK"][0]["version"] == "0.2.0"