diff --git a/conda/cli/install.py b/conda/cli/install.py index b4da9458e15..acae23e1306 100644 --- a/conda/cli/install.py +++ b/conda/cli/install.py @@ -10,6 +10,9 @@ from __future__ import annotations +from rattler import install as rattler_install +from rattler import RepoDataRecord, PackageRecord + import os from logging import getLogger from os.path import abspath, basename, exists, isdir @@ -309,8 +312,8 @@ def ensure_update_specs_exist(prefix: str, specs: list[str]): if not prefix_data.get(spec.name, None): raise PackageNotInstalledError(prefix, spec.name) - -def install(args, parser, command="install"): + +async def install(args, parser, command="install"): """Logic for `conda install`, `conda update`, and `conda create`.""" newenv = command == "create" isupdate = command == "update" @@ -389,7 +392,7 @@ def install(args, parser, command="install"): command=args.cmd, ) try: - unlink_link_transaction = solver.solve_for_transaction( + solved_diff = solver.solve_for_diff( deps_modifier=deps_modifier, update_modifier=update_modifier, force_reinstall=context.force_reinstall or context.force, @@ -401,7 +404,7 @@ def install(args, parser, command="install"): if not getattr(e, "allow_retry", True): raise e if _should_retry_unfrozen: - unlink_link_transaction = solver.solve_for_transaction( + solved_diff = solver.solve_for_diff( deps_modifier=deps_modifier, update_modifier=UpdateModifier.UPDATE_SPECS, force_reinstall=context.force_reinstall or context.force, @@ -416,7 +419,7 @@ def install(args, parser, command="install"): raise CondaImportError(str(e)) raise e - handle_txn(unlink_link_transaction, prefix, args, newenv) + await handle_txn_for_diff(solved_diff, prefix, args, newenv) def install_clone(args, parser): @@ -566,3 +569,47 @@ def handle_txn(unlink_link_transaction, prefix, args, newenv, remove_op=False): if context.json: actions = unlink_link_transaction._make_legacy_action_groups()[0] common.stdout_json_success(prefix=prefix, actions=actions) + + +async def handle_txn_for_diff(solved_diff, prefix, args, newenv, remove_op=False): + # Note: + # - benchmark with --json output + # - doesn't do dry run, or download only + if newenv: + if context.subdir != context._native_subdir(): + set_keys( + ("subdir", context.subdir), + path=Path(prefix, DEFAULT_CONDARC_FILENAME), + ) + + prefix_data = PrefixData(prefix) + installed = [ + PackageRecord( + name=rec.name, version=rec.version, build=rec.build, + build_number=rec.build_number, subdir=rec.subdir, arch=None, + platform=None + ) + for rec in prefix_data.iter_records() + ] + + records_repodata_records = [] + for rec in solved_diff[1]: + pkg_rec = PackageRecord( + name=rec.name, version=rec.version, build=rec.build, + build_number=rec.build_number, subdir=rec.subdir, arch=None, + platform=None + ) + records_repodata_records.append(RepoDataRecord( + package_record=pkg_rec, + file_name=rec.url.split("/")[-1], + channel=str(rec.channel), + url=rec.url + )) + + await rattler_install( + records = records_repodata_records, + target_prefix=prefix, + installed_packages=installed, + ) + + diff --git a/conda/cli/main_create.py b/conda/cli/main_create.py index a5b8d4b8cbc..e4e77623f76 100644 --- a/conda/cli/main_create.py +++ b/conda/cli/main_create.py @@ -6,7 +6,7 @@ """ from __future__ import annotations - +import asyncio from logging import getLogger from typing import TYPE_CHECKING @@ -167,7 +167,7 @@ def execute(args: Namespace, parser: ArgumentParser) -> int: if args.clone: install_clone(args, parser) else: - install(args, parser, "create") + asyncio.run(install(args, parser, "create")) # Run post-install steps applicable to all new environments prefix_data.set_nonadmin() print_activate(args.name or context.target_prefix)