diff --git a/Cargo.lock b/Cargo.lock index cbb7b057e..4ba8f1ca4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,9 +72,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.7" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd2405b3ac1faab2990b74d728624cd9fd115651fcecc7c2d8daf01376275ba" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" dependencies = [ "anstyle", "anstyle-parse", @@ -168,9 +168,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc2d0cfb2a7388d34f590e76686704c494ed7aaceed62ee1ba35cbf363abc2a5" +checksum = "a116f46a969224200a0a97f29cfd4c50e7534e4b4826bd23ea2c3c533039c82c" dependencies = [ "bzip2", "flate2", @@ -433,9 +433,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bitvec" @@ -662,9 +662,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.17" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80932e03c33999b9235edb8655bc9df3204adc9887c2f95b50cb1deb9fd54253" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -672,9 +672,9 @@ dependencies = [ [[package]] name = "clap-verbosity-flag" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c90e95e5bd4e8ac34fa6f37c774b0c6f8ed06ea90c79931fd448fcf941a9767" +checksum = "b57f73ca21b17a0352944b9bb61803b6007bd911b6cccfef7153f7f0600ac495" dependencies = [ "clap", "log", @@ -682,9 +682,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.17" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c0db58c659eef1c73e444d298c27322a1b52f6927d2ad470c0c0f96fa7b8fa" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -836,7 +836,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "crossterm_winapi", "libc", "parking_lot", @@ -1006,6 +1006,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "drop_bomb" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" + [[package]] name = "dunce" version = "1.0.4" @@ -1421,9 +1427,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes 1.5.0", "fnv", @@ -1464,9 +1470,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" [[package]] name = "hex" @@ -1941,7 +1947,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libc", "redox_syscall", ] @@ -1967,7 +1973,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "761e49ec5fd8a5a463f9b84e877c373d888935b71c6be78f3767fe2ae6bed18e" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libc", ] @@ -1979,9 +1985,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -2190,7 +2196,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "libc", ] @@ -2343,7 +2349,7 @@ version = "0.10.62" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "foreign-types", "libc", @@ -2741,9 +2747,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "plist" @@ -2935,17 +2941,19 @@ dependencies = [ [[package]] name = "rattler" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "anyhow", - "async-compression 0.4.5", + "async-compression 0.4.6", "bytes 1.5.0", "chrono", "digest", "dirs", + "drop_bomb", "futures 0.3.30", "fxhash", "hex", + "indexmap 2.1.0", "itertools 0.11.0", "memchr", "memmap2 0.7.1", @@ -2976,7 +2984,7 @@ dependencies = [ [[package]] name = "rattler_conda_types" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "chrono", "fxhash", @@ -3020,7 +3028,7 @@ dependencies = [ [[package]] name = "rattler_digest" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "blake2", "digest", @@ -3093,7 +3101,7 @@ dependencies = [ [[package]] name = "rattler_lock" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "chrono", "fxhash", @@ -3114,7 +3122,7 @@ dependencies = [ [[package]] name = "rattler_macros" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "quote", "syn 2.0.48", @@ -3123,7 +3131,7 @@ dependencies = [ [[package]] name = "rattler_networking" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "anyhow", "dirs", @@ -3147,7 +3155,7 @@ dependencies = [ [[package]] name = "rattler_package_streaming" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "bzip2", "chrono", @@ -3172,10 +3180,10 @@ dependencies = [ [[package]] name = "rattler_repodata_gateway" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "anyhow", - "async-compression 0.4.5", + "async-compression 0.4.6", "blake2", "cache_control", "chrono", @@ -3210,7 +3218,7 @@ dependencies = [ [[package]] name = "rattler_shell" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "enum_dispatch", "indexmap 2.1.0", @@ -3227,7 +3235,7 @@ dependencies = [ [[package]] name = "rattler_solve" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "anyhow", "chrono", @@ -3246,7 +3254,7 @@ dependencies = [ [[package]] name = "rattler_virtual_packages" version = "0.16.2" -source = "git+https://github.com/mamba-org/rattler?branch=main#8d94237197c87b03e61c3d5efd39889409da8909" +source = "git+https://github.com/mamba-org/rattler?branch=main#d1fec29e06e5f6ae7e36e06e510f7f7c43250ef3" dependencies = [ "cfg-if", "libloading", @@ -3262,9 +3270,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -3272,9 +3280,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3367,7 +3375,7 @@ version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "async-compression 0.4.5", + "async-compression 0.4.6", "base64", "bytes 1.5.0", "encoding_rs", @@ -3510,10 +3518,10 @@ version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", - "linux-raw-sys 0.4.12", + "linux-raw-sys 0.4.13", "windows-sys 0.52.0", ] @@ -3911,9 +3919,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" +checksum = "3b187f0231d56fe41bfb12034819dd2bf336422a5866de41bc3fec4b2e3883e8" dependencies = [ "serde", ] @@ -4509,9 +4517,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -4578,9 +4586,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" dependencies = [ "getrandom", "rand", @@ -4947,7 +4955,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", - "linux-raw-sys 0.4.12", + "linux-raw-sys 0.4.13", "rustix 0.38.30", ] diff --git a/src/cli/global/install.rs b/src/cli/global/install.rs index 14e1a59ac..2da229efb 100644 --- a/src/cli/global/install.rs +++ b/src/cli/global/install.rs @@ -431,7 +431,7 @@ pub(super) async fn globally_install_package( // Create the transaction that we need let transaction = Transaction::from_current_and_desired( - prefix_records, + prefix_records.clone(), records.iter().cloned(), Platform::current(), ) @@ -446,6 +446,7 @@ pub(super) async fn globally_install_package( "creating virtual environment", execute_transaction( &transaction, + &prefix_records, prefix.root().to_path_buf(), config::get_cache_dir()?, default_authenticated_client(), diff --git a/src/cli/shell_hook.rs b/src/cli/shell_hook.rs index e27d91624..0363cae35 100644 --- a/src/cli/shell_hook.rs +++ b/src/cli/shell_hook.rs @@ -24,7 +24,14 @@ pub struct Args { async fn generate_activation_script(shell: Option) -> miette::Result { let project = Project::discover()?; - get_up_to_date_prefix(&project, LockFileUsage::Frozen, false, None).await?; + get_up_to_date_prefix( + &project, + LockFileUsage::Frozen, + false, + None, + Default::default(), + ) + .await?; let platform = Platform::current(); let prefix = Prefix::new(project.default_environment().dir())?; diff --git a/src/environment.rs b/src/environment.rs index 5eca8ae31..440c71784 100644 --- a/src/environment.rs +++ b/src/environment.rs @@ -308,9 +308,12 @@ pub async fn update_prefix_conda( let desired_conda_packages = lock_file .get_conda_packages_by_platform(platform) .into_diagnostic()?; - let transaction = - Transaction::from_current_and_desired(installed_packages, desired_conda_packages, platform) - .into_diagnostic()?; + let transaction = Transaction::from_current_and_desired( + installed_packages.clone(), + desired_conda_packages, + platform, + ) + .into_diagnostic()?; // Execute the transaction if there is work to do if !transaction.operations.is_empty() { @@ -319,6 +322,7 @@ pub async fn update_prefix_conda( "updating environment", install::execute_transaction( &transaction, + &installed_packages, prefix.root().to_path_buf(), config::get_cache_dir()?, default_authenticated_client(), diff --git a/src/install.rs b/src/install.rs index 6ab4566e8..81ac72cb4 100644 --- a/src/install.rs +++ b/src/install.rs @@ -6,21 +6,21 @@ use crate::progress::{ use futures::future::ready; use futures::{stream, FutureExt, StreamExt, TryFutureExt, TryStreamExt}; use itertools::Itertools; -use miette::{IntoDiagnostic, WrapErr}; +use miette::IntoDiagnostic; use rattler::install::{ - link_package, InstallDriver, InstallOptions, Transaction, TransactionOperation, + link_package, unlink_package, InstallDriver, InstallOptions, Transaction, TransactionOperation, }; use rattler::package_cache::PackageCache; use rattler_conda_types::{PrefixRecord, RepoDataRecord}; use rattler_networking::AuthenticatedClient; use std::cmp::Ordering; -use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::time::Duration; /// Executes the transaction on the given environment. pub async fn execute_transaction( transaction: &Transaction, + prefix_records: &[PrefixRecord], target_prefix: PathBuf, cache_dir: PathBuf, download_client: AuthenticatedClient, @@ -29,7 +29,7 @@ pub async fn execute_transaction( let package_cache = PackageCache::new(cache_dir.join("pkgs")); // Create an install driver which helps limit the number of concurrent filesystem operations - let install_driver = InstallDriver::default(); + let install_driver = InstallDriver::new(100, Some(prefix_records)); // Define default installation options. let install_options = InstallOptions { @@ -134,6 +134,12 @@ pub async fn execute_transaction( }) .await; + // Post-process the environment installation to unclobber all files deterministically + let new_prefix_records = PrefixRecord::collect_from_prefix(&target_prefix).into_diagnostic()?; + install_driver + .post_process(&new_prefix_records, &target_prefix) + .into_diagnostic()?; + // Clear progress bars if let Some(download_pb) = download_pb { download_pb.into_progress_bar().finish_and_clear(); @@ -257,8 +263,8 @@ async fn install_package_to_environment( install_driver: &InstallDriver, install_options: &InstallOptions, ) -> miette::Result<()> { - // Link the contents of the package into our environment. This returns all the paths that were - // linked. + // Link the contents of the package into our environment. + // This returns all the paths that were linked. let paths = link_package( &package_dir, target_prefix, @@ -291,16 +297,7 @@ async fn install_package_to_environment( std::fs::create_dir_all(&conda_meta_path)?; // Write the conda-meta information - let pkg_meta_path = conda_meta_path.join(format!( - "{}-{}-{}.json", - prefix_record - .repodata_record - .package_record - .name - .as_source(), - prefix_record.repodata_record.package_record.version, - prefix_record.repodata_record.package_record.build - )); + let pkg_meta_path = conda_meta_path.join(prefix_record.file_name()); prefix_record.write_to_path(pkg_meta_path, true) }) .await @@ -321,35 +318,7 @@ async fn remove_package_from_environment( target_prefix: &Path, package: &PrefixRecord, ) -> miette::Result<()> { - // TODO: Take into account any clobbered files, they need to be restored. - // TODO: Can we also delete empty directories? - - // Remove all entries - for paths in package.paths_data.paths.iter() { - match tokio::fs::remove_file(target_prefix.join(&paths.relative_path)).await { - Ok(_) => {} - Err(e) if e.kind() == ErrorKind::NotFound => { - // Simply ignore if the file is already gone. - } - Err(e) => { - return Err(e).into_diagnostic().wrap_err(format!( - "failed to delete {}", - paths.relative_path.display() - )) - } - } - } - - // Remove the conda-meta file - let conda_meta_path = target_prefix.join("conda-meta").join(format!( - "{}-{}-{}.json", - package.repodata_record.package_record.name.as_normalized(), - package.repodata_record.package_record.version, - package.repodata_record.package_record.build - )); - tokio::fs::remove_file(conda_meta_path) + unlink_package(target_prefix, package) .await - .into_diagnostic()?; - - Ok(()) + .into_diagnostic() }