Install pip deps from lockfile (#1908)

This commit is contained in:
Jakob van Santen 2022-09-12 15:35:18 +02:00 committed by GitHub
parent 94d31222df
commit 94c179d6ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 138 additions and 20 deletions

View File

@ -49,7 +49,7 @@ See the [repoquery documentation](https://mamba.readthedocs.io/en/latest/user_gu
### Installing lock files
`micromamba` can be used to install lock files generated by [conda-lock](https://conda-incubator.github.io/conda-lock/) without having to install `conda-lock`.
`micromamba` can be used to install lock files generated by [conda-lock](https://conda-incubator.github.io/conda-lock/) without having to install `conda-lock`. Simply invoke e.g. `micromamba create -n my-env -f conda-lock.yml` with an environment lockfile named `*-lock.yml` or `*-lock.yaml`.
### provision-with-micromamba (setup-miniconda replacement)

View File

@ -27,6 +27,7 @@
#include "thread_utils.hpp"
#include "transaction_context.hpp"
#include "env_lockfile.hpp"
#include "mamba/api/install.hpp"
extern "C"
{
@ -170,13 +171,17 @@ namespace mamba
bool m_force_reinstall = false;
};
MTransaction create_explicit_transaction_from_urls(MPool& pool,
const std::vector<std::string>& urls,
MultiPackageCache& package_caches);
MTransaction create_explicit_transaction_from_urls(
MPool& pool,
const std::vector<std::string>& urls,
MultiPackageCache& package_caches,
std::vector<detail::other_pkg_mgr_spec>& other_specs);
MTransaction create_explicit_transaction_from_lockfile(MPool& pool,
const fs::u8path& env_lockfile_path,
MultiPackageCache& package_caches);
MTransaction create_explicit_transaction_from_lockfile(
MPool& pool,
const fs::u8path& env_lockfile_path,
MultiPackageCache& package_caches,
std::vector<detail::other_pkg_mgr_spec>& other_specs);
} // namespace mamba
#endif // MAMBA_TRANSACTION_HPP

View File

@ -38,7 +38,16 @@ namespace mamba
const std::unordered_map<std::string, command_args> other_pkg_mgr_install_instructions{
{ "pip",
{ get_python_path(), "-m", "pip", "install", "-r", spec_file, "--no-input" } }
{ get_python_path(), "-m", "pip", "install", "-r", spec_file, "--no-input" } },
{ "pip --no-deps",
{ get_python_path(),
"-m",
"pip",
"install",
"--no-deps",
"-r",
spec_file,
"--no-input" } }
};
auto found_it = other_pkg_mgr_install_instructions.find(name);
@ -554,9 +563,10 @@ namespace mamba
MRepo::create(
pool, prefix_data); // Potentially re-alloc (moves in memory) Solvables in the pool
std::vector<detail::other_pkg_mgr_spec> others;
// Note that the Transaction will gather the Solvables,
// so they must have been ready in the pool before this line
auto transaction = create_transaction(pool, pkg_caches);
auto transaction = create_transaction(pool, pkg_caches, others);
if (ctx.json)
transaction.log_json();
@ -567,6 +577,11 @@ namespace mamba
detail::create_target_directory(ctx.target_prefix);
transaction.execute(prefix_data);
for (auto other_spec : others)
{
install_for_other_pkgmgr(other_spec);
}
}
}
}
@ -574,16 +589,18 @@ namespace mamba
void install_explicit_specs(const std::vector<std::string>& specs, bool create_env)
{
detail::install_explicit_with_transaction(
[&](auto& pool, auto& pkg_caches)
{ return create_explicit_transaction_from_urls(pool, specs, pkg_caches); },
[&](auto& pool, auto& pkg_caches, auto& others)
{ return create_explicit_transaction_from_urls(pool, specs, pkg_caches, others); },
create_env);
}
void install_lockfile_specs(const fs::u8path& lockfile, bool create_env)
{
detail::install_explicit_with_transaction(
[&](auto& pool, auto& pkg_caches)
{ return create_explicit_transaction_from_lockfile(pool, lockfile, pkg_caches); },
[&](auto& pool, auto& pkg_caches, auto& others) {
return create_explicit_transaction_from_lockfile(
pool, lockfile, pkg_caches, others);
},
create_env);
}

View File

@ -30,7 +30,8 @@ namespace mamba
return optional_node.as<bool>();
return false;
}(),
/* .category = */ package_node["category"].as<std::string>(),
/* .category = */
package_node["category"] ? package_node["category"].as<std::string>() : "main",
/* .manager = */ package_node["manager"].as<std::string>(),
/* .platform = */ package_node["platform"].as<std::string>(),
};

View File

@ -1527,9 +1527,11 @@ namespace mamba
t.print(std::cout);
}
MTransaction create_explicit_transaction_from_urls(MPool& pool,
const std::vector<std::string>& urls,
MultiPackageCache& package_caches)
MTransaction create_explicit_transaction_from_urls(
MPool& pool,
const std::vector<std::string>& urls,
MultiPackageCache& package_caches,
std::vector<detail::other_pkg_mgr_spec>& other_specs)
{
std::vector<MatchSpec> specs_to_install;
for (auto& u : urls)
@ -1558,9 +1560,11 @@ namespace mamba
return MTransaction(pool, {}, specs_to_install, package_caches);
}
MTransaction create_explicit_transaction_from_lockfile(MPool& pool,
const fs::u8path& env_lockfile_path,
MultiPackageCache& package_caches)
MTransaction create_explicit_transaction_from_lockfile(
MPool& pool,
const fs::u8path& env_lockfile_path,
MultiPackageCache& package_caches,
std::vector<detail::other_pkg_mgr_spec>& other_specs)
{
const auto maybe_lockfile = read_environment_lockfile(env_lockfile_path);
if (!maybe_lockfile)
@ -1575,6 +1579,24 @@ namespace mamba
const auto packages = lockfile_data.get_packages_for(
default_category, Context::instance().platform, default_manager);
// extract pip packages
{
const auto pip_packages = lockfile_data.get_packages_for(
default_category, Context::instance().platform, "pip");
if (!pip_packages.empty())
{
std::vector<std::string> pip_specs;
for (const auto& package : pip_packages)
{
pip_specs.push_back(package.name + " @ " + package.url
+ "#sha256=" + package.sha256);
}
other_specs.push_back({ "pip --no-deps",
pip_specs,
fs::absolute(env_lockfile_path.parent_path()).string() });
}
}
return MTransaction{ pool, packages, package_caches };
}

View File

@ -186,4 +186,28 @@ package:
platform: win-64
url: https://conda.anaconda.org/conda-forge/win-64/zlib-1.2.11-h8ffe710_1013.tar.bz2
version: 1.2.11
- dependencies:
anyio: '>=3.0.0,<4'
hash:
sha256: 26a18cbda5e6b651c964c12c88b36d9898481cd428ed6e063f5f29c418f73050
manager: pip
name: starlette
platform: linux-64
source: null
url: https://files.pythonhosted.org/packages/32/57/e9c68acc2845ee4ca66202d19856f6a3581cab2a885d25d490103270ffa2/starlette-0.17.1-py3-none-any.whl
version: 0.17.1
category: main
- dependencies:
asgiref: '>=3.4.0'
click: '>=7.0'
h11: '>=0.8'
hash:
sha256: 19e2a0e96c9ac5581c01eb1a79a7d2f72bb479691acd2b8921fce48ed5b961a6
manager: pip
name: uvicorn
platform: linux-64
source: null
url: https://files.pythonhosted.org/packages/36/ab/c13847c53d0624ee5a2e19c9c8d19a8cea5f865b95d08b839fac375a9e83/uvicorn-0.17.6-py3-none-any.whl
version: 0.17.6
category: main
version: 1

View File

@ -0,0 +1,33 @@
version: 1
# TODO: change the metadata to make them valid/matching actual locked env
metadata:
channels:
- url: conda-forge
used_env_vars: []
- url: defaults
used_env_vars: []
content_hash:
linux-64: 1173e3c96ce20d063a5701b325b76deb97394f891af270af4ee0cb7cc1f6e838
osx-64: d01c1f5433f30bdbcd3bdad8d9b096774ab55f1210c094acdc61a35b32b28d67
win-64: 310b23581083bfb983927c40d3bdc86162192d7b26ffd7bffc385f627c155697
platforms:
- linux-64
- osx-64
- win-64
sources:
- environment.yml
package:
- dependencies:
vc: '>=14.1,<15.0a0'
vs2015_runtime: '>=14.16.27012'
hash:
md5: b28dd2488b4e5f892c67071acc1d0a8c
sha256: 5b7e002932c0138d78d251caae0c571d13f857ff90e7ce21d58d67073381250e
manager: conda
name: libzlib
optional: false
platform: win-64
url: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.11-h8ffe710_1013.tar.bz2
version: 1.2.11

View File

@ -66,6 +66,17 @@ namespace mamba
EXPECT_EQ(lockfile.get_all_packages().size(), 1);
}
TEST(env_lockfile, valid_one_package_implicit_category)
{
const fs::u8path lockfile_path{
"env_lockfile_test/good_one_package_missing_category-lock.yaml"
};
const auto maybe_lockfile = read_environment_lockfile(lockfile_path);
ASSERT_TRUE(maybe_lockfile) << maybe_lockfile.error().what();
const auto lockfile = maybe_lockfile.value();
EXPECT_EQ(lockfile.get_all_packages().size(), 1);
}
TEST(env_lockfile, valid_multiple_packages_succeed)
{
const fs::u8path lockfile_path{ "env_lockfile_test/good_multiple_packages-lock.yaml" };
@ -85,6 +96,11 @@ namespace mamba
EXPECT_FALSE(packages.empty());
EXPECT_GT(packages.size(), 4);
}
{
const auto packages = lockfile.get_packages_for("main", "linux-64", "pip");
EXPECT_FALSE(packages.empty());
EXPECT_EQ(packages.size(), 2);
}
}