Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add link_package_from_archive #937

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
61 changes: 60 additions & 1 deletion crates/rattler/src/install/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ use rattler_conda_types::{
prefix_record::PathsEntry,
Platform,
};
use rattler_package_streaming::{fs::extract, ExtractError};
use simple_spawn_blocking::Cancelled;
use tokio::task::JoinError;
use tracing::instrument;
Expand Down Expand Up @@ -102,6 +103,14 @@ pub enum InstallError {
#[error("failed to create target directory")]
FailedToCreateTargetDirectory(#[source] std::io::Error),

/// Failed to create a temporary directory.
#[error("failed to create temporary directory")]
FailedToCreateTempDirectory(#[source] std::io::Error),

/// Failed to extract a conda package.
#[error("failed to extract conda package")]
FailedToExtractPackage(#[source] ExtractError),

/// A noarch package could not be installed because no python version was
/// specified.
#[error("cannot install noarch python package because there is no python version specified")]
Expand Down Expand Up @@ -242,6 +251,29 @@ pub struct InstallOptions {
pub apple_codesign_behavior: AppleCodeSignBehavior,
}

/// Given a non-extracted conda package (`package_path`), installs its files
/// to the `target_dir`.
///
/// Returns a [`PathsEntry`] for every file that was linked into the target
/// directory. The entries are ordered in the same order as they appear in the
/// `paths.json` file of the package.
pub async fn link_package_from_archive(
package_path: &Path,
target_dir: &Path,
driver: &InstallDriver,
options: InstallOptions,
) -> Result<Vec<PathsEntry>, InstallError> {
let temp_dir = tempfile::tempdir().map_err(InstallError::FailedToCreateTempDirectory)?;
tracing::debug!(
"extracting {} to temporary directory {}",
package_path.display(),
temp_dir.path().display()
);

extract(package_path, temp_dir.path()).map_err(InstallError::FailedToExtractPackage)?;
link_package(temp_dir.path(), target_dir, driver, options).await
}

/// Given an extracted package archive (`package_dir`), installs its files to
/// the `target_dir`.
///
Expand Down Expand Up @@ -722,7 +754,9 @@ mod test {

use crate::{
get_test_data_dir,
install::{link_package, InstallDriver, InstallOptions, PythonInfo},
install::{
link_package, link_package_from_archive, InstallDriver, InstallOptions, PythonInfo,
},
package_cache::PackageCache,
};

Expand Down Expand Up @@ -876,4 +910,29 @@ mod test {

insta::assert_yaml_snapshot!(paths);
}

#[rstest::rstest]
#[case("clobber-tar-bz2", "clobber/clobber-1-0.1.0-h4616a5c_0.tar.bz2")]
#[case("clobber-conda", "clobber/clobber-python-0.1.0-cpython.conda")]
#[tracing_test::traced_test]
#[tokio::test]
async fn test_link_package_from_archive(#[case] package: &str, #[case] package_path: &str) {
let environment_dir = tempfile::TempDir::new().unwrap();

let package_path = get_test_data_dir().join(package_path);

let install_driver = InstallDriver::default();

// Link the package
let paths = link_package_from_archive(
&package_path,
environment_dir.path(),
&install_driver,
InstallOptions::default(),
)
.await
.unwrap();

insta::assert_yaml_snapshot!(format!("link_package_from_archive-{}", package), paths);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: crates/rattler/src/install/mod.rs
assertion_line: 937
expression: paths
snapshot_kind: text
---
- _path: bin/python
path_type: hardlink
sha256: 9e13091076809d9c845dc484b21ae2ba965895705d7fec77dd51ec3af7e26e31
sha256_in_prefix: 9e13091076809d9c845dc484b21ae2ba965895705d7fec77dd51ec3af7e26e31
size_in_bytes: 8
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
source: crates/rattler/src/install/mod.rs
assertion_line: 937
expression: paths
snapshot_kind: text
---
- _path: another-clobber.txt
path_type: hardlink
sha256: dd79cf28afefb8038e9ca3141f2d47ca3c764cd50b880eb65263705792b909c8
sha256_in_prefix: dd79cf28afefb8038e9ca3141f2d47ca3c764cd50b880eb65263705792b909c8
size_in_bytes: 10
- _path: clobber.txt
path_type: hardlink
sha256: dd79cf28afefb8038e9ca3141f2d47ca3c764cd50b880eb65263705792b909c8
sha256_in_prefix: dd79cf28afefb8038e9ca3141f2d47ca3c764cd50b880eb65263705792b909c8
size_in_bytes: 10