diff --git a/crates/rattler_index/src/lib.rs b/crates/rattler_index/src/lib.rs index 6ea2c85dc..078198351 100644 --- a/crates/rattler_index/src/lib.rs +++ b/crates/rattler_index/src/lib.rs @@ -131,7 +131,7 @@ async fn index_subdir( subdir: Platform, op: Operator, force: bool, - progress: MultiProgress, + progress: Option, semaphore: Arc, ) -> Result<()> { let mut registered_packages: FxHashMap = HashMap::default(); @@ -215,7 +215,12 @@ async fn index_subdir( subdir ); - let pb = Arc::new(progress.add(ProgressBar::new(packages_to_add.len() as u64))); + let pb = if let Some(progress) = progress { + progress.add(ProgressBar::new(packages_to_add.len() as u64)) + } else { + ProgressBar::hidden() + }; + let sty = ProgressStyle::with_template( "[{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {msg}", ) @@ -314,10 +319,11 @@ pub async fn index_fs( target_platform: Option, force: bool, max_parallel: usize, + multi_progress: Option, ) -> anyhow::Result<()> { let mut config = FsConfig::default(); config.root = Some(channel.into().canonicalize()?.to_string_lossy().to_string()); - index(target_platform, config, force, max_parallel).await + index(target_platform, config, force, max_parallel, multi_progress).await } /// Create a new `repodata.json` for all packages in the channel at the given S3 URL. @@ -333,6 +339,7 @@ pub async fn index_s3( target_platform: Option, force: bool, max_parallel: usize, + multi_progress: Option, ) -> anyhow::Result<()> { let mut s3_config = S3Config::default(); s3_config.root = Some(channel.path().to_string()); @@ -366,7 +373,14 @@ pub async fn index_s3( s3_config.session_token = session_token; } } - index(target_platform, s3_config, force, max_parallel).await + index( + target_platform, + s3_config, + force, + max_parallel, + multi_progress, + ) + .await } /// Create a new `repodata.json` for all packages in the given configurator's root. @@ -386,36 +400,42 @@ pub async fn index( config: T, force: bool, max_parallel: usize, + multi_progress: Option, ) -> anyhow::Result<()> { let builder = config.into_builder(); // Get all subdirs let op = Operator::new(builder)?.finish(); let entries = op.list_with("").await?; - let mut subdirs = entries - .iter() - .filter_map(|entry| { - if entry.metadata().mode().is_dir() && entry.name() != "/" { - // Directory entries always end with `/`. - Some(entry.name().trim_end_matches('/').to_string()) - } else { - None - } - }) - .map(|s| Platform::from_str(&s)) - .collect::, _>>()?; // If requested `target_platform` subdir does not exist, we create it. - if let Some(target_platform) = target_platform { - tracing::debug!("Did not find {target_platform} subdir, creating."); - if !subdirs.contains(&target_platform) { + let mut subdirs = if let Some(target_platform) = target_platform { + if !op.exists(&format!("{}/", target_platform.as_str())).await? { + tracing::debug!("Did not find {target_platform} subdir, creating."); op.create_dir(&format!("{}/", target_platform.as_str())) .await?; } // Limit subdirs to only the requested `target_platform`. - subdirs = HashSet::default(); - subdirs.insert(target_platform); - } else if !subdirs.contains(&Platform::NoArch) { + HashSet::from([target_platform]) + } else { + entries + .iter() + .filter_map(|entry| { + if entry.metadata().mode().is_dir() && entry.name() != "/" { + // Directory entries always end with `/`. + Some(entry.name().trim_end_matches('/').to_string()) + } else { + None + } + }) + .filter_map(|s| Platform::from_str(&s).ok()) + .collect::>() + }; + + if !op + .exists(&format!("{}/", Platform::NoArch.as_str())) + .await? + { // If `noarch` subdir does not exist, we create it. tracing::debug!("Did not find noarch subdir, creating."); op.create_dir(&format!("{}/", Platform::NoArch.as_str())) @@ -423,7 +443,6 @@ pub async fn index( subdirs.insert(Platform::NoArch); } - let multi_progress = MultiProgress::new(); let semaphore = Semaphore::new(max_parallel); let semaphore = Arc::new(semaphore); diff --git a/crates/rattler_index/src/main.rs b/crates/rattler_index/src/main.rs index 738bcdc84..c72fc1d47 100644 --- a/crates/rattler_index/src/main.rs +++ b/crates/rattler_index/src/main.rs @@ -99,9 +99,18 @@ async fn main() -> anyhow::Result<()> { .with_max_level(cli.verbosity) .init(); + let multi_progress = indicatif::MultiProgress::new(); + match cli.command { Commands::FileSystem { channel } => { - index_fs(channel, cli.target_platform, cli.force, cli.max_parallel).await + index_fs( + channel, + cli.target_platform, + cli.force, + cli.max_parallel, + Some(multi_progress), + ) + .await } Commands::S3 { channel, @@ -123,6 +132,7 @@ async fn main() -> anyhow::Result<()> { cli.target_platform, cli.force, cli.max_parallel, + Some(multi_progress), ) .await } diff --git a/crates/rattler_index/tests/test_index.rs b/crates/rattler_index/tests/test_index.rs index 5fd83aeec..5b088ff3b 100644 --- a/crates/rattler_index/tests/test_index.rs +++ b/crates/rattler_index/tests/test_index.rs @@ -58,7 +58,7 @@ async fn test_index() { ) .unwrap(); - let res = index_fs(temp_dir.path(), Some(Platform::Win64), true, 100).await; + let res = index_fs(temp_dir.path(), Some(Platform::Win64), true, 100, None).await; assert!(res.is_ok()); let repodata_path = temp_dir.path().join(subdir_path).join("repodata.json"); @@ -98,7 +98,7 @@ async fn test_index_empty_directory_creates_noarch_repodata() { let noarch_path = temp_dir.path().join("noarch"); let repodata_path = noarch_path.join("repodata.json"); - let res = index_fs(temp_dir.path(), None, true, 100).await; + let res = index_fs(temp_dir.path(), None, true, 100, None).await; assert!(res.is_ok()); assert!(noarch_path.is_dir()); diff --git a/crates/rattler_menuinst/src/lib.rs b/crates/rattler_menuinst/src/lib.rs index 9421b830c..6e8aef4cf 100644 --- a/crates/rattler_menuinst/src/lib.rs +++ b/crates/rattler_menuinst/src/lib.rs @@ -10,13 +10,13 @@ mod linux; #[cfg(target_os = "macos")] mod macos; mod render; -mod schema; +pub mod schema; #[cfg(target_os = "windows")] mod windows; use crate::{render::BaseMenuItemPlaceholders, schema::MenuInstSchema}; -pub mod utils; +mod utils; #[derive(thiserror::Error, Debug)] pub enum MenuInstError { diff --git a/crates/rattler_menuinst/src/macos.rs b/crates/rattler_menuinst/src/macos.rs index c02ebdc6e..21b28b6c7 100644 --- a/crates/rattler_menuinst/src/macos.rs +++ b/crates/rattler_menuinst/src/macos.rs @@ -22,11 +22,21 @@ use crate::{ CFBundleDocumentTypesModel, CFBundleTypeRole, CFBundleURLTypesModel, LSHandlerRank, MacOS, MacOSVersion, MenuItemCommand, UTTypeDeclarationModel, }, - utils::{self, log_output, run_pre_create_command}, + utils::{log_output, run_pre_create_command}, MenuInstError, MenuMode, }; use std::collections::HashMap; +pub fn quote_args(args: I) -> Vec +where + I: IntoIterator, + S: AsRef, +{ + args.into_iter() + .map(|arg| format!(r#""{}""#, arg.as_ref())) + .collect() +} + #[derive(Debug, Clone)] pub struct MacOSMenu { name: String, @@ -658,7 +668,7 @@ impl MacOSMenu { .command .iter() .map(|s| s.resolve(&self.placeholders)); - lines.push(utils::quote_args(command).join(" ")); + lines.push(quote_args(command).join(" ")); Ok(lines.join("\n")) } diff --git a/crates/rattler_menuinst/src/utils/mod.rs b/crates/rattler_menuinst/src/utils/mod.rs index 5145fa3e0..e4a3e03ac 100644 --- a/crates/rattler_menuinst/src/utils/mod.rs +++ b/crates/rattler_menuinst/src/utils/mod.rs @@ -5,13 +5,3 @@ pub use terminal::log_output; #[cfg(target_family = "unix")] pub use terminal::run_pre_create_command; - -pub fn quote_args(args: I) -> Vec -where - I: IntoIterator, - S: AsRef, -{ - args.into_iter() - .map(|arg| format!(r#""{}""#, arg.as_ref())) - .collect() -} diff --git a/crates/rattler_menuinst/src/utils/slugify.rs b/crates/rattler_menuinst/src/utils/slugify.rs index 583695b76..d0d1751b5 100644 --- a/crates/rattler_menuinst/src/utils/slugify.rs +++ b/crates/rattler_menuinst/src/utils/slugify.rs @@ -8,14 +8,6 @@ use unicode_normalization::UnicodeNormalization; /// 1. Normalizes the text using Unicode normalization and removes non-ASCII characters. /// 2. Removes special characters, converts the text to lowercase, and trims whitespace. /// 3. Replaces whitespace and hyphens with a single hyphen. -/// -/// # Examples -/// -/// ``` -/// # use rattler_menuinst::utils::slugify; -/// let slug = slugify("Hello, World!"); -/// assert_eq!(slug, "hello-world"); -/// ``` pub fn slugify(text: &str) -> String { static RE_SPECIAL: Lazy = Lazy::new(|| Regex::new(r"[^\w\s-]").expect("Invalid regex")); static RE_SPACES: Lazy = Lazy::new(|| Regex::new(r"[_\s-]+").expect("Invalid regex")); diff --git a/py-rattler/src/index.rs b/py-rattler/src/index.rs index 5658441f9..c7b221a0e 100644 --- a/py-rattler/src/index.rs +++ b/py-rattler/src/index.rs @@ -19,9 +19,15 @@ pub fn py_index_fs( ) -> PyResult> { future_into_py(py, async move { let target_platform = target_platform.map(Platform::from); - index_fs(channel_directory, target_platform, force, max_parallel) - .await - .map_err(|e| PyRattlerError::from(e).into()) + index_fs( + channel_directory, + target_platform, + force, + max_parallel, + None, + ) + .await + .map_err(|e| PyRattlerError::from(e).into()) }) } @@ -56,6 +62,7 @@ pub fn py_index_s3( target_platform, force, max_parallel, + None, ) .await .map_err(|e| PyRattlerError::from(e).into())