diff --git a/crates/rattler/src/install/clobber_registry.rs b/crates/rattler/src/install/clobber_registry.rs index 3c9a62570..16426025c 100644 --- a/crates/rattler/src/install/clobber_registry.rs +++ b/crates/rattler/src/install/clobber_registry.rs @@ -1173,4 +1173,70 @@ mod tests { assert_check_files(&target_prefix.path().join("bin"), &["python"]); } + + // This used to hit an expect in the clobbering code + #[tokio::test] + async fn test_directory_clobber() { + // Create a transaction + let repodata_record_with_dir = get_repodata_record( + get_test_data_dir().join("clobber/clobber-with-dir-0.1.0-h4616a5c_0.conda"), + ); + let repodata_record_without_dir = get_repodata_record( + get_test_data_dir().join("clobber/clobber-without-dir-0.1.0-h4616a5c_0.conda"), + ); + + let transaction = transaction::Transaction:: { + operations: vec![TransactionOperation::Install(repodata_record_with_dir)], + python_info: None, + current_python_info: None, + platform: Platform::current(), + }; + + // execute transaction + let target_prefix = tempfile::tempdir().unwrap(); + + let packages_dir = tempfile::tempdir().unwrap(); + let cache = PackageCache::new(packages_dir.path()); + + execute_transaction( + transaction, + target_prefix.path(), + &reqwest_middleware::ClientWithMiddleware::from(reqwest::Client::new()), + &cache, + &InstallDriver::default(), + &InstallOptions::default(), + ) + .await; + + let prefix_records = PrefixRecord::collect_from_prefix(target_prefix.path()).unwrap(); + + // remove one of the clobbering files + let transaction = transaction::Transaction:: { + operations: vec![ + TransactionOperation::Remove( + prefix_records[0].clone(), + ), + TransactionOperation::Install(repodata_record_without_dir), + ], + python_info: None, + current_python_info: None, + platform: Platform::current(), + }; + + let install_driver = InstallDriver::builder() + .with_prefix_records(&prefix_records) + .finish(); + + execute_transaction( + transaction, + target_prefix.path(), + &reqwest_middleware::ClientWithMiddleware::from(reqwest::Client::new()), + &cache, + &install_driver, + &InstallOptions::default(), + ) + .await; + + assert_check_files(&target_prefix.path(), &["dir"]); + } } diff --git a/test-data/clobber/clobber-with-dir-0.1.0-h4616a5c_0.conda b/test-data/clobber/clobber-with-dir-0.1.0-h4616a5c_0.conda new file mode 100644 index 000000000..339b889d0 Binary files /dev/null and b/test-data/clobber/clobber-with-dir-0.1.0-h4616a5c_0.conda differ diff --git a/test-data/clobber/clobber-without-dir-0.1.0-h4616a5c_0.conda b/test-data/clobber/clobber-without-dir-0.1.0-h4616a5c_0.conda new file mode 100644 index 000000000..1380136d2 Binary files /dev/null and b/test-data/clobber/clobber-without-dir-0.1.0-h4616a5c_0.conda differ diff --git a/test-data/clobber/recipe/recipe-with-dir.yaml b/test-data/clobber/recipe/recipe-with-dir.yaml new file mode 100644 index 000000000..29151a6ba --- /dev/null +++ b/test-data/clobber/recipe/recipe-with-dir.yaml @@ -0,0 +1,23 @@ +recipe: + name: clobber-with-dir + version: 0.1.0 + +outputs: + - package: + name: clobber-with-dir + version: 0.1.0 + + build: + noarch: generic + script: + - mkdir $PREFIX/dir + - echo "clobber-1" > $PREFIX/dir/clobber.txt + + - package: + name: clobber-without-dir + version: 0.1.0 + + build: + noarch: generic + script: + - echo "clobber-1" > $PREFIX/dir