From 726c63353d1d15b0ed59fee0d20c7d3211babb72 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Wed, 21 Aug 2024 22:07:20 -0400 Subject: [PATCH 01/33] start adding interface to override --- crates/rattler_virtual_packages/src/lib.rs | 121 +++++++++++++++++---- 1 file changed, 102 insertions(+), 19 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index c9d5219bc..045fb5b66 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -62,22 +62,50 @@ pub trait EnvOverride: Sized { /// - `None`, then the environment variable did not exist, /// - `Some(Err(None))`, then the environment variable exist but was set to zero, so the package should be disabled /// - `Some(Ok(pkg))`, then the override was for the package. - fn from_env_var_name(env_var_name: &str) -> Option>> { - let var = env::var(env_var_name).ok()?; - if var.is_empty() { - Some(Err(None)) - } else { - Some(Self::from_env_var_name_with_var(env_var_name, &var).map_err(Some)) + fn from_env_var_name_or( + env_var_name: &str, + f: F, + ) -> Result, DetectVirtualPackageError> + where + F: FnOnce() -> Result, DetectVirtualPackageError>, + { + match env::var(env_var_name) { + Ok(var) => Ok(Some(Self::from_env_var_name_with_var(env_var_name, &var)?)), + Err(env::VarError::NotPresent) => f(), + Err(e) => Err(DetectVirtualPackageError::VarError(e)), } } + /// Helper method for [`EnvOverride::from_env_var_name_or`] that uses [`EnvOverride::current`] as the default. + fn from_env_var_name_or_current( + env_var_name: &str, + ) -> Result, DetectVirtualPackageError> { + Self::from_env_var_name_or(env_var_name, Self::current) + } + + /// Helper method for [`EnvOverride::from_env_var_name_or`] that does not have any default. + fn from_env_var_name(env_var_name: &str) -> Result, DetectVirtualPackageError> { + Self::from_env_var_name_or(env_var_name, || Ok(None)) + } + /// Default name of the environment variable that overrides the virtual package. const DEFAULT_ENV_NAME: &'static str; /// Shortcut for `EnvOverride::from_env_var_name(EnvOverride::DEFAULT_ENV_NAME)`. - fn from_default_env_var() -> Option>> { - Self::from_env_var_name(Self::DEFAULT_ENV_NAME) + fn from_default_env_var_or(f: F) -> Result, DetectVirtualPackageError> + where + F: FnOnce() -> Result, DetectVirtualPackageError>, + { + Self::from_env_var_name_or(Self::DEFAULT_ENV_NAME, f) } + + /// Shortcut for `EnvOverride::from_env_var_name(EnvOverride::DEFAULT_ENV_NAME)`. + fn from_default_env_var() -> Result, DetectVirtualPackageError> { + Self::from_default_env_var_or(|| Ok(None)) + } + + /// This method is here so that `::current` always returns the same error type. + fn current() -> Result, DetectVirtualPackageError>; } /// An enum that represents all virtual package types provided by this library. @@ -150,10 +178,42 @@ pub enum DetectVirtualPackageError { #[error(transparent)] DetectLibC(#[from] DetectLibCError), + + #[error(transparent)] + VarError(#[from] env::VarError), + + #[error(transparent)] + VersionParseError(#[from] ParseVersionError), +} + +struct VirtualPackageOverride<'a> { + osx: Option<&'a str>, + libc: Option<&'a str>, + cuda: Option<&'a str>, +} + +impl VirtualPackageOverride<'static> { + fn none() -> Self { + Self { + osx: None, + libc: None, + cuda: None, + } + } + + fn default() -> Self { + Self { + osx: Some(Osx::DEFAULT_ENV_NAME), + libc: Some(LibC::DEFAULT_ENV_NAME), + cuda: Some(Cuda::DEFAULT_ENV_NAME), + } + } } // Detect the available virtual packages on the system -fn try_detect_virtual_packages() -> Result, DetectVirtualPackageError> { +fn try_detect_virtual_packages_with_overrides( + overrides: &VirtualPackageOverride<'_>, +) -> Result, DetectVirtualPackageError> { let mut result = Vec::new(); let platform = Platform::current(); @@ -169,18 +229,27 @@ fn try_detect_virtual_packages() -> Result, DetectVirtualPac if let Some(linux_version) = Linux::current()? { result.push(linux_version.into()); } - if let Some(libc) = LibC::current()? { + if let Some(libc) = overrides.libc.map_or_else( + ::current, + LibC::from_env_var_name_or_current, + )? { result.push(libc.into()); } } if platform.is_osx() { - if let Some(osx) = Osx::current()? { + if let Some(osx) = overrides.osx.map_or_else( + ::current, + Osx::from_env_var_name_or_current, + )? { result.push(osx.into()); } } - if let Some(cuda) = Cuda::current() { + if let Some(cuda) = overrides.cuda.map_or_else( + ::current, + Cuda::from_env_var_name_or_current, + )? { result.push(cuda.into()); } @@ -191,6 +260,9 @@ fn try_detect_virtual_packages() -> Result, DetectVirtualPac Ok(result) } +fn try_detect_virtual_packages() -> Result, DetectVirtualPackageError> { + try_detect_virtual_packages_with_overrides(&VirtualPackageOverride::none()) +} /// Linux virtual package description #[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)] pub struct Linux { @@ -283,6 +355,10 @@ impl EnvOverride for LibC { version, }) } + + fn current() -> Result, DetectVirtualPackageError> { + Ok(Self::current()?) + } } /// Cuda virtual package description @@ -312,7 +388,9 @@ impl EnvOverride for Cuda { ) -> Result { Version::from_str(env_var_value).map(|version| Self { version }) } - + fn current() -> Result, DetectVirtualPackageError> { + Ok(Self::current()) + } const DEFAULT_ENV_NAME: &'static str = "CONDA_OVERRIDE_CUDA"; } @@ -489,7 +567,9 @@ impl EnvOverride for Osx { ) -> Result { Version::from_str(env_var_value).map(|version| Self { version }) } - + fn current() -> Result, DetectVirtualPackageError> { + Ok(Self::current()?) + } const DEFAULT_ENV_NAME: &'static str = "CONDA_OVERRIDE_OSX"; } @@ -519,11 +599,14 @@ mod test { family: "glibc".into(), }; env::set_var(LibC::DEFAULT_ENV_NAME, v); - assert_eq!(LibC::from_default_env_var(), Some(Ok(res))); + assert_eq!(LibC::from_default_env_var().unwrap().unwrap(), res); env::set_var(LibC::DEFAULT_ENV_NAME, ""); - assert_eq!(LibC::from_default_env_var(), Some(Err(None))); + assert_eq!(LibC::from_default_env_var().unwrap(), None); env::remove_var(LibC::DEFAULT_ENV_NAME); - assert_eq!(LibC::from_default_env_var(), None); + match LibC::from_default_env_var().unwrap_err() { + crate::DetectVirtualPackageError::VarError(env::VarError::NotPresent) => {} + e => panic!("Expected VarError::NotPresent, got {e:?}"), + }; } #[test] @@ -533,7 +616,7 @@ mod test { version: Version::from_str(v).unwrap(), }; env::set_var(Cuda::DEFAULT_ENV_NAME, v); - assert_eq!(Cuda::from_default_env_var(), Some(Ok(res))); + assert_eq!(Cuda::from_default_env_var().unwrap().unwrap(), res); } #[test] @@ -543,6 +626,6 @@ mod test { version: Version::from_str(v).unwrap(), }; env::set_var(Osx::DEFAULT_ENV_NAME, v); - assert_eq!(Osx::from_default_env_var(), Some(Ok(res))); + assert_eq!(Osx::from_default_env_var().unwrap().unwrap(), res); } } From 02d1fc862c7e9fc188432d686694bdde464b868a Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Wed, 21 Aug 2024 22:15:17 -0400 Subject: [PATCH 02/33] complete the interface --- crates/rattler_virtual_packages/src/lib.rs | 32 ++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 045fb5b66..de3e5be51 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -164,6 +164,24 @@ impl VirtualPackage { .get_or_try_init(try_detect_virtual_packages) .map(Vec::as_slice) } + + /// disable overrides + pub fn current_no_overrides() -> Result<&'static [Self], DetectVirtualPackageError> { + static DETECTED_VIRTUAL_PACKAGES: OnceCell> = OnceCell::new(); + DETECTED_VIRTUAL_PACKAGES + .get_or_try_init(try_detect_virtual_packages_no_overrides) + .map(Vec::as_slice) + } + + /// use custom overrides + pub fn current_with_overrides( + overrides: &VirtualPackageOverride<'_>, + ) -> Result<&'static [Self], DetectVirtualPackageError> { + static DETECTED_VIRTUAL_PACKAGES: OnceCell> = OnceCell::new(); + DETECTED_VIRTUAL_PACKAGES + .get_or_try_init(|| try_detect_virtual_packages_with_overrides(overrides)) + .map(Vec::as_slice) + } } /// An error that might be returned by [`VirtualPackage::current`]. @@ -186,14 +204,17 @@ pub enum DetectVirtualPackageError { VersionParseError(#[from] ParseVersionError), } -struct VirtualPackageOverride<'a> { +/// Configure the overrides used in in this crate. + +pub struct VirtualPackageOverride<'a> { osx: Option<&'a str>, libc: Option<&'a str>, cuda: Option<&'a str>, } impl VirtualPackageOverride<'static> { - fn none() -> Self { + /// Disable all overrides + pub fn none() -> Self { Self { osx: None, libc: None, @@ -201,6 +222,7 @@ impl VirtualPackageOverride<'static> { } } + /// Use the default overrides of Conda. fn default() -> Self { Self { osx: Some(Osx::DEFAULT_ENV_NAME), @@ -261,8 +283,14 @@ fn try_detect_virtual_packages_with_overrides( } fn try_detect_virtual_packages() -> Result, DetectVirtualPackageError> { + try_detect_virtual_packages_with_overrides(&VirtualPackageOverride::default()) +} + +fn try_detect_virtual_packages_no_overrides( +) -> Result, DetectVirtualPackageError> { try_detect_virtual_packages_with_overrides(&VirtualPackageOverride::none()) } + /// Linux virtual package description #[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)] pub struct Linux { From 84b362b24c95919878efd72efbdf1a0d2ec6bf14 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Fri, 23 Aug 2024 09:46:24 -0400 Subject: [PATCH 03/33] handle empty strings again --- crates/rattler_virtual_packages/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index de3e5be51..6c6c693f2 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -70,7 +70,13 @@ pub trait EnvOverride: Sized { F: FnOnce() -> Result, DetectVirtualPackageError>, { match env::var(env_var_name) { - Ok(var) => Ok(Some(Self::from_env_var_name_with_var(env_var_name, &var)?)), + Ok(var) => { + if var.is_empty() { + Ok(None) + } else { + Ok(Some(Self::from_env_var_name_with_var(env_var_name, &var)?)) + } + } Err(env::VarError::NotPresent) => f(), Err(e) => Err(DetectVirtualPackageError::VarError(e)), } From aa8e7e14ea3013b2154c7a3fb622e2ea553cbc4c Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Fri, 23 Aug 2024 10:22:24 -0400 Subject: [PATCH 04/33] fix test --- crates/rattler_virtual_packages/src/lib.rs | 10 ++++++---- crates/rattler_virtual_packages/src/libc.rs | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 6c6c693f2..5e1fb5d6a 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -637,10 +637,12 @@ mod test { env::set_var(LibC::DEFAULT_ENV_NAME, ""); assert_eq!(LibC::from_default_env_var().unwrap(), None); env::remove_var(LibC::DEFAULT_ENV_NAME); - match LibC::from_default_env_var().unwrap_err() { - crate::DetectVirtualPackageError::VarError(env::VarError::NotPresent) => {} - e => panic!("Expected VarError::NotPresent, got {e:?}"), - }; + assert_eq!( + LibC::from_default_env_var_or(|| Ok(Some(res.clone()))) + .unwrap() + .unwrap(), + res + ); } #[test] diff --git a/crates/rattler_virtual_packages/src/libc.rs b/crates/rattler_virtual_packages/src/libc.rs index e3248df34..30b8b4fb2 100644 --- a/crates/rattler_virtual_packages/src/libc.rs +++ b/crates/rattler_virtual_packages/src/libc.rs @@ -37,7 +37,7 @@ pub enum DetectLibCError { #[cfg(unix)] fn try_detect_libc_version() -> Result, DetectLibCError> { // Run `ldd --version` to detect the libc version and family on the system. - // `ldd` is shipped with libc so if an error occured during its execution we + // `ldd` is shipped with libc so if an error occurred during its execution we // can assume no libc is available on the system. let output = match std::process::Command::new("ldd").arg("--version").output() { Err(e) => { From 673231656d81eb3b27f441a3680b4a98fdbcc91c Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Tue, 27 Aug 2024 11:41:41 -0400 Subject: [PATCH 05/33] iter --- crates/rattler_virtual_packages/src/lib.rs | 50 +++++++++------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 5e1fb5d6a..9502d2077 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -164,29 +164,20 @@ impl From for GenericVirtualPackage { impl VirtualPackage { /// Returns virtual packages detected for the current system or an error if the versions could /// not be properly detected. - pub fn current() -> Result<&'static [Self], DetectVirtualPackageError> { - static DETECTED_VIRTUAL_PACKAGES: OnceCell> = OnceCell::new(); - DETECTED_VIRTUAL_PACKAGES - .get_or_try_init(try_detect_virtual_packages) - .map(Vec::as_slice) + pub fn current() -> Result, DetectVirtualPackageError> { + try_detect_virtual_packages() } /// disable overrides - pub fn current_no_overrides() -> Result<&'static [Self], DetectVirtualPackageError> { - static DETECTED_VIRTUAL_PACKAGES: OnceCell> = OnceCell::new(); - DETECTED_VIRTUAL_PACKAGES - .get_or_try_init(try_detect_virtual_packages_no_overrides) - .map(Vec::as_slice) + pub fn current_no_overrides() -> Result, DetectVirtualPackageError> { + try_detect_virtual_packages_no_overrides() } /// use custom overrides pub fn current_with_overrides( - overrides: &VirtualPackageOverride<'_>, - ) -> Result<&'static [Self], DetectVirtualPackageError> { - static DETECTED_VIRTUAL_PACKAGES: OnceCell> = OnceCell::new(); - DETECTED_VIRTUAL_PACKAGES - .get_or_try_init(|| try_detect_virtual_packages_with_overrides(overrides)) - .map(Vec::as_slice) + overrides: &VirtualPackageOverride, + ) -> Result, DetectVirtualPackageError> { + try_detect_virtual_packages_with_overrides(overrides) } } @@ -212,13 +203,13 @@ pub enum DetectVirtualPackageError { /// Configure the overrides used in in this crate. -pub struct VirtualPackageOverride<'a> { - osx: Option<&'a str>, - libc: Option<&'a str>, - cuda: Option<&'a str>, +pub struct VirtualPackageOverride { + osx: Option, + libc: Option, + cuda: Option, } -impl VirtualPackageOverride<'static> { +impl VirtualPackageOverride { /// Disable all overrides pub fn none() -> Self { Self { @@ -227,20 +218,21 @@ impl VirtualPackageOverride<'static> { cuda: None, } } +} - /// Use the default overrides of Conda. +impl Default for VirtualPackageOverride { fn default() -> Self { Self { - osx: Some(Osx::DEFAULT_ENV_NAME), - libc: Some(LibC::DEFAULT_ENV_NAME), - cuda: Some(Cuda::DEFAULT_ENV_NAME), + osx: Some(Osx::DEFAULT_ENV_NAME.to_string()), + libc: Some(LibC::DEFAULT_ENV_NAME.to_string()), + cuda: Some(Cuda::DEFAULT_ENV_NAME.to_string()), } } } // Detect the available virtual packages on the system fn try_detect_virtual_packages_with_overrides( - overrides: &VirtualPackageOverride<'_>, + overrides: &VirtualPackageOverride, ) -> Result, DetectVirtualPackageError> { let mut result = Vec::new(); let platform = Platform::current(); @@ -257,7 +249,7 @@ fn try_detect_virtual_packages_with_overrides( if let Some(linux_version) = Linux::current()? { result.push(linux_version.into()); } - if let Some(libc) = overrides.libc.map_or_else( + if let Some(libc) = overrides.libc.as_ref().map(String::as_str).map_or_else( ::current, LibC::from_env_var_name_or_current, )? { @@ -266,7 +258,7 @@ fn try_detect_virtual_packages_with_overrides( } if platform.is_osx() { - if let Some(osx) = overrides.osx.map_or_else( + if let Some(osx) = overrides.osx.as_ref().map(String::as_str).map_or_else( ::current, Osx::from_env_var_name_or_current, )? { @@ -274,7 +266,7 @@ fn try_detect_virtual_packages_with_overrides( } } - if let Some(cuda) = overrides.cuda.map_or_else( + if let Some(cuda) = overrides.cuda.as_ref().map(String::as_str).map_or_else( ::current, Cuda::from_env_var_name_or_current, )? { From 16beb978f9530a6caeea587ee577ee103770bdfe Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Tue, 27 Aug 2024 11:42:21 -0400 Subject: [PATCH 06/33] remove unused import --- crates/rattler_virtual_packages/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 9502d2077..04a30fa24 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -34,7 +34,6 @@ pub mod linux; pub mod osx; use archspec::cpu::Microarchitecture; -use once_cell::sync::OnceCell; use rattler_conda_types::{ GenericVirtualPackage, PackageName, ParseVersionError, Platform, Version, }; From de3f3316da49e41d7969d140c572d9e58eddf532 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Tue, 27 Aug 2024 11:49:54 -0400 Subject: [PATCH 07/33] use as_deref --- crates/rattler_virtual_packages/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 04a30fa24..211f0121a 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -248,7 +248,7 @@ fn try_detect_virtual_packages_with_overrides( if let Some(linux_version) = Linux::current()? { result.push(linux_version.into()); } - if let Some(libc) = overrides.libc.as_ref().map(String::as_str).map_or_else( + if let Some(libc) = overrides.libc.as_deref().map_or_else( ::current, LibC::from_env_var_name_or_current, )? { @@ -257,7 +257,7 @@ fn try_detect_virtual_packages_with_overrides( } if platform.is_osx() { - if let Some(osx) = overrides.osx.as_ref().map(String::as_str).map_or_else( + if let Some(osx) = overrides.osx.as_deref().map_or_else( ::current, Osx::from_env_var_name_or_current, )? { @@ -265,7 +265,7 @@ fn try_detect_virtual_packages_with_overrides( } } - if let Some(cuda) = overrides.cuda.as_ref().map(String::as_str).map_or_else( + if let Some(cuda) = overrides.cuda.as_deref().map_or_else( ::current, Cuda::from_env_var_name_or_current, )? { From 2a9ffdd727b262b37fcf69316a9116c33507f54a Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Tue, 27 Aug 2024 22:15:34 -0400 Subject: [PATCH 08/33] add quad state overrides --- crates/rattler_virtual_packages/src/lib.rs | 145 ++++++++++----------- 1 file changed, 70 insertions(+), 75 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 211f0121a..a789f22ab 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -47,14 +47,39 @@ use libc::DetectLibCError; use linux::ParseLinuxVersionError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +/// Configure the overrides used in in this crate. +pub enum Override { + /// Use the default override env var name + DefaultEnvVar, + /// Use custom env var name + EnvVar(String), + /// Use a custom override directly + String(String), + /// Disable overrides + None, +} + +impl Default for Override { + fn default() -> Self { + Self::DefaultEnvVar + } +} + /// Traits for overridable virtual packages /// Use as `Cuda::from_default_env_var.unwrap_or(Cuda::current().into()).unwrap()` pub trait EnvOverride: Sized { /// Parse `env_var_value` - fn from_env_var_name_with_var( - env_var_name: &str, - env_var_value: &str, - ) -> Result; + fn parse_version(value: &str) -> Result; + + + /// Helper to convert the output of `parse_version` and handling empty strings. + fn parse_version_(value: &str) -> Result, DetectVirtualPackageError> { + if value.is_empty() { + Ok(None) + } else { + Ok(Some(Self::parse_version(value)?)) + } + } /// Read the environment variable and if it exists, try to parse it with [`EnvOverride::from_env_var_name_with_var`] /// If the output is: @@ -69,48 +94,35 @@ pub trait EnvOverride: Sized { F: FnOnce() -> Result, DetectVirtualPackageError>, { match env::var(env_var_name) { - Ok(var) => { - if var.is_empty() { - Ok(None) - } else { - Ok(Some(Self::from_env_var_name_with_var(env_var_name, &var)?)) - } - } + Ok(var) => Self::parse_version_(&var), Err(env::VarError::NotPresent) => f(), Err(e) => Err(DetectVirtualPackageError::VarError(e)), } } - /// Helper method for [`EnvOverride::from_env_var_name_or`] that uses [`EnvOverride::current`] as the default. - fn from_env_var_name_or_current( - env_var_name: &str, - ) -> Result, DetectVirtualPackageError> { - Self::from_env_var_name_or(env_var_name, Self::current) - } - - /// Helper method for [`EnvOverride::from_env_var_name_or`] that does not have any default. - fn from_env_var_name(env_var_name: &str) -> Result, DetectVirtualPackageError> { - Self::from_env_var_name_or(env_var_name, || Ok(None)) - } - /// Default name of the environment variable that overrides the virtual package. const DEFAULT_ENV_NAME: &'static str; - /// Shortcut for `EnvOverride::from_env_var_name(EnvOverride::DEFAULT_ENV_NAME)`. - fn from_default_env_var_or(f: F) -> Result, DetectVirtualPackageError> + /// This method is here so that `::current` always returns the same error type. + fn current() -> Result, DetectVirtualPackageError>; + + /// Apply the override to the current virtual package. If the override is `None` then use the fallback + fn apply_override_or(ov: &Override, f: F) -> Result, DetectVirtualPackageError> where F: FnOnce() -> Result, DetectVirtualPackageError>, { - Self::from_env_var_name_or(Self::DEFAULT_ENV_NAME, f) + match ov { + Override::None => f(), + Override::String(str) => Self::parse_version_(str), + Override::DefaultEnvVar => Self::from_env_var_name_or(Self::DEFAULT_ENV_NAME, f), + Override::EnvVar(name) => Self::from_env_var_name_or(name, f), + } } - /// Shortcut for `EnvOverride::from_env_var_name(EnvOverride::DEFAULT_ENV_NAME)`. - fn from_default_env_var() -> Result, DetectVirtualPackageError> { - Self::from_default_env_var_or(|| Ok(None)) + /// Shortcut for `apply_override_or` with `Self::current` + fn apply_override(ov: &Override) -> Result, DetectVirtualPackageError> { + Self::apply_override_or(ov, Self::current) } - - /// This method is here so that `::current` always returns the same error type. - fn current() -> Result, DetectVirtualPackageError>; } /// An enum that represents all virtual package types provided by this library. @@ -199,35 +211,25 @@ pub enum DetectVirtualPackageError { #[error(transparent)] VersionParseError(#[from] ParseVersionError), } - /// Configure the overrides used in in this crate. - +#[derive(Default)] pub struct VirtualPackageOverride { - osx: Option, - libc: Option, - cuda: Option, + osx: Override, + libc: Override, + cuda: Override, } impl VirtualPackageOverride { /// Disable all overrides pub fn none() -> Self { Self { - osx: None, - libc: None, - cuda: None, + osx: Override::None, + libc: Override::None, + cuda: Override::None, } } } -impl Default for VirtualPackageOverride { - fn default() -> Self { - Self { - osx: Some(Osx::DEFAULT_ENV_NAME.to_string()), - libc: Some(LibC::DEFAULT_ENV_NAME.to_string()), - cuda: Some(Cuda::DEFAULT_ENV_NAME.to_string()), - } - } -} // Detect the available virtual packages on the system fn try_detect_virtual_packages_with_overrides( @@ -248,27 +250,18 @@ fn try_detect_virtual_packages_with_overrides( if let Some(linux_version) = Linux::current()? { result.push(linux_version.into()); } - if let Some(libc) = overrides.libc.as_deref().map_or_else( - ::current, - LibC::from_env_var_name_or_current, - )? { + if let Some(libc) = LibC::apply_override(&overrides.libc)? { result.push(libc.into()); } } if platform.is_osx() { - if let Some(osx) = overrides.osx.as_deref().map_or_else( - ::current, - Osx::from_env_var_name_or_current, - )? { + if let Some(osx) = Osx::apply_override(&overrides.osx)? { result.push(osx.into()); } } - if let Some(cuda) = overrides.cuda.as_deref().map_or_else( - ::current, - Cuda::from_env_var_name_or_current, - )? { + if let Some(cuda) = Cuda::apply_override(&overrides.cuda)? { result.push(cuda.into()); } @@ -371,10 +364,7 @@ impl From for VirtualPackage { impl EnvOverride for LibC { const DEFAULT_ENV_NAME: &'static str = "CONDA_OVERRIDE_GLIBC"; - fn from_env_var_name_with_var( - _env_var_name: &str, - env_var_value: &str, - ) -> Result { + fn parse_version(env_var_value: &str) -> Result { Version::from_str(env_var_value).map(|version| Self { family: "glibc".into(), version, @@ -407,8 +397,7 @@ impl From for Cuda { } impl EnvOverride for Cuda { - fn from_env_var_name_with_var( - _env_var_name: &str, + fn parse_version( env_var_value: &str, ) -> Result { Version::from_str(env_var_value).map(|version| Self { version }) @@ -586,8 +575,7 @@ impl From for Osx { } impl EnvOverride for Osx { - fn from_env_var_name_with_var( - _env_var_name: &str, + fn parse_version( env_var_value: &str, ) -> Result { Version::from_str(env_var_value).map(|version| Self { version }) @@ -610,6 +598,7 @@ mod test { use crate::LibC; use crate::Osx; use crate::VirtualPackage; + use crate::Override; #[test] fn doesnt_crash() { @@ -624,17 +613,23 @@ mod test { family: "glibc".into(), }; env::set_var(LibC::DEFAULT_ENV_NAME, v); - assert_eq!(LibC::from_default_env_var().unwrap().unwrap(), res); + assert_eq!(LibC::apply_override(&Override::DefaultEnvVar).unwrap().unwrap(), res); env::set_var(LibC::DEFAULT_ENV_NAME, ""); - assert_eq!(LibC::from_default_env_var().unwrap(), None); + assert_eq!(LibC::apply_override(&Override::DefaultEnvVar).unwrap(), None); env::remove_var(LibC::DEFAULT_ENV_NAME); assert_eq!( - LibC::from_default_env_var_or(|| Ok(Some(res.clone()))) + LibC::apply_override_or(&Override::DefaultEnvVar, || Ok(Some(res.clone()))) .unwrap() .unwrap(), res ); - } + assert_eq!( + LibC::apply_override_or(&Override::String(v.to_string()), || Ok(None)) + .unwrap() + .unwrap(), + res + ); + } #[test] fn parse_cuda() { @@ -643,7 +638,7 @@ mod test { version: Version::from_str(v).unwrap(), }; env::set_var(Cuda::DEFAULT_ENV_NAME, v); - assert_eq!(Cuda::from_default_env_var().unwrap().unwrap(), res); + assert_eq!(Cuda::apply_override(&Override::DefaultEnvVar).unwrap().unwrap(), res); } #[test] @@ -653,6 +648,6 @@ mod test { version: Version::from_str(v).unwrap(), }; env::set_var(Osx::DEFAULT_ENV_NAME, v); - assert_eq!(Osx::from_default_env_var().unwrap().unwrap(), res); + assert_eq!(Osx::apply_override(&Override::DefaultEnvVar).unwrap().unwrap(), res); } } From 8fad46ff4cc28d69726fa4c0544da981473e3003 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Tue, 27 Aug 2024 22:17:51 -0400 Subject: [PATCH 09/33] fmt --- crates/rattler_virtual_packages/src/lib.rs | 40 ++++++++++++++-------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index a789f22ab..d5098d142 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -71,7 +71,6 @@ pub trait EnvOverride: Sized { /// Parse `env_var_value` fn parse_version(value: &str) -> Result; - /// Helper to convert the output of `parse_version` and handling empty strings. fn parse_version_(value: &str) -> Result, DetectVirtualPackageError> { if value.is_empty() { @@ -230,7 +229,6 @@ impl VirtualPackageOverride { } } - // Detect the available virtual packages on the system fn try_detect_virtual_packages_with_overrides( overrides: &VirtualPackageOverride, @@ -397,9 +395,7 @@ impl From for Cuda { } impl EnvOverride for Cuda { - fn parse_version( - env_var_value: &str, - ) -> Result { + fn parse_version(env_var_value: &str) -> Result { Version::from_str(env_var_value).map(|version| Self { version }) } fn current() -> Result, DetectVirtualPackageError> { @@ -575,9 +571,7 @@ impl From for Osx { } impl EnvOverride for Osx { - fn parse_version( - env_var_value: &str, - ) -> Result { + fn parse_version(env_var_value: &str) -> Result { Version::from_str(env_var_value).map(|version| Self { version }) } fn current() -> Result, DetectVirtualPackageError> { @@ -597,8 +591,8 @@ mod test { use crate::EnvOverride; use crate::LibC; use crate::Osx; - use crate::VirtualPackage; use crate::Override; + use crate::VirtualPackage; #[test] fn doesnt_crash() { @@ -613,9 +607,17 @@ mod test { family: "glibc".into(), }; env::set_var(LibC::DEFAULT_ENV_NAME, v); - assert_eq!(LibC::apply_override(&Override::DefaultEnvVar).unwrap().unwrap(), res); + assert_eq!( + LibC::apply_override(&Override::DefaultEnvVar) + .unwrap() + .unwrap(), + res + ); env::set_var(LibC::DEFAULT_ENV_NAME, ""); - assert_eq!(LibC::apply_override(&Override::DefaultEnvVar).unwrap(), None); + assert_eq!( + LibC::apply_override(&Override::DefaultEnvVar).unwrap(), + None + ); env::remove_var(LibC::DEFAULT_ENV_NAME); assert_eq!( LibC::apply_override_or(&Override::DefaultEnvVar, || Ok(Some(res.clone()))) @@ -629,7 +631,7 @@ mod test { .unwrap(), res ); - } + } #[test] fn parse_cuda() { @@ -638,7 +640,12 @@ mod test { version: Version::from_str(v).unwrap(), }; env::set_var(Cuda::DEFAULT_ENV_NAME, v); - assert_eq!(Cuda::apply_override(&Override::DefaultEnvVar).unwrap().unwrap(), res); + assert_eq!( + Cuda::apply_override(&Override::DefaultEnvVar) + .unwrap() + .unwrap(), + res + ); } #[test] @@ -648,6 +655,11 @@ mod test { version: Version::from_str(v).unwrap(), }; env::set_var(Osx::DEFAULT_ENV_NAME, v); - assert_eq!(Osx::apply_override(&Override::DefaultEnvVar).unwrap().unwrap(), res); + assert_eq!( + Osx::apply_override(&Override::DefaultEnvVar) + .unwrap() + .unwrap(), + res + ); } } From 8bbd546b15f19ddb8b90918f6a710f14fb7eee18 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Tue, 27 Aug 2024 23:16:13 -0400 Subject: [PATCH 10/33] remove useless methods --- crates/rattler_virtual_packages/src/lib.rs | 27 ++++++---------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index d5098d142..6cd55907e 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -48,6 +48,7 @@ use linux::ParseLinuxVersionError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// Configure the overrides used in in this crate. +#[derive(Clone, Debug)] pub enum Override { /// Use the default override env var name DefaultEnvVar, @@ -175,17 +176,12 @@ impl VirtualPackage { /// Returns virtual packages detected for the current system or an error if the versions could /// not be properly detected. pub fn current() -> Result, DetectVirtualPackageError> { - try_detect_virtual_packages() - } - - /// disable overrides - pub fn current_no_overrides() -> Result, DetectVirtualPackageError> { - try_detect_virtual_packages_no_overrides() + try_detect_virtual_packages_with_overrides(&VirtualPackageOverrides::default()) } /// use custom overrides pub fn current_with_overrides( - overrides: &VirtualPackageOverride, + overrides: &VirtualPackageOverrides, ) -> Result, DetectVirtualPackageError> { try_detect_virtual_packages_with_overrides(overrides) } @@ -211,14 +207,14 @@ pub enum DetectVirtualPackageError { VersionParseError(#[from] ParseVersionError), } /// Configure the overrides used in in this crate. -#[derive(Default)] -pub struct VirtualPackageOverride { +#[derive(Default, Clone, Debug)] +pub struct VirtualPackageOverrides { osx: Override, libc: Override, cuda: Override, } -impl VirtualPackageOverride { +impl VirtualPackageOverrides { /// Disable all overrides pub fn none() -> Self { Self { @@ -231,7 +227,7 @@ impl VirtualPackageOverride { // Detect the available virtual packages on the system fn try_detect_virtual_packages_with_overrides( - overrides: &VirtualPackageOverride, + overrides: &VirtualPackageOverrides, ) -> Result, DetectVirtualPackageError> { let mut result = Vec::new(); let platform = Platform::current(); @@ -270,15 +266,6 @@ fn try_detect_virtual_packages_with_overrides( Ok(result) } -fn try_detect_virtual_packages() -> Result, DetectVirtualPackageError> { - try_detect_virtual_packages_with_overrides(&VirtualPackageOverride::default()) -} - -fn try_detect_virtual_packages_no_overrides( -) -> Result, DetectVirtualPackageError> { - try_detect_virtual_packages_with_overrides(&VirtualPackageOverride::none()) -} - /// Linux virtual package description #[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)] pub struct Linux { From 28e07acd22e3cecb3e4395897f88ba34e71f4036 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Tue, 27 Aug 2024 23:16:35 -0400 Subject: [PATCH 11/33] make python binding --- .../virtual_package/virtual_package.py | 147 +++++++++++++++++- py-rattler/src/lib.rs | 4 +- py-rattler/src/virtual_package.rs | 82 +++++++++- 3 files changed, 226 insertions(+), 7 deletions(-) diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index 5d8544438..893618cd9 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -1,11 +1,146 @@ from __future__ import annotations -from rattler.rattler import PyVirtualPackage +from rattler.rattler import PyVirtualPackage, PyOverride, PyVirtualPackageOverrides from typing import List from rattler.virtual_package.generic import GenericVirtualPackage +class Override: + _override: PyOverride + + @classmethod + def _from_py_override(cls, py_override: PyOverride) -> Override: + """Construct Rattler Override from FFI PyOverride object.""" + override = cls.__new__(cls) + override._override = py_override + return override + + @classmethod + def _from_default_env_var(cls) -> Override: + """ + Returns the default environment variable override. + """ + return cls._from_py_override(PyOverride.default_env_var()) + + @classmethod + def _from_env_var(cls, env_var: str) -> Override: + """ + Returns the environment variable override for the given environment variable. + """ + return cls._from_py_override(PyOverride.env_var(env_var)) + + @classmethod + def _from_string(cls, override: str) -> Override: + """ + Returns the override for the given string. + """ + return cls._from_py_override(PyOverride.from_str(override)) + + @classmethod + def _from_none(cls) -> Override: + """ + Returns the override for None. + """ + return cls._from_py_override(PyOverride.none()) + + def __str__(self) -> str: + """ + Returns string representation of the Override. + """ + return self._override.as_str() + + def __repr__(self) -> str: + """ + Returns a representation of the Override. + """ + return f"Override({self._override.as_str()})" + + +class VirtualPackageOverrides: + _overrides: PyVirtualPackageOverrides + + @classmethod + def _from_py_virtual_package_overrides( + cls, py_virtual_package_overrides: PyVirtualPackageOverrides + ) -> VirtualPackageOverrides: + """Construct Rattler VirtualPackageOverrides from FFI PyVirtualPackageOverrides object.""" + virtual_package_overrides = cls.__new__(cls) + virtual_package_overrides._overrides = py_virtual_package_overrides + return virtual_package_overrides + + @classmethod + def _from_default(cls) -> VirtualPackageOverrides: + """ + Returns the default virtual package overrides. + """ + return cls._from_py_virtual_package_overrides(PyVirtualPackageOverrides.default()) + + @classmethod + def _from_none(cls) -> VirtualPackageOverrides: + """ + Returns the virtual package overrides for None. + """ + return cls._from_py_virtual_package_overrides(PyVirtualPackageOverrides.none()) + + @property + def osx(self) -> Override: + """ + Returns the OSX override. + """ + return Override._from_py_override(self._overrides.osx) + + @osx.setter + def osx(self, override: Override) -> VirtualPackageOverrides: + """ + Sets the OSX override. + """ + self._overrides.osx = override._override + return self._overrides.osx + + @property + def libc(self) -> Override: + """ + Returns the libc override. + """ + return Override._from_py_override(self._overrides.libc) + + @libc.setter + def libc(self, override: Override) -> VirtualPackageOverrides: + """ + Sets the libc override. + """ + self._overrides.libc = override._override + return self._overrides.libc + + @property + def cuda(self) -> Override: + """ + Returns the CUDA override. + """ + return Override._from_py_override(self._overrides.cuda) + + @cuda.setter + def cuda(self, override: Override) -> VirtualPackageOverrides: + """ + Sets the CUDA override. + """ + self._overrides.cuda = override._override + return self._overrides.cuda + + def __str__(self) -> str: + """ + Returns string representation of the VirtualPackageOverrides. + """ + return self._overrides.as_str() + + def __repr__(self) -> str: + """ + Returns a representation of the VirtualPackageOverrides. + """ + return f"VirtualPackageOverrides({self._overrides.as_str()})" + + class VirtualPackage: _virtual_package: PyVirtualPackage @@ -24,6 +159,16 @@ def current() -> List[VirtualPackage]: """ return [VirtualPackage._from_py_virtual_package(vp) for vp in PyVirtualPackage.current()] + @staticmethod + def current_with_overrides(overrides: VirtualPackageOverrides) -> List[VirtualPackage]: + """ + Returns virtual packages detected for the current system with the given overrides. + """ + return [ + VirtualPackage._from_py_virtual_package(vp) + for vp in PyVirtualPackage.current_with_overrides(overrides._overrides) + ] + def into_generic(self) -> GenericVirtualPackage: """ Returns a GenericVirtualPackage from VirtualPackage. diff --git a/py-rattler/src/lib.rs b/py-rattler/src/lib.rs index 570cf8cc4..3cfe48f3b 100644 --- a/py-rattler/src/lib.rs +++ b/py-rattler/src/lib.rs @@ -65,7 +65,7 @@ use run_exports_json::PyRunExportsJson; use shell::{PyActivationResult, PyActivationVariables, PyActivator, PyShellEnum}; use solver::{py_solve, py_solve_with_sparse_repodata}; use version::PyVersion; -use virtual_package::PyVirtualPackage; +use virtual_package::{PyOverride, PyVirtualPackage, PyVirtualPackageOverrides}; use crate::error::GatewayException; @@ -115,6 +115,8 @@ fn rattler(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(py_fetch_repo_data, m).unwrap()) .unwrap(); m.add_class::().unwrap(); + m.add_class::().unwrap(); + m.add_class::().unwrap(); m.add_class::().unwrap(); m.add_class::().unwrap(); m.add_class::().unwrap(); diff --git a/py-rattler/src/virtual_package.rs b/py-rattler/src/virtual_package.rs index 6f2b2d59c..2dcc33948 100644 --- a/py-rattler/src/virtual_package.rs +++ b/py-rattler/src/virtual_package.rs @@ -1,8 +1,74 @@ use pyo3::{pyclass, pymethods, PyResult}; -use rattler_virtual_packages::VirtualPackage; +use rattler_virtual_packages::{Override, VirtualPackage, VirtualPackageOverrides}; use crate::{error::PyRattlerError, generic_virtual_package::PyGenericVirtualPackage}; +#[pyclass] +#[repr(transparent)] +#[derive(Clone, Default)] +pub struct PyOverride { + pub(crate) inner: Override, +} + +impl From for PyOverride { + fn from(value: Override) -> Self { + Self { inner: value } + } +} + +impl From for Override { + fn from(value: PyOverride) -> Self { + value.inner + } +} + +#[pymethods] +impl PyOverride { + #[staticmethod] + pub fn none() -> Self { + Self { + inner: Override::None, + } + } + + pub fn as_str(&self) -> String { + format!("{:?}", self.inner) + } +} + +#[pyclass] +#[repr(transparent)] +#[derive(Clone, Default)] +pub struct PyVirtualPackageOverrides { + pub(crate) inner: VirtualPackageOverrides, +} + +impl From for PyVirtualPackageOverrides { + fn from(value: VirtualPackageOverrides) -> Self { + Self { inner: value } + } +} + +impl From for VirtualPackageOverrides { + fn from(value: PyVirtualPackageOverrides) -> Self { + value.inner + } +} + +#[pymethods] +impl PyVirtualPackageOverrides { + #[staticmethod] + pub fn none() -> Self { + Self { + inner: VirtualPackageOverrides::none(), + } + } + + pub fn as_str(&self) -> String { + format!("{:?}", self.inner) + } +} + #[pyclass] #[repr(transparent)] #[derive(Clone)] @@ -21,16 +87,22 @@ impl From for VirtualPackage { value.inner } } - #[pymethods] impl PyVirtualPackage { /// Returns virtual packages detected for the current system or an error if the versions could /// not be properly detected. #[staticmethod] pub fn current() -> PyResult> { - Ok(VirtualPackage::current() - .map(|vp| vp.iter().map(|v| v.clone().into()).collect::>()) - .map_err(PyRattlerError::from)?) + Self::current_with_overrides(&PyVirtualPackageOverrides::default()) + } + + #[staticmethod] + pub fn current_with_overrides(overrides: &PyVirtualPackageOverrides) -> PyResult> { + Ok( + VirtualPackage::current_with_overrides(&overrides.clone().into()) + .map(|vp| vp.iter().map(|v| v.clone().into()).collect::>()) + .map_err(PyRattlerError::from)?, + ) } pub fn as_generic(&self) -> PyGenericVirtualPackage { From 1e030e92e4b7ff9f26efa4bccdad540054efacda Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Wed, 28 Aug 2024 09:35:59 -0400 Subject: [PATCH 12/33] add a few more tests, do not use default env var name, just in case --- crates/rattler_virtual_packages/src/lib.rs | 44 ++++++++++++++-------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 6cd55907e..7224c02d3 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -131,19 +131,19 @@ pub enum VirtualPackage { /// Available on windows Win, - /// Available on unix based platforms + /// Available on `Unix` based platforms Unix, - /// Available when running on Linux + /// Available when running on `Linux`` Linux(Linux), - /// Available when running on OSX + /// Available when running on `OSX` Osx(Osx), - /// Available LibC family and version + /// Available `LibC` family and version LibC(LibC), - /// Available Cuda version + /// Available `Cuda` version Cuda(Cuda), /// The CPU architecture @@ -308,7 +308,7 @@ impl From for Linux { /// `LibC` virtual package description #[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)] pub struct LibC { - /// The family of LibC. This could be glibc for instance. + /// The family of `LibC`. This could be glibc for instance. pub family: String, /// The version of the libc distribution. @@ -593,19 +593,20 @@ mod test { version: Version::from_str(v).unwrap(), family: "glibc".into(), }; - env::set_var(LibC::DEFAULT_ENV_NAME, v); + let env_var_name = format!("{}_{}", LibC::DEFAULT_ENV_NAME, "12345511231"); + env::set_var(env_var_name.clone(), v); assert_eq!( - LibC::apply_override(&Override::DefaultEnvVar) + LibC::apply_override(&Override::EnvVar(env_var_name.clone())) .unwrap() .unwrap(), res ); - env::set_var(LibC::DEFAULT_ENV_NAME, ""); + env::set_var(env_var_name.clone(), ""); assert_eq!( - LibC::apply_override(&Override::DefaultEnvVar).unwrap(), + LibC::apply_override(&Override::EnvVar(env_var_name.clone())).unwrap(), None ); - env::remove_var(LibC::DEFAULT_ENV_NAME); + env::remove_var(env_var_name.clone()); assert_eq!( LibC::apply_override_or(&Override::DefaultEnvVar, || Ok(Some(res.clone()))) .unwrap() @@ -626,9 +627,21 @@ mod test { let res = Cuda { version: Version::from_str(v).unwrap(), }; - env::set_var(Cuda::DEFAULT_ENV_NAME, v); + let env_var_name = format!("{}_{}", Cuda::DEFAULT_ENV_NAME, "12345511231"); + env::set_var(env_var_name.clone(), v); assert_eq!( - Cuda::apply_override(&Override::DefaultEnvVar) + Cuda::apply_override(&Override::EnvVar(env_var_name.clone())) + .unwrap() + .unwrap(), + res + ); + assert_eq!( + Cuda::apply_override(&Override::None).map_err(|_x| 1), + ::current().map_err(|_x| 1) + ); + env::remove_var(env_var_name.clone()); + assert_eq!( + Cuda::apply_override(&Override::String(v.to_string())) .unwrap() .unwrap(), res @@ -641,9 +654,10 @@ mod test { let res = Osx { version: Version::from_str(v).unwrap(), }; - env::set_var(Osx::DEFAULT_ENV_NAME, v); + let env_var_name = format!("{}_{}", Osx::DEFAULT_ENV_NAME, "12345511231"); + env::set_var(env_var_name.clone(), v); assert_eq!( - Osx::apply_override(&Override::DefaultEnvVar) + Osx::apply_override(&Override::EnvVar(env_var_name.clone())) .unwrap() .unwrap(), res From 06dfb06f7d866688e3ad1ab7037399a053059212 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Wed, 28 Aug 2024 10:03:00 -0400 Subject: [PATCH 13/33] add a single python unit test --- py-rattler/rattler/__init__.py | 4 ++- .../rattler/virtual_package/__init__.py | 4 +-- .../virtual_package/virtual_package.py | 12 ++++----- py-rattler/tests/unit/test_override.py | 26 +++++++++++++++++++ 4 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 py-rattler/tests/unit/test_override.py diff --git a/py-rattler/rattler/__init__.py b/py-rattler/rattler/__init__.py index 131aeadf0..11fae0431 100644 --- a/py-rattler/rattler/__init__.py +++ b/py-rattler/rattler/__init__.py @@ -11,7 +11,7 @@ ) from rattler.channel import Channel, ChannelConfig, ChannelPriority from rattler.networking import AuthenticatedClient, fetch_repo_data -from rattler.virtual_package import GenericVirtualPackage, VirtualPackage +from rattler.virtual_package import GenericVirtualPackage, VirtualPackage, VirtualPackageOverrides, Override from rattler.package import ( PackageName, AboutJson, @@ -58,6 +58,8 @@ "fetch_repo_data", "GenericVirtualPackage", "VirtualPackage", + "VirtualPackageOverrides", + "Override", "PackageName", "PrefixRecord", "PrefixPaths", diff --git a/py-rattler/rattler/virtual_package/__init__.py b/py-rattler/rattler/virtual_package/__init__.py index 2e96eca51..2ce68f629 100644 --- a/py-rattler/rattler/virtual_package/__init__.py +++ b/py-rattler/rattler/virtual_package/__init__.py @@ -1,4 +1,4 @@ from rattler.virtual_package.generic import GenericVirtualPackage -from rattler.virtual_package.virtual_package import VirtualPackage +from rattler.virtual_package.virtual_package import VirtualPackage, VirtualPackageOverrides, Override -__all__ = ["GenericVirtualPackage", "VirtualPackage"] +__all__ = ["GenericVirtualPackage", "VirtualPackage", "VirtualPackageOverrides", "Override"] diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index 893618cd9..12e93d754 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -17,28 +17,28 @@ def _from_py_override(cls, py_override: PyOverride) -> Override: return override @classmethod - def _from_default_env_var(cls) -> Override: + def default_envvar(cls) -> Override: """ Returns the default environment variable override. """ return cls._from_py_override(PyOverride.default_env_var()) @classmethod - def _from_env_var(cls, env_var: str) -> Override: + def env_var(cls, env_var: str) -> Override: """ Returns the environment variable override for the given environment variable. """ return cls._from_py_override(PyOverride.env_var(env_var)) @classmethod - def _from_string(cls, override: str) -> Override: + def string(cls, override: str) -> Override: """ Returns the override for the given string. """ return cls._from_py_override(PyOverride.from_str(override)) @classmethod - def _from_none(cls) -> Override: + def none(cls) -> Override: """ Returns the override for None. """ @@ -70,14 +70,14 @@ def _from_py_virtual_package_overrides( return virtual_package_overrides @classmethod - def _from_default(cls) -> VirtualPackageOverrides: + def default(cls) -> VirtualPackageOverrides: """ Returns the default virtual package overrides. """ return cls._from_py_virtual_package_overrides(PyVirtualPackageOverrides.default()) @classmethod - def _from_none(cls) -> VirtualPackageOverrides: + def none(cls) -> VirtualPackageOverrides: """ Returns the virtual package overrides for None. """ diff --git a/py-rattler/tests/unit/test_override.py b/py-rattler/tests/unit/test_override.py new file mode 100644 index 000000000..0bc1e9724 --- /dev/null +++ b/py-rattler/tests/unit/test_override.py @@ -0,0 +1,26 @@ +from rattler import VirtualPackage, VirtualPackageOverrides, Override, Version + +def test_stuff(): + overrides = VirtualPackageOverrides.none() + assert overrides.osx == Override.none() + assert overrides.libc == Override.none() + assert overrides.cuda == Override.none() + overrides = VirtualPackageOverrides.default() + assert overrides.osx == Override.default() + assert overrides.libc == Override.default() + assert overrides.cuda == Override.default() + + overrides.osx = Override.string("123.45") + overrides.libc = Override.string("123.457") + overrides.cuda = Override.string("123.4578") + + r = VirtualPackage.current_with_overrides(overrides) + def find(name, ver): + for i in r: + if i.name == name: + assert i.version == Version(ver) + assert False + + find("__cuda", "123.4578") + find("__libc", "123.457") + find("__osx", "123.45") \ No newline at end of file From 2dc457724faafd8e453f1a7efb4276b011bb4e72 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Wed, 28 Aug 2024 10:31:18 -0400 Subject: [PATCH 14/33] add a python test for good measure --- crates/rattler_virtual_packages/src/lib.rs | 11 ++-- .../virtual_package/virtual_package.py | 12 +++- py-rattler/src/virtual_package.rs | 63 ++++++++++++++++++- py-rattler/tests/unit/test_override.py | 22 ++++--- 4 files changed, 90 insertions(+), 18 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 7224c02d3..1d97bda90 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -48,7 +48,7 @@ use linux::ParseLinuxVersionError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// Configure the overrides used in in this crate. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum Override { /// Use the default override env var name DefaultEnvVar, @@ -209,9 +209,12 @@ pub enum DetectVirtualPackageError { /// Configure the overrides used in in this crate. #[derive(Default, Clone, Debug)] pub struct VirtualPackageOverrides { - osx: Override, - libc: Override, - cuda: Override, + /// The override for the osx virtual package + pub osx: Override, + /// The override for the libc virtual package + pub libc: Override, + /// The override for the cuda virtual package + pub cuda: Override, } impl VirtualPackageOverrides { diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index 12e93d754..f8f522189 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -17,7 +17,7 @@ def _from_py_override(cls, py_override: PyOverride) -> Override: return override @classmethod - def default_envvar(cls) -> Override: + def default_env_var(cls) -> Override: """ Returns the default environment variable override. """ @@ -35,7 +35,7 @@ def string(cls, override: str) -> Override: """ Returns the override for the given string. """ - return cls._from_py_override(PyOverride.from_str(override)) + return cls._from_py_override(PyOverride.string(override)) @classmethod def none(cls) -> Override: @@ -56,6 +56,14 @@ def __repr__(self) -> str: """ return f"Override({self._override.as_str()})" + def __eq__(self, other: object) -> bool: + """ + Returns True if the Overrides are equal, False otherwise. + """ + if not isinstance(other, Override): + return NotImplemented + return self._override == other._override + class VirtualPackageOverrides: _overrides: PyVirtualPackageOverrides diff --git a/py-rattler/src/virtual_package.rs b/py-rattler/src/virtual_package.rs index 2dcc33948..338410820 100644 --- a/py-rattler/src/virtual_package.rs +++ b/py-rattler/src/virtual_package.rs @@ -5,7 +5,7 @@ use crate::{error::PyRattlerError, generic_virtual_package::PyGenericVirtualPack #[pyclass] #[repr(transparent)] -#[derive(Clone, Default)] +#[derive(Clone, Default, PartialEq)] pub struct PyOverride { pub(crate) inner: Override, } @@ -31,14 +31,39 @@ impl PyOverride { } } + #[staticmethod] + pub fn default_env_var() -> Self { + Self { + inner: Override::DefaultEnvVar, + } + } + + #[staticmethod] + pub fn env_var(name: &str) -> Self { + Self { + inner: Override::EnvVar(name.to_string()), + } + } + + #[staticmethod] + pub fn string(value: &str) -> Self { + Self { + inner: Override::String(value.to_string()), + } + } + pub fn as_str(&self) -> String { format!("{:?}", self.inner) } + + pub fn __eq__(&self, other: &Self) -> bool { + self.inner == other.inner + } } #[pyclass] #[repr(transparent)] -#[derive(Clone, Default)] +#[derive(Clone)] pub struct PyVirtualPackageOverrides { pub(crate) inner: VirtualPackageOverrides, } @@ -57,6 +82,13 @@ impl From for VirtualPackageOverrides { #[pymethods] impl PyVirtualPackageOverrides { + #[staticmethod] + pub fn default() -> Self { + Self { + inner: VirtualPackageOverrides::default(), + } + } + #[staticmethod] pub fn none() -> Self { Self { @@ -67,6 +99,33 @@ impl PyVirtualPackageOverrides { pub fn as_str(&self) -> String { format!("{:?}", self.inner) } + + #[getter] + pub fn get_osx(&self) -> PyOverride { + self.inner.osx.clone().into() + } + #[setter] + pub fn set_osx(&mut self, value: PyOverride) { + self.inner.osx = value.into(); + } + #[getter] + pub fn get_cuda(&self) -> PyOverride { + self.inner.cuda.clone().into() + } + #[setter] + pub fn set_cuda(&mut self, value: PyOverride) { + self.inner.cuda = value.into(); + } + #[getter] + pub fn get_libc(&self) -> PyOverride { + self.inner.libc.clone().into() + } + #[setter] + pub fn set_libc(&mut self, value: PyOverride) { + self.inner.libc = value.into(); + } + + } #[pyclass] diff --git a/py-rattler/tests/unit/test_override.py b/py-rattler/tests/unit/test_override.py index 0bc1e9724..c05cc5a6b 100644 --- a/py-rattler/tests/unit/test_override.py +++ b/py-rattler/tests/unit/test_override.py @@ -1,26 +1,28 @@ -from rattler import VirtualPackage, VirtualPackageOverrides, Override, Version +from rattler import VirtualPackage, VirtualPackageOverrides, Override, Version, PackageName def test_stuff(): overrides = VirtualPackageOverrides.none() + print(overrides.osx, Override.none()) assert overrides.osx == Override.none() assert overrides.libc == Override.none() assert overrides.cuda == Override.none() overrides = VirtualPackageOverrides.default() - assert overrides.osx == Override.default() - assert overrides.libc == Override.default() - assert overrides.cuda == Override.default() + assert overrides.osx == Override.default_env_var() + assert overrides.libc == Override.default_env_var() + assert overrides.cuda == Override.default_env_var() overrides.osx = Override.string("123.45") overrides.libc = Override.string("123.457") overrides.cuda = Override.string("123.4578") - r = VirtualPackage.current_with_overrides(overrides) - def find(name, ver): + r = [i.into_generic() for i in VirtualPackage.current_with_overrides(overrides)] + def find(name, ver, must_find=True): for i in r: - if i.name == name: + if i.name.source == name: assert i.version == Version(ver) - assert False + return + assert not must_find find("__cuda", "123.4578") - find("__libc", "123.457") - find("__osx", "123.45") \ No newline at end of file + find("__libc", "123.4578", False) + find("__osx", "123.45", False) \ No newline at end of file From 38108610f31912b6abdb00685198061d3aa2533e Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Wed, 28 Aug 2024 10:34:33 -0400 Subject: [PATCH 15/33] add annotation --- py-rattler/tests/unit/test_override.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py-rattler/tests/unit/test_override.py b/py-rattler/tests/unit/test_override.py index c05cc5a6b..c079b7fde 100644 --- a/py-rattler/tests/unit/test_override.py +++ b/py-rattler/tests/unit/test_override.py @@ -1,6 +1,6 @@ from rattler import VirtualPackage, VirtualPackageOverrides, Override, Version, PackageName -def test_stuff(): +def test_stuff() -> None: overrides = VirtualPackageOverrides.none() print(overrides.osx, Override.none()) assert overrides.osx == Override.none() @@ -16,7 +16,7 @@ def test_stuff(): overrides.cuda = Override.string("123.4578") r = [i.into_generic() for i in VirtualPackage.current_with_overrides(overrides)] - def find(name, ver, must_find=True): + def find(name, ver, must_find=True) -> None: for i in r: if i.name.source == name: assert i.version == Version(ver) From def7eb6024f4ee3fdebf19d47925b64d9bef07df Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Wed, 28 Aug 2024 12:03:35 -0400 Subject: [PATCH 16/33] fix doc --- crates/rattler_virtual_packages/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 1d97bda90..037d85cbc 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -81,7 +81,7 @@ pub trait EnvOverride: Sized { } } - /// Read the environment variable and if it exists, try to parse it with [`EnvOverride::from_env_var_name_with_var`] + /// Read the environment variable and if it exists, try to parse it with [`EnvOverride::parse_version`] /// If the output is: /// - `None`, then the environment variable did not exist, /// - `Some(Err(None))`, then the environment variable exist but was set to zero, so the package should be disabled From f4a9803860ff9afeb281b9395680cfb8c6309478 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Wed, 28 Aug 2024 12:07:21 -0400 Subject: [PATCH 17/33] annotate test --- py-rattler/tests/unit/test_override.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py-rattler/tests/unit/test_override.py b/py-rattler/tests/unit/test_override.py index c079b7fde..e21c6c14c 100644 --- a/py-rattler/tests/unit/test_override.py +++ b/py-rattler/tests/unit/test_override.py @@ -16,9 +16,9 @@ def test_stuff() -> None: overrides.cuda = Override.string("123.4578") r = [i.into_generic() for i in VirtualPackage.current_with_overrides(overrides)] - def find(name, ver, must_find=True) -> None: + def find(name: str, ver: str, must_find: bool=True) -> None: for i in r: - if i.name.source == name: + if i.name == PackageName(name): assert i.version == Version(ver) return assert not must_find From 184f1a473138f976ed1f607053fc60aaa126bf92 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Wed, 28 Aug 2024 12:11:35 -0400 Subject: [PATCH 18/33] fmt --- py-rattler/src/virtual_package.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/py-rattler/src/virtual_package.rs b/py-rattler/src/virtual_package.rs index 338410820..d88feaffb 100644 --- a/py-rattler/src/virtual_package.rs +++ b/py-rattler/src/virtual_package.rs @@ -124,8 +124,6 @@ impl PyVirtualPackageOverrides { pub fn set_libc(&mut self, value: PyOverride) { self.inner.libc = value.into(); } - - } #[pyclass] From 15a9b4b91efec2fd3db50c39fe23ae67ec924f30 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 09:11:48 -0400 Subject: [PATCH 19/33] Update crates/rattler_virtual_packages/src/lib.rs Co-authored-by: Bas Zalmstra --- crates/rattler_virtual_packages/src/lib.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 037d85cbc..05fd5e7e3 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -48,9 +48,10 @@ use linux::ParseLinuxVersionError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// Configure the overrides used in in this crate. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub enum Override { /// Use the default override env var name + #[default] DefaultEnvVar, /// Use custom env var name EnvVar(String), @@ -60,12 +61,6 @@ pub enum Override { None, } -impl Default for Override { - fn default() -> Self { - Self::DefaultEnvVar - } -} - /// Traits for overridable virtual packages /// Use as `Cuda::from_default_env_var.unwrap_or(Cuda::current().into()).unwrap()` pub trait EnvOverride: Sized { From 237c669b212a183a6dd039c7c7bbeb81b7abdccb Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 09:19:31 -0400 Subject: [PATCH 20/33] Update py-rattler/rattler/virtual_package/virtual_package.py Co-authored-by: Bas Zalmstra --- py-rattler/rattler/virtual_package/virtual_package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index f8f522189..883da4b8c 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -19,7 +19,7 @@ def _from_py_override(cls, py_override: PyOverride) -> Override: @classmethod def default_env_var(cls) -> Override: """ - Returns the default environment variable override. + Returns a new instance to indicate that the default environment variable should overwrite the detected information from the host if specified. """ return cls._from_py_override(PyOverride.default_env_var()) From a7cabed8bb79001e87f7da72cbc8577ce19be1d6 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 09:58:43 -0400 Subject: [PATCH 21/33] rename some stuff --- crates/rattler_virtual_packages/src/lib.rs | 76 +++++++++++-------- .../virtual_package/virtual_package.py | 32 ++++++-- py-rattler/src/virtual_package.rs | 13 +++- py-rattler/tests/unit/test_override.py | 4 +- 4 files changed, 81 insertions(+), 44 deletions(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 1d97bda90..1c3c51181 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -67,13 +67,13 @@ impl Default for Override { } /// Traits for overridable virtual packages -/// Use as `Cuda::from_default_env_var.unwrap_or(Cuda::current().into()).unwrap()` +/// Use as `Cuda::detect_with_overrides(override)` pub trait EnvOverride: Sized { /// Parse `env_var_value` fn parse_version(value: &str) -> Result; /// Helper to convert the output of `parse_version` and handling empty strings. - fn parse_version_(value: &str) -> Result, DetectVirtualPackageError> { + fn parse_version_opt(value: &str) -> Result, DetectVirtualPackageError> { if value.is_empty() { Ok(None) } else { @@ -88,14 +88,14 @@ pub trait EnvOverride: Sized { /// - `Some(Ok(pkg))`, then the override was for the package. fn from_env_var_name_or( env_var_name: &str, - f: F, + fallback: F, ) -> Result, DetectVirtualPackageError> where F: FnOnce() -> Result, DetectVirtualPackageError>, { match env::var(env_var_name) { - Ok(var) => Self::parse_version_(&var), - Err(env::VarError::NotPresent) => f(), + Ok(var) => Self::parse_version_opt(&var), + Err(env::VarError::NotPresent) => fallback(), Err(e) => Err(DetectVirtualPackageError::VarError(e)), } } @@ -103,25 +103,28 @@ pub trait EnvOverride: Sized { /// Default name of the environment variable that overrides the virtual package. const DEFAULT_ENV_NAME: &'static str; + /// Detect the virutal package for the current system. /// This method is here so that `::current` always returns the same error type. - fn current() -> Result, DetectVirtualPackageError>; + /// `current` may return different types of errors depending on the virtual package. This one always returns + /// `DetectVirtualPackageError`. + fn detect_from_host() -> Result, DetectVirtualPackageError>; /// Apply the override to the current virtual package. If the override is `None` then use the fallback - fn apply_override_or(ov: &Override, f: F) -> Result, DetectVirtualPackageError> + fn detect_with_fallback(ov: &Override, fallback: F) -> Result, DetectVirtualPackageError> where F: FnOnce() -> Result, DetectVirtualPackageError>, { match ov { - Override::None => f(), - Override::String(str) => Self::parse_version_(str), - Override::DefaultEnvVar => Self::from_env_var_name_or(Self::DEFAULT_ENV_NAME, f), - Override::EnvVar(name) => Self::from_env_var_name_or(name, f), + Override::None => fallback(), + Override::String(str) => Self::parse_version_opt(str), + Override::DefaultEnvVar => Self::from_env_var_name_or(Self::DEFAULT_ENV_NAME, fallback), + Override::EnvVar(name) => Self::from_env_var_name_or(name, fallback), } } - /// Shortcut for `apply_override_or` with `Self::current` - fn apply_override(ov: &Override) -> Result, DetectVirtualPackageError> { - Self::apply_override_or(ov, Self::current) + /// Shortcut for `Self::detect_with_fallback` with `Self::detect_from_host` as fallback + fn detect_with_overrides(ov: &Override) -> Result, DetectVirtualPackageError> { + Self::detect_with_fallback(ov, Self::detect_from_host) } } @@ -175,12 +178,21 @@ impl From for GenericVirtualPackage { impl VirtualPackage { /// Returns virtual packages detected for the current system or an error if the versions could /// not be properly detected. + #[deprecated( + since = "1.0.4", + note = "Use `Self::detect` instead" + )] pub fn current() -> Result, DetectVirtualPackageError> { + try_detect_virtual_packages_with_overrides(&VirtualPackageOverrides::none()) + } + + /// Detect the virtual packages of the current system with the default overrides. + pub fn detect() -> Result, DetectVirtualPackageError> { try_detect_virtual_packages_with_overrides(&VirtualPackageOverrides::default()) } - /// use custom overrides - pub fn current_with_overrides( + /// Detect the virtual packages of the current system with the given overrides. + pub fn detect_with_overrides( overrides: &VirtualPackageOverrides, ) -> Result, DetectVirtualPackageError> { try_detect_virtual_packages_with_overrides(overrides) @@ -247,18 +259,18 @@ fn try_detect_virtual_packages_with_overrides( if let Some(linux_version) = Linux::current()? { result.push(linux_version.into()); } - if let Some(libc) = LibC::apply_override(&overrides.libc)? { + if let Some(libc) = LibC::detect_with_overrides(&overrides.libc)? { result.push(libc.into()); } } if platform.is_osx() { - if let Some(osx) = Osx::apply_override(&overrides.osx)? { + if let Some(osx) = Osx::detect_with_overrides(&overrides.osx)? { result.push(osx.into()); } } - if let Some(cuda) = Cuda::apply_override(&overrides.cuda)? { + if let Some(cuda) = Cuda::detect_with_overrides(&overrides.cuda)? { result.push(cuda.into()); } @@ -359,7 +371,7 @@ impl EnvOverride for LibC { }) } - fn current() -> Result, DetectVirtualPackageError> { + fn detect_from_host() -> Result, DetectVirtualPackageError> { Ok(Self::current()?) } } @@ -388,7 +400,7 @@ impl EnvOverride for Cuda { fn parse_version(env_var_value: &str) -> Result { Version::from_str(env_var_value).map(|version| Self { version }) } - fn current() -> Result, DetectVirtualPackageError> { + fn detect_from_host() -> Result, DetectVirtualPackageError> { Ok(Self::current()) } const DEFAULT_ENV_NAME: &'static str = "CONDA_OVERRIDE_CUDA"; @@ -564,7 +576,7 @@ impl EnvOverride for Osx { fn parse_version(env_var_value: &str) -> Result { Version::from_str(env_var_value).map(|version| Self { version }) } - fn current() -> Result, DetectVirtualPackageError> { + fn detect_from_host() -> Result, DetectVirtualPackageError> { Ok(Self::current()?) } const DEFAULT_ENV_NAME: &'static str = "CONDA_OVERRIDE_OSX"; @@ -586,7 +598,7 @@ mod test { #[test] fn doesnt_crash() { - let virtual_packages = VirtualPackage::current().unwrap(); + let virtual_packages = VirtualPackage::detect().unwrap(); println!("{virtual_packages:?}"); } #[test] @@ -599,25 +611,25 @@ mod test { let env_var_name = format!("{}_{}", LibC::DEFAULT_ENV_NAME, "12345511231"); env::set_var(env_var_name.clone(), v); assert_eq!( - LibC::apply_override(&Override::EnvVar(env_var_name.clone())) + LibC::detect_with_overrides(&Override::EnvVar(env_var_name.clone())) .unwrap() .unwrap(), res ); env::set_var(env_var_name.clone(), ""); assert_eq!( - LibC::apply_override(&Override::EnvVar(env_var_name.clone())).unwrap(), + LibC::detect_with_overrides(&Override::EnvVar(env_var_name.clone())).unwrap(), None ); env::remove_var(env_var_name.clone()); assert_eq!( - LibC::apply_override_or(&Override::DefaultEnvVar, || Ok(Some(res.clone()))) + LibC::detect_with_fallback(&Override::DefaultEnvVar, || Ok(Some(res.clone()))) .unwrap() .unwrap(), res ); assert_eq!( - LibC::apply_override_or(&Override::String(v.to_string()), || Ok(None)) + LibC::detect_with_fallback(&Override::String(v.to_string()), || Ok(None)) .unwrap() .unwrap(), res @@ -633,18 +645,18 @@ mod test { let env_var_name = format!("{}_{}", Cuda::DEFAULT_ENV_NAME, "12345511231"); env::set_var(env_var_name.clone(), v); assert_eq!( - Cuda::apply_override(&Override::EnvVar(env_var_name.clone())) + Cuda::detect_with_overrides(&Override::EnvVar(env_var_name.clone())) .unwrap() .unwrap(), res ); assert_eq!( - Cuda::apply_override(&Override::None).map_err(|_x| 1), - ::current().map_err(|_x| 1) + Cuda::detect_with_overrides(&Override::None).map_err(|_x| 1), + ::detect_from_host().map_err(|_x| 1) ); env::remove_var(env_var_name.clone()); assert_eq!( - Cuda::apply_override(&Override::String(v.to_string())) + Cuda::detect_with_overrides(&Override::String(v.to_string())) .unwrap() .unwrap(), res @@ -660,7 +672,7 @@ mod test { let env_var_name = format!("{}_{}", Osx::DEFAULT_ENV_NAME, "12345511231"); env::set_var(env_var_name.clone(), v); assert_eq!( - Osx::apply_override(&Override::EnvVar(env_var_name.clone())) + Osx::detect_with_overrides(&Override::EnvVar(env_var_name.clone())) .unwrap() .unwrap(), res diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index f8f522189..d8f8a3314 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -1,12 +1,21 @@ from __future__ import annotations +from typing import List +import warnings from rattler.rattler import PyVirtualPackage, PyOverride, PyVirtualPackageOverrides -from typing import List from rattler.virtual_package.generic import GenericVirtualPackage - class Override: + """ + Represents an override for a virtual package. + An override can be build using + - `Override.default_env_var()` for overriding the detection with the default environment variable, + - `Override.env_var(str)` for overriding the detection with a custom environment variable, + - `Override.string(str)` for passing the version directly, or + - `Override.none()` for disabling the override process all together. + """ + _override: PyOverride @classmethod @@ -77,12 +86,12 @@ def _from_py_virtual_package_overrides( virtual_package_overrides._overrides = py_virtual_package_overrides return virtual_package_overrides - @classmethod - def default(cls) -> VirtualPackageOverrides: + + def __init__(self) -> VirtualPackageOverrides: """ Returns the default virtual package overrides. """ - return cls._from_py_virtual_package_overrides(PyVirtualPackageOverrides.default()) + self._overrides = PyVirtualPackageOverrides.default() @classmethod def none(cls) -> VirtualPackageOverrides: @@ -161,6 +170,15 @@ def _from_py_virtual_package(cls, py_virtual_package: PyVirtualPackage) -> Virtu @staticmethod def current() -> List[VirtualPackage]: + """ + Returns virtual packages detected for the current system or an error + if the versions could not be properly detected. + """ + warnings.warn("Use `detect` instead") + return [VirtualPackage._from_py_virtual_package(vp) for vp in PyVirtualPackage.current()] + + @staticmethod + def detect() -> List[VirtualPackage]: """ Returns virtual packages detected for the current system or an error if the versions could not be properly detected. @@ -168,13 +186,13 @@ def current() -> List[VirtualPackage]: return [VirtualPackage._from_py_virtual_package(vp) for vp in PyVirtualPackage.current()] @staticmethod - def current_with_overrides(overrides: VirtualPackageOverrides) -> List[VirtualPackage]: + def detect_with_overrides(overrides: VirtualPackageOverrides) -> List[VirtualPackage]: """ Returns virtual packages detected for the current system with the given overrides. """ return [ VirtualPackage._from_py_virtual_package(vp) - for vp in PyVirtualPackage.current_with_overrides(overrides._overrides) + for vp in PyVirtualPackage.detect_with_overrides(overrides._overrides) ] def into_generic(self) -> GenericVirtualPackage: diff --git a/py-rattler/src/virtual_package.rs b/py-rattler/src/virtual_package.rs index 338410820..2abafbdd5 100644 --- a/py-rattler/src/virtual_package.rs +++ b/py-rattler/src/virtual_package.rs @@ -151,14 +151,21 @@ impl PyVirtualPackage { /// Returns virtual packages detected for the current system or an error if the versions could /// not be properly detected. #[staticmethod] + #[deprecated(note = "Use `Self::detect` instead.")] pub fn current() -> PyResult> { - Self::current_with_overrides(&PyVirtualPackageOverrides::default()) + Self::detect_with_overrides(&PyVirtualPackageOverrides::none()) } #[staticmethod] - pub fn current_with_overrides(overrides: &PyVirtualPackageOverrides) -> PyResult> { + pub fn detect() -> PyResult> { + Self::detect_with_overrides(&PyVirtualPackageOverrides::default()) + } + + + #[staticmethod] + pub fn detect_with_overrides(overrides: &PyVirtualPackageOverrides) -> PyResult> { Ok( - VirtualPackage::current_with_overrides(&overrides.clone().into()) + VirtualPackage::detect_with_overrides(&overrides.clone().into()) .map(|vp| vp.iter().map(|v| v.clone().into()).collect::>()) .map_err(PyRattlerError::from)?, ) diff --git a/py-rattler/tests/unit/test_override.py b/py-rattler/tests/unit/test_override.py index c079b7fde..4edaf7527 100644 --- a/py-rattler/tests/unit/test_override.py +++ b/py-rattler/tests/unit/test_override.py @@ -6,7 +6,7 @@ def test_stuff() -> None: assert overrides.osx == Override.none() assert overrides.libc == Override.none() assert overrides.cuda == Override.none() - overrides = VirtualPackageOverrides.default() + overrides = VirtualPackageOverrides() assert overrides.osx == Override.default_env_var() assert overrides.libc == Override.default_env_var() assert overrides.cuda == Override.default_env_var() @@ -15,7 +15,7 @@ def test_stuff() -> None: overrides.libc = Override.string("123.457") overrides.cuda = Override.string("123.4578") - r = [i.into_generic() for i in VirtualPackage.current_with_overrides(overrides)] + r = [i.into_generic() for i in VirtualPackage.detect_with_overrides(overrides)] def find(name, ver, must_find=True) -> None: for i in r: if i.name.source == name: From 8f17402b060b245b60b1a64f263effbaca8fbda9 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 10:08:09 -0400 Subject: [PATCH 22/33] fmt, stop using current --- crates/rattler-bin/src/commands/create.rs | 2 +- crates/rattler-bin/src/commands/virtual_packages.rs | 2 +- crates/rattler_virtual_packages/src/lib.rs | 10 +++++----- py-rattler/examples/solve_and_install.py | 2 +- py-rattler/rattler/virtual_package/virtual_package.py | 2 +- py-rattler/src/virtual_package.rs | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/rattler-bin/src/commands/create.rs b/crates/rattler-bin/src/commands/create.rs index 5b3dcf305..11eedef30 100644 --- a/crates/rattler-bin/src/commands/create.rs +++ b/crates/rattler-bin/src/commands/create.rs @@ -193,7 +193,7 @@ pub async fn create(opt: Opt) -> anyhow::Result<()> { }) .collect::>>()?) } else { - rattler_virtual_packages::VirtualPackage::current() + rattler_virtual_packages::VirtualPackage::detect() .map(|vpkgs| { vpkgs .iter() diff --git a/crates/rattler-bin/src/commands/virtual_packages.rs b/crates/rattler-bin/src/commands/virtual_packages.rs index 719e62970..8aa35ee0f 100644 --- a/crates/rattler-bin/src/commands/virtual_packages.rs +++ b/crates/rattler-bin/src/commands/virtual_packages.rs @@ -4,7 +4,7 @@ use rattler_conda_types::GenericVirtualPackage; pub struct Opt {} pub fn virtual_packages(_opt: Opt) -> anyhow::Result<()> { - let virtual_packages = rattler_virtual_packages::VirtualPackage::current()?; + let virtual_packages = rattler_virtual_packages::VirtualPackage::detect()?; for package in virtual_packages { println!("{}", GenericVirtualPackage::from(package.clone())); } diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 1c5df5c4b..c33c3e811 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -105,7 +105,10 @@ pub trait EnvOverride: Sized { fn detect_from_host() -> Result, DetectVirtualPackageError>; /// Apply the override to the current virtual package. If the override is `None` then use the fallback - fn detect_with_fallback(ov: &Override, fallback: F) -> Result, DetectVirtualPackageError> + fn detect_with_fallback( + ov: &Override, + fallback: F, + ) -> Result, DetectVirtualPackageError> where F: FnOnce() -> Result, DetectVirtualPackageError>, { @@ -173,10 +176,7 @@ impl From for GenericVirtualPackage { impl VirtualPackage { /// Returns virtual packages detected for the current system or an error if the versions could /// not be properly detected. - #[deprecated( - since = "1.0.4", - note = "Use `Self::detect` instead" - )] + #[deprecated(since = "1.0.4", note = "Use `Self::detect` instead")] pub fn current() -> Result, DetectVirtualPackageError> { try_detect_virtual_packages_with_overrides(&VirtualPackageOverrides::none()) } diff --git a/py-rattler/examples/solve_and_install.py b/py-rattler/examples/solve_and_install.py index 5cd7640c1..3f84c6f18 100644 --- a/py-rattler/examples/solve_and_install.py +++ b/py-rattler/examples/solve_and_install.py @@ -16,7 +16,7 @@ async def main() -> None: # The specs to solve for specs=["python ~=3.12.0", "pip", "requests 2.31.0"], # Virtual packages define the specifications of the environment - virtual_packages=VirtualPackage.current(), + virtual_packages=VirtualPackage.detect(), ) print("solved required dependencies") diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index 00aca59a7..a147c6b68 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -183,7 +183,7 @@ def detect() -> List[VirtualPackage]: Returns virtual packages detected for the current system or an error if the versions could not be properly detected. """ - return [VirtualPackage._from_py_virtual_package(vp) for vp in PyVirtualPackage.current()] + return [VirtualPackage._from_py_virtual_package(vp) for vp in PyVirtualPackage.detect()] @staticmethod def detect_with_overrides(overrides: VirtualPackageOverrides) -> List[VirtualPackage]: diff --git a/py-rattler/src/virtual_package.rs b/py-rattler/src/virtual_package.rs index 4098a17a3..01bb0e370 100644 --- a/py-rattler/src/virtual_package.rs +++ b/py-rattler/src/virtual_package.rs @@ -149,7 +149,7 @@ impl PyVirtualPackage { /// Returns virtual packages detected for the current system or an error if the versions could /// not be properly detected. #[staticmethod] - #[deprecated(note = "Use `Self::detect` instead.")] + #[deprecated(note = "Use `Self::detect()` instead.")] pub fn current() -> PyResult> { Self::detect_with_overrides(&PyVirtualPackageOverrides::none()) } From 1618ae0dffc614894fe801ba309db51e82570ded Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 10:14:40 -0400 Subject: [PATCH 23/33] bump --- py-rattler/src/virtual_package.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/py-rattler/src/virtual_package.rs b/py-rattler/src/virtual_package.rs index 01bb0e370..716b2ec47 100644 --- a/py-rattler/src/virtual_package.rs +++ b/py-rattler/src/virtual_package.rs @@ -148,8 +148,9 @@ impl From for VirtualPackage { impl PyVirtualPackage { /// Returns virtual packages detected for the current system or an error if the versions could /// not be properly detected. + // marking this as depreacted causes a warning when building the code, + // we just warn directly from python. #[staticmethod] - #[deprecated(note = "Use `Self::detect()` instead.")] pub fn current() -> PyResult> { Self::detect_with_overrides(&PyVirtualPackageOverrides::none()) } From a6a84038dae140fab6d9d8cac01e1b17d4aaa1df Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 10:23:57 -0400 Subject: [PATCH 24/33] mypy --- py-rattler/rattler/virtual_package/virtual_package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index a147c6b68..3cde389d4 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -87,7 +87,7 @@ def _from_py_virtual_package_overrides( return virtual_package_overrides - def __init__(self) -> VirtualPackageOverrides: + def __init__(self) -> None: """ Returns the default virtual package overrides. """ From 752bdd2b36748ebfcd024279c309a88a0cd64b36 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 10:33:19 -0400 Subject: [PATCH 25/33] ruf --- py-rattler/rattler/virtual_package/virtual_package.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index 3cde389d4..4be636136 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -6,9 +6,10 @@ from rattler.virtual_package.generic import GenericVirtualPackage + class Override: """ - Represents an override for a virtual package. + Represents an override for a virtual package. An override can be build using - `Override.default_env_var()` for overriding the detection with the default environment variable, - `Override.env_var(str)` for overriding the detection with a custom environment variable, @@ -86,7 +87,6 @@ def _from_py_virtual_package_overrides( virtual_package_overrides._overrides = py_virtual_package_overrides return virtual_package_overrides - def __init__(self) -> None: """ Returns the default virtual package overrides. From 976c30f8b971b3bf0cf6f8bdd643b3fb38f4e3fe Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 10:39:33 -0400 Subject: [PATCH 26/33] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --- py-rattler/src/virtual_package.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/py-rattler/src/virtual_package.rs b/py-rattler/src/virtual_package.rs index 716b2ec47..97d6e5f1e 100644 --- a/py-rattler/src/virtual_package.rs +++ b/py-rattler/src/virtual_package.rs @@ -160,7 +160,6 @@ impl PyVirtualPackage { Self::detect_with_overrides(&PyVirtualPackageOverrides::default()) } - #[staticmethod] pub fn detect_with_overrides(overrides: &PyVirtualPackageOverrides) -> PyResult> { Ok( From fb21bf4bc1e3e921dfd44b683c7d4600fbbf6805 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 13:25:26 -0400 Subject: [PATCH 27/33] Update crates/rattler_virtual_packages/src/lib.rs Co-authored-by: Bas Zalmstra --- crates/rattler_virtual_packages/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index c33c3e811..b52599454 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -213,7 +213,7 @@ pub enum DetectVirtualPackageError { #[error(transparent)] VersionParseError(#[from] ParseVersionError), } -/// Configure the overrides used in in this crate. +/// Configure the overrides used in this crate. #[derive(Default, Clone, Debug)] pub struct VirtualPackageOverrides { /// The override for the osx virtual package From b79dde077d020a3e18435e23ebd6c4d52e1a48b8 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 13:35:16 -0400 Subject: [PATCH 28/33] apply @Baszalmastra's suggetions --- crates/rattler-bin/src/commands/create.rs | 18 +++++++------- .../src/commands/virtual_packages.rs | 4 +++- crates/rattler_virtual_packages/src/lib.rs | 5 ---- .../virtual_package/virtual_package.py | 24 +++++++++---------- py-rattler/tests/unit/test_override.py | 2 +- 5 files changed, 26 insertions(+), 27 deletions(-) diff --git a/crates/rattler-bin/src/commands/create.rs b/crates/rattler-bin/src/commands/create.rs index 11eedef30..79a797914 100644 --- a/crates/rattler-bin/src/commands/create.rs +++ b/crates/rattler-bin/src/commands/create.rs @@ -193,14 +193,16 @@ pub async fn create(opt: Opt) -> anyhow::Result<()> { }) .collect::>>()?) } else { - rattler_virtual_packages::VirtualPackage::detect() - .map(|vpkgs| { - vpkgs - .iter() - .map(|vpkg| GenericVirtualPackage::from(vpkg.clone())) - .collect::>() - }) - .map_err(anyhow::Error::from) + rattler_virtual_packages::VirtualPackage::detect_with_overrides( + &rattler_virtual_packages::VirtualPackageOverrides::default(), + ) + .map(|vpkgs| { + vpkgs + .iter() + .map(|vpkg| GenericVirtualPackage::from(vpkg.clone())) + .collect::>() + }) + .map_err(anyhow::Error::from) } })?; diff --git a/crates/rattler-bin/src/commands/virtual_packages.rs b/crates/rattler-bin/src/commands/virtual_packages.rs index 8aa35ee0f..1c54e8cc7 100644 --- a/crates/rattler-bin/src/commands/virtual_packages.rs +++ b/crates/rattler-bin/src/commands/virtual_packages.rs @@ -4,7 +4,9 @@ use rattler_conda_types::GenericVirtualPackage; pub struct Opt {} pub fn virtual_packages(_opt: Opt) -> anyhow::Result<()> { - let virtual_packages = rattler_virtual_packages::VirtualPackage::detect()?; + let virtual_packages = rattler_virtual_packages::VirtualPackage::detect_with_overrides( + &rattler_virtual_packages::VirtualPackageOverrides::default(), + )?; for package in virtual_packages { println!("{}", GenericVirtualPackage::from(package.clone())); } diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index b52599454..2b814e524 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -181,11 +181,6 @@ impl VirtualPackage { try_detect_virtual_packages_with_overrides(&VirtualPackageOverrides::none()) } - /// Detect the virtual packages of the current system with the default overrides. - pub fn detect() -> Result, DetectVirtualPackageError> { - try_detect_virtual_packages_with_overrides(&VirtualPackageOverrides::default()) - } - /// Detect the virtual packages of the current system with the given overrides. pub fn detect_with_overrides( overrides: &VirtualPackageOverrides, diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index 4be636136..46effaf61 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -87,11 +87,18 @@ def _from_py_virtual_package_overrides( virtual_package_overrides._overrides = py_virtual_package_overrides return virtual_package_overrides - def __init__(self) -> None: + def __init__(self, osx=None, libc=None, cuda=None) -> None: """ Returns the default virtual package overrides. """ self._overrides = PyVirtualPackageOverrides.default() + if osx is not None: + self.osx = osx + if libc is not None: + self.libc = libc + if cuda is not None: + self.cuda = cuda + @classmethod def none(cls) -> VirtualPackageOverrides: @@ -175,24 +182,17 @@ def current() -> List[VirtualPackage]: if the versions could not be properly detected. """ warnings.warn("Use `detect` instead") - return [VirtualPackage._from_py_virtual_package(vp) for vp in PyVirtualPackage.current()] - - @staticmethod - def detect() -> List[VirtualPackage]: - """ - Returns virtual packages detected for the current system or an error - if the versions could not be properly detected. - """ - return [VirtualPackage._from_py_virtual_package(vp) for vp in PyVirtualPackage.detect()] + return VirtualPackage.detect_with_overrides(VirtualPackageOverrides.none()) @staticmethod - def detect_with_overrides(overrides: VirtualPackageOverrides) -> List[VirtualPackage]: + def detect_with_overrides(overrides: VirtualPackageOverrides | None = None) -> List[VirtualPackage]: """ Returns virtual packages detected for the current system with the given overrides. """ + _overrides: VirtualPackageOverrides = overrides or VirtualPackageOverrides() return [ VirtualPackage._from_py_virtual_package(vp) - for vp in PyVirtualPackage.detect_with_overrides(overrides._overrides) + for vp in PyVirtualPackage.detect_with_overrides(_overrides._overrides) ] def into_generic(self) -> GenericVirtualPackage: diff --git a/py-rattler/tests/unit/test_override.py b/py-rattler/tests/unit/test_override.py index 5fb976abd..5438307fc 100644 --- a/py-rattler/tests/unit/test_override.py +++ b/py-rattler/tests/unit/test_override.py @@ -1,6 +1,6 @@ from rattler import VirtualPackage, VirtualPackageOverrides, Override, Version, PackageName -def test_stuff() -> None: +def test_overrides() -> None: overrides = VirtualPackageOverrides.none() print(overrides.osx, Override.none()) assert overrides.osx == Override.none() From d6c8d59e506ddc2d896a44773a2daaf72214c2b6 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 14:48:58 -0400 Subject: [PATCH 29/33] use `Default::default()` --- crates/rattler-bin/src/commands/create.rs | 2 +- .../src/commands/virtual_packages.rs | 4 +-- crates/rattler_virtual_packages/src/lib.rs | 29 ++++++++++--------- .../virtual_package/virtual_package.py | 9 +++--- py-rattler/src/virtual_package.rs | 17 ++++------- py-rattler/tests/unit/test_override.py | 12 ++++---- 6 files changed, 34 insertions(+), 39 deletions(-) diff --git a/crates/rattler-bin/src/commands/create.rs b/crates/rattler-bin/src/commands/create.rs index 79a797914..7c840a77a 100644 --- a/crates/rattler-bin/src/commands/create.rs +++ b/crates/rattler-bin/src/commands/create.rs @@ -193,7 +193,7 @@ pub async fn create(opt: Opt) -> anyhow::Result<()> { }) .collect::>>()?) } else { - rattler_virtual_packages::VirtualPackage::detect_with_overrides( + rattler_virtual_packages::VirtualPackage::detect( &rattler_virtual_packages::VirtualPackageOverrides::default(), ) .map(|vpkgs| { diff --git a/crates/rattler-bin/src/commands/virtual_packages.rs b/crates/rattler-bin/src/commands/virtual_packages.rs index 1c54e8cc7..5e18b3445 100644 --- a/crates/rattler-bin/src/commands/virtual_packages.rs +++ b/crates/rattler-bin/src/commands/virtual_packages.rs @@ -4,9 +4,7 @@ use rattler_conda_types::GenericVirtualPackage; pub struct Opt {} pub fn virtual_packages(_opt: Opt) -> anyhow::Result<()> { - let virtual_packages = rattler_virtual_packages::VirtualPackage::detect_with_overrides( - &rattler_virtual_packages::VirtualPackageOverrides::default(), - )?; + let virtual_packages = rattler_virtual_packages::VirtualPackage::detect(&Default::default())?; for package in virtual_packages { println!("{}", GenericVirtualPackage::from(package.clone())); } diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 2b814e524..76b2b468c 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -62,7 +62,7 @@ pub enum Override { } /// Traits for overridable virtual packages -/// Use as `Cuda::detect_with_overrides(override)` +/// Use as `Cuda::detect(override)` pub trait EnvOverride: Sized { /// Parse `env_var_value` fn parse_version(value: &str) -> Result; @@ -121,7 +121,7 @@ pub trait EnvOverride: Sized { } /// Shortcut for `Self::detect_with_fallback` with `Self::detect_from_host` as fallback - fn detect_with_overrides(ov: &Override) -> Result, DetectVirtualPackageError> { + fn detect(ov: &Override) -> Result, DetectVirtualPackageError> { Self::detect_with_fallback(ov, Self::detect_from_host) } } @@ -176,13 +176,16 @@ impl From for GenericVirtualPackage { impl VirtualPackage { /// Returns virtual packages detected for the current system or an error if the versions could /// not be properly detected. - #[deprecated(since = "1.0.4", note = "Use `Self::detect` instead")] + #[deprecated( + since = "1.0.4", + note = "Use `Self::detect(&Default::default)` instead" + )] pub fn current() -> Result, DetectVirtualPackageError> { try_detect_virtual_packages_with_overrides(&VirtualPackageOverrides::none()) } /// Detect the virtual packages of the current system with the given overrides. - pub fn detect_with_overrides( + pub fn detect( overrides: &VirtualPackageOverrides, ) -> Result, DetectVirtualPackageError> { try_detect_virtual_packages_with_overrides(overrides) @@ -249,18 +252,18 @@ fn try_detect_virtual_packages_with_overrides( if let Some(linux_version) = Linux::current()? { result.push(linux_version.into()); } - if let Some(libc) = LibC::detect_with_overrides(&overrides.libc)? { + if let Some(libc) = LibC::detect(&overrides.libc)? { result.push(libc.into()); } } if platform.is_osx() { - if let Some(osx) = Osx::detect_with_overrides(&overrides.osx)? { + if let Some(osx) = Osx::detect(&overrides.osx)? { result.push(osx.into()); } } - if let Some(cuda) = Cuda::detect_with_overrides(&overrides.cuda)? { + if let Some(cuda) = Cuda::detect(&overrides.cuda)? { result.push(cuda.into()); } @@ -601,14 +604,14 @@ mod test { let env_var_name = format!("{}_{}", LibC::DEFAULT_ENV_NAME, "12345511231"); env::set_var(env_var_name.clone(), v); assert_eq!( - LibC::detect_with_overrides(&Override::EnvVar(env_var_name.clone())) + LibC::detect(&Override::EnvVar(env_var_name.clone())) .unwrap() .unwrap(), res ); env::set_var(env_var_name.clone(), ""); assert_eq!( - LibC::detect_with_overrides(&Override::EnvVar(env_var_name.clone())).unwrap(), + LibC::detect(&Override::EnvVar(env_var_name.clone())).unwrap(), None ); env::remove_var(env_var_name.clone()); @@ -635,18 +638,18 @@ mod test { let env_var_name = format!("{}_{}", Cuda::DEFAULT_ENV_NAME, "12345511231"); env::set_var(env_var_name.clone(), v); assert_eq!( - Cuda::detect_with_overrides(&Override::EnvVar(env_var_name.clone())) + Cuda::detect(&Override::EnvVar(env_var_name.clone())) .unwrap() .unwrap(), res ); assert_eq!( - Cuda::detect_with_overrides(&Override::None).map_err(|_x| 1), + Cuda::detect(&Override::None).map_err(|_x| 1), ::detect_from_host().map_err(|_x| 1) ); env::remove_var(env_var_name.clone()); assert_eq!( - Cuda::detect_with_overrides(&Override::String(v.to_string())) + Cuda::detect(&Override::String(v.to_string())) .unwrap() .unwrap(), res @@ -662,7 +665,7 @@ mod test { let env_var_name = format!("{}_{}", Osx::DEFAULT_ENV_NAME, "12345511231"); env::set_var(env_var_name.clone(), v); assert_eq!( - Osx::detect_with_overrides(&Override::EnvVar(env_var_name.clone())) + Osx::detect(&Override::EnvVar(env_var_name.clone())) .unwrap() .unwrap(), res diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index 46effaf61..ff80867a5 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -87,7 +87,7 @@ def _from_py_virtual_package_overrides( virtual_package_overrides._overrides = py_virtual_package_overrides return virtual_package_overrides - def __init__(self, osx=None, libc=None, cuda=None) -> None: + def __init__(self, osx: Override | None = None, libc: Override | None = None, cuda: Override | None = None) -> None: """ Returns the default virtual package overrides. """ @@ -99,7 +99,6 @@ def __init__(self, osx=None, libc=None, cuda=None) -> None: if cuda is not None: self.cuda = cuda - @classmethod def none(cls) -> VirtualPackageOverrides: """ @@ -182,17 +181,17 @@ def current() -> List[VirtualPackage]: if the versions could not be properly detected. """ warnings.warn("Use `detect` instead") - return VirtualPackage.detect_with_overrides(VirtualPackageOverrides.none()) + return VirtualPackage.detect(VirtualPackageOverrides.none()) @staticmethod - def detect_with_overrides(overrides: VirtualPackageOverrides | None = None) -> List[VirtualPackage]: + def detect(overrides: VirtualPackageOverrides | None = None) -> List[VirtualPackage]: """ Returns virtual packages detected for the current system with the given overrides. """ _overrides: VirtualPackageOverrides = overrides or VirtualPackageOverrides() return [ VirtualPackage._from_py_virtual_package(vp) - for vp in PyVirtualPackage.detect_with_overrides(_overrides._overrides) + for vp in PyVirtualPackage.detect(_overrides._overrides) ] def into_generic(self) -> GenericVirtualPackage: diff --git a/py-rattler/src/virtual_package.rs b/py-rattler/src/virtual_package.rs index 97d6e5f1e..51975c142 100644 --- a/py-rattler/src/virtual_package.rs +++ b/py-rattler/src/virtual_package.rs @@ -152,21 +152,14 @@ impl PyVirtualPackage { // we just warn directly from python. #[staticmethod] pub fn current() -> PyResult> { - Self::detect_with_overrides(&PyVirtualPackageOverrides::none()) + Self::detect(&PyVirtualPackageOverrides::none()) } #[staticmethod] - pub fn detect() -> PyResult> { - Self::detect_with_overrides(&PyVirtualPackageOverrides::default()) - } - - #[staticmethod] - pub fn detect_with_overrides(overrides: &PyVirtualPackageOverrides) -> PyResult> { - Ok( - VirtualPackage::detect_with_overrides(&overrides.clone().into()) - .map(|vp| vp.iter().map(|v| v.clone().into()).collect::>()) - .map_err(PyRattlerError::from)?, - ) + pub fn detect(overrides: &PyVirtualPackageOverrides) -> PyResult> { + Ok(VirtualPackage::detect(&overrides.clone().into()) + .map(|vp| vp.iter().map(|v| v.clone().into()).collect::>()) + .map_err(PyRattlerError::from)?) } pub fn as_generic(&self) -> PyGenericVirtualPackage { diff --git a/py-rattler/tests/unit/test_override.py b/py-rattler/tests/unit/test_override.py index 5438307fc..731daa295 100644 --- a/py-rattler/tests/unit/test_override.py +++ b/py-rattler/tests/unit/test_override.py @@ -1,5 +1,6 @@ from rattler import VirtualPackage, VirtualPackageOverrides, Override, Version, PackageName + def test_overrides() -> None: overrides = VirtualPackageOverrides.none() print(overrides.osx, Override.none()) @@ -10,19 +11,20 @@ def test_overrides() -> None: assert overrides.osx == Override.default_env_var() assert overrides.libc == Override.default_env_var() assert overrides.cuda == Override.default_env_var() - + overrides.osx = Override.string("123.45") overrides.libc = Override.string("123.457") overrides.cuda = Override.string("123.4578") - r = [i.into_generic() for i in VirtualPackage.detect_with_overrides(overrides)] - def find(name: str, ver: str, must_find: bool=True) -> None: + r = [i.into_generic() for i in VirtualPackage.detect(overrides)] + + def find(name: str, ver: str, must_find: bool = True) -> None: for i in r: if i.name == PackageName(name): assert i.version == Version(ver) return assert not must_find - + find("__cuda", "123.4578") find("__libc", "123.4578", False) - find("__osx", "123.45", False) \ No newline at end of file + find("__osx", "123.45", False) From 157c8132de313d328a7ff20be1ae1a99a3ba65b5 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 15:01:13 -0400 Subject: [PATCH 30/33] fmt --- py-rattler/rattler/virtual_package/virtual_package.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/py-rattler/rattler/virtual_package/virtual_package.py b/py-rattler/rattler/virtual_package/virtual_package.py index ff80867a5..a37da3452 100644 --- a/py-rattler/rattler/virtual_package/virtual_package.py +++ b/py-rattler/rattler/virtual_package/virtual_package.py @@ -189,10 +189,7 @@ def detect(overrides: VirtualPackageOverrides | None = None) -> List[VirtualPack Returns virtual packages detected for the current system with the given overrides. """ _overrides: VirtualPackageOverrides = overrides or VirtualPackageOverrides() - return [ - VirtualPackage._from_py_virtual_package(vp) - for vp in PyVirtualPackage.detect(_overrides._overrides) - ] + return [VirtualPackage._from_py_virtual_package(vp) for vp in PyVirtualPackage.detect(_overrides._overrides)] def into_generic(self) -> GenericVirtualPackage: """ From 1c03db5fb38ccf02e35a73c67ef731afd3a401dd Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 15:05:11 -0400 Subject: [PATCH 31/33] fix test --- crates/rattler_virtual_packages/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 76b2b468c..95ecc083e 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -591,7 +591,7 @@ mod test { #[test] fn doesnt_crash() { - let virtual_packages = VirtualPackage::detect().unwrap(); + let virtual_packages = VirtualPackage::detect(&Default::default()).unwrap(); println!("{virtual_packages:?}"); } #[test] From 9057932c2fb165689328b1983e903e4b7a057d7e Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 16:07:16 -0400 Subject: [PATCH 32/33] change deprecation --- crates/rattler_virtual_packages/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index 95ecc083e..edab19267 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -178,7 +178,7 @@ impl VirtualPackage { /// not be properly detected. #[deprecated( since = "1.0.4", - note = "Use `Self::detect(&Default::default)` instead" + note = "Use `Self::detect(&Default::none)` instead." )] pub fn current() -> Result, DetectVirtualPackageError> { try_detect_virtual_packages_with_overrides(&VirtualPackageOverrides::none()) From 5aa6af868687b74bd8c976af8426f2c462ae99a8 Mon Sep 17 00:00:00 2001 From: Sobhan Mohammadpour Date: Thu, 29 Aug 2024 16:09:42 -0400 Subject: [PATCH 33/33] oops --- crates/rattler_virtual_packages/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rattler_virtual_packages/src/lib.rs b/crates/rattler_virtual_packages/src/lib.rs index edab19267..52349a680 100644 --- a/crates/rattler_virtual_packages/src/lib.rs +++ b/crates/rattler_virtual_packages/src/lib.rs @@ -178,7 +178,7 @@ impl VirtualPackage { /// not be properly detected. #[deprecated( since = "1.0.4", - note = "Use `Self::detect(&Default::none)` instead." + note = "Use `Self::detect(&VirtualPackageOverrides::none())` instead." )] pub fn current() -> Result, DetectVirtualPackageError> { try_detect_virtual_packages_with_overrides(&VirtualPackageOverrides::none())