From 725a21f88b3efd6a4bb1d9db3fc37f64676dbd12 Mon Sep 17 00:00:00 2001 From: suhr25 Date: Sat, 7 Mar 2026 06:39:28 +0000 Subject: [PATCH 1/4] fix: return error instead of panicking in sort_paths when path is not under base_path Signed-off-by: suhr25 --- crates/rattler_package_streaming/src/write.rs | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/crates/rattler_package_streaming/src/write.rs b/crates/rattler_package_streaming/src/write.rs index 70437f5d3..57422c0e1 100644 --- a/crates/rattler_package_streaming/src/write.rs +++ b/crates/rattler_package_streaming/src/write.rs @@ -70,18 +70,33 @@ impl Read for ProgressBarReader { /// a function that sorts paths into two iterators, one that starts with `info/` /// and one that does not both iterators are sorted alphabetically for /// reproducibility -fn sort_paths<'a>(paths: &'a [PathBuf], base_path: &'a Path) -> (Vec, Vec) { +fn sort_paths( + paths: &[PathBuf], + base_path: &Path, +) -> Result<(Vec, Vec), io::Error> { let info = Path::new("info/"); - let (mut info_paths, mut other_paths): (Vec<_>, Vec<_>) = paths - .iter() - .map(|p| p.strip_prefix(base_path).unwrap()) - .map(Path::to_path_buf) - .partition(|path| path.starts_with(info)); + let mut relative_paths = Vec::with_capacity(paths.len()); + for p in paths { + let rel = p.strip_prefix(base_path).map_err(|_| { + io::Error::new( + io::ErrorKind::InvalidInput, + format!( + "path '{}' is not under base path '{}'", + p.display(), + base_path.display() + ), + ) + })?; + relative_paths.push(rel.to_path_buf()); + } + + let (mut info_paths, mut other_paths): (Vec<_>, Vec<_>) = + relative_paths.into_iter().partition(|p| p.starts_with(info)); info_paths.sort(); other_paths.sort(); - (info_paths, other_paths) + Ok((info_paths, other_paths)) } fn total_size(base_path: &Path, paths: &[PathBuf]) -> u64 { @@ -146,7 +161,7 @@ pub fn write_tar_bz2_package( progress_bar_wrapper.set_total(total_size); // sort paths alphabetically, and sort paths beginning with `info/` first - let (info_paths, other_paths) = sort_paths(paths, base_path); + let (info_paths, other_paths) = sort_paths(paths, base_path)?; for path in info_paths.iter().chain(other_paths.iter()) { append_path_to_archive( &mut archive, @@ -281,7 +296,7 @@ pub fn write_conda_package( outer_archive.start_file("metadata.json", options)?; outer_archive.write_all(package_metadata.as_bytes())?; - let (info_paths, other_paths) = sort_paths(paths, base_path); + let (info_paths, other_paths) = sort_paths(paths, base_path)?; let archive_path = format!("pkg-{out_name}.tar.zst"); From f31d3d0babf6fb970676d212cb4fb4b2f7143b1c Mon Sep 17 00:00:00 2001 From: suhr25 Date: Sat, 7 Mar 2026 07:06:31 +0000 Subject: [PATCH 2/4] chore: fix lint errors in rattler_package_streaming - Gate `StreamExt` and `AsyncReadExt` imports with `#[cfg(feature = "reqwest")]` since they are only used in reqwest-gated code paths - Rename `|_|` to `|_e|` in map_err to satisfy clippy::map_err_ignore Signed-off-by: suhr25 --- crates/rattler_package_streaming/src/tokio/async_read.rs | 5 +++-- crates/rattler_package_streaming/src/write.rs | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/rattler_package_streaming/src/tokio/async_read.rs b/crates/rattler_package_streaming/src/tokio/async_read.rs index d2e51647f..2c969585e 100644 --- a/crates/rattler_package_streaming/src/tokio/async_read.rs +++ b/crates/rattler_package_streaming/src/tokio/async_read.rs @@ -6,9 +6,10 @@ use std::path::Path; use async_compression::tokio::bufread::BzDecoder; use async_spooled_tempfile::SpooledTempFile; use async_zip::base::read::stream::ZipFileReader; -use futures_util::StreamExt; -use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeekExt}; +use tokio::io::{AsyncRead, AsyncSeekExt}; use tokio_util::compat::{FuturesAsyncReadCompatExt, TokioAsyncReadCompatExt}; +#[cfg(feature = "reqwest")] +use {futures_util::StreamExt as _, tokio::io::AsyncReadExt}; use crate::{read::SizeCountingReader, ExtractError, ExtractResult}; diff --git a/crates/rattler_package_streaming/src/write.rs b/crates/rattler_package_streaming/src/write.rs index 57422c0e1..68635a363 100644 --- a/crates/rattler_package_streaming/src/write.rs +++ b/crates/rattler_package_streaming/src/write.rs @@ -77,7 +77,7 @@ fn sort_paths( let info = Path::new("info/"); let mut relative_paths = Vec::with_capacity(paths.len()); for p in paths { - let rel = p.strip_prefix(base_path).map_err(|_| { + let rel = p.strip_prefix(base_path).map_err(|_e| { io::Error::new( io::ErrorKind::InvalidInput, format!( @@ -90,8 +90,9 @@ fn sort_paths( relative_paths.push(rel.to_path_buf()); } - let (mut info_paths, mut other_paths): (Vec<_>, Vec<_>) = - relative_paths.into_iter().partition(|p| p.starts_with(info)); + let (mut info_paths, mut other_paths): (Vec<_>, Vec<_>) = relative_paths + .into_iter() + .partition(|p| p.starts_with(info)); info_paths.sort(); other_paths.sort(); From cecd516fc308ab78ad07d107023ca0d2113632cd Mon Sep 17 00:00:00 2001 From: suhr25 Date: Thu, 12 Mar 2026 02:20:31 +0000 Subject: [PATCH 3/4] Fix review: replace for loop with idiomatic iterator pattern --- crates/rattler_package_streaming/src/write.rs | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/crates/rattler_package_streaming/src/write.rs b/crates/rattler_package_streaming/src/write.rs index 68635a363..e7e97b8e3 100644 --- a/crates/rattler_package_streaming/src/write.rs +++ b/crates/rattler_package_streaming/src/write.rs @@ -75,20 +75,23 @@ fn sort_paths( base_path: &Path, ) -> Result<(Vec, Vec), io::Error> { let info = Path::new("info/"); - let mut relative_paths = Vec::with_capacity(paths.len()); - for p in paths { - let rel = p.strip_prefix(base_path).map_err(|_e| { - io::Error::new( - io::ErrorKind::InvalidInput, - format!( - "path '{}' is not under base path '{}'", - p.display(), - base_path.display() - ), - ) - })?; - relative_paths.push(rel.to_path_buf()); - } + let relative_paths = paths + .iter() + .map(|p| { + p.strip_prefix(base_path) + .map(Path::to_path_buf) + .map_err(|_| { + io::Error::new( + io::ErrorKind::InvalidInput, + format!( + "path '{}' is not under base path '{}'", + p.display(), + base_path.display() + ), + ) + }) + }) + .collect::, _>>()?; let (mut info_paths, mut other_paths): (Vec<_>, Vec<_>) = relative_paths .into_iter() From db31a91c97727b87dd85207b08b6d1b946160242 Mon Sep 17 00:00:00 2001 From: suhr25 Date: Thu, 12 Mar 2026 02:57:22 +0000 Subject: [PATCH 4/4] Fix CI: resolve lint errors and rebase branch --- crates/rattler_package_streaming/src/write.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rattler_package_streaming/src/write.rs b/crates/rattler_package_streaming/src/write.rs index e7e97b8e3..09d516d87 100644 --- a/crates/rattler_package_streaming/src/write.rs +++ b/crates/rattler_package_streaming/src/write.rs @@ -80,7 +80,7 @@ fn sort_paths( .map(|p| { p.strip_prefix(base_path) .map(Path::to_path_buf) - .map_err(|_| { + .map_err(|_e| { io::Error::new( io::ErrorKind::InvalidInput, format!(