From 7e78b4bcef158a1ff7b26a130e8e10acb154608d Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Mon, 23 Sep 2024 09:21:13 +0200 Subject: [PATCH] feat: add path to namedchannelorurl (#873) --- crates/rattler_conda_types/src/channel/mod.rs | 37 +++++++--- py-rattler/Cargo.lock | 72 +++++++++++++------ 2 files changed, 79 insertions(+), 30 deletions(-) diff --git a/crates/rattler_conda_types/src/channel/mod.rs b/crates/rattler_conda_types/src/channel/mod.rs index 221933e43..b9050ec04 100644 --- a/crates/rattler_conda_types/src/channel/mod.rs +++ b/crates/rattler_conda_types/src/channel/mod.rs @@ -85,6 +85,9 @@ pub enum NamedChannelOrUrl { /// A url Url(Url), + + /// A path. Can either be absolute or relative. + Path(Utf8TypedPathBuf), } impl NamedChannelOrUrl { @@ -96,12 +99,13 @@ impl NamedChannelOrUrl { match self { NamedChannelOrUrl::Name(name) => name, NamedChannelOrUrl::Url(url) => url.as_str().trim_end_matches('/'), + NamedChannelOrUrl::Path(path) => path.as_str(), } } /// Converts the channel to a base url using the given configuration. /// This method ensures that the base url always ends with a `/`. - pub fn into_base_url(self, config: &ChannelConfig) -> Url { + pub fn into_base_url(self, config: &ChannelConfig) -> Result { let url = match self { NamedChannelOrUrl::Name(name) => { let mut base_url = config.channel_alias.clone(); @@ -113,21 +117,27 @@ impl NamedChannelOrUrl { base_url } NamedChannelOrUrl::Url(url) => url, + NamedChannelOrUrl::Path(path) => { + let absolute_path = absolute_path(path.as_str(), &config.root_dir)?; + directory_path_to_url(absolute_path.to_path()) + .map_err(|_err| ParseChannelError::InvalidPath(path.to_string()))? + } }; - add_trailing_slash(&url).into_owned() + Ok(add_trailing_slash(&url).into_owned()) } /// Converts this instance into a channel. - pub fn into_channel(self, config: &ChannelConfig) -> Channel { + pub fn into_channel(self, config: &ChannelConfig) -> Result { let name = match &self { NamedChannelOrUrl::Name(name) => Some(name.clone()), NamedChannelOrUrl::Url(base_url) => config.strip_channel_alias(base_url), + NamedChannelOrUrl::Path(_) => None, }; - let base_url = self.into_base_url(config); - Channel { + let base_url = self.into_base_url(config)?; + Ok(Channel { name, ..Channel::from_url(base_url) - } + }) } } @@ -143,6 +153,8 @@ impl FromStr for NamedChannelOrUrl { fn from_str(s: &str) -> Result { if parse_scheme(s).is_some() { Ok(NamedChannelOrUrl::Url(Url::from_str(s)?)) + } else if is_path(s) { + Ok(NamedChannelOrUrl::Path(s.into())) } else { Ok(NamedChannelOrUrl::Name(s.to_string())) } @@ -767,6 +779,8 @@ mod tests { "conda-forge/", "https://conda.anaconda.org/conda-forge", "https://conda.anaconda.org/conda-forge/", + "../conda-forge/", + "../conda-forge", ]; for channel_str in test_channels { @@ -775,12 +789,15 @@ mod tests { assert!(!channel.base_url().as_str().ends_with("//")); let named_channel = NamedChannelOrUrl::from_str(channel_str).unwrap(); - let base_url = named_channel.clone().into_base_url(&channel_config); + let base_url = named_channel + .clone() + .into_base_url(&channel_config) + .unwrap(); let base_url_str = base_url.as_str(); assert!(base_url_str.ends_with('/')); assert!(!base_url_str.ends_with("//")); - let channel = named_channel.into_channel(&channel_config); + let channel = named_channel.into_channel(&channel_config).unwrap(); assert!(channel.base_url().as_str().ends_with('/')); assert!(!channel.base_url().as_str().ends_with("//")); } @@ -796,14 +813,14 @@ mod tests { let channel = Channel::from_str("conda-forge", &channel_config).unwrap(); assert_eq!( &channel.base_url, - named.into_channel(&channel_config).base_url() + named.into_channel(&channel_config).unwrap().base_url() ); let named = NamedChannelOrUrl::Name("nvidia/label/cuda-11.8.0".to_string()); let channel = Channel::from_str("nvidia/label/cuda-11.8.0", &channel_config).unwrap(); assert_eq!( channel.base_url(), - named.into_channel(&channel_config).base_url() + named.into_channel(&channel_config).unwrap().base_url() ); } } diff --git a/py-rattler/Cargo.lock b/py-rattler/Cargo.lock index bfa564535..2245f24eb 100644 --- a/py-rattler/Cargo.lock +++ b/py-rattler/Cargo.lock @@ -159,6 +159,21 @@ dependencies = [ "slab", ] +[[package]] +name = "async-fd-lock" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7569377d7062165f6f7834d9cb3051974a2d141433cc201c2f94c149e993cccf" +dependencies = [ + "async-trait", + "cfg-if", + "pin-project", + "rustix", + "thiserror", + "tokio", + "windows-sys 0.52.0", +] + [[package]] name = "async-fs" version = "2.1.2" @@ -832,7 +847,7 @@ checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "file_url" -version = "0.1.4" +version = "0.1.5" dependencies = [ "itertools 0.13.0", "percent-encoding", @@ -924,6 +939,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" dependencies = [ "autocfg", + "tokio", +] + +[[package]] +name = "fs4" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c6b3bd49c37d2aa3f3f2220233b29a7cd23f79d1fe70e5337d25fb390793de" +dependencies = [ + "fs-err", + "rustix", + "windows-sys 0.52.0", ] [[package]] @@ -1799,7 +1826,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -2619,7 +2646,7 @@ dependencies = [ [[package]] name = "rattler" -version = "0.27.6" +version = "0.27.11" dependencies = [ "anyhow", "console", @@ -2657,11 +2684,14 @@ dependencies = [ [[package]] name = "rattler_cache" -version = "0.1.8" +version = "0.2.3" dependencies = [ "anyhow", + "dashmap", "digest", "dirs", + "fs4", + "futures", "fxhash", "itertools 0.13.0", "parking_lot", @@ -2671,6 +2701,7 @@ dependencies = [ "rattler_package_streaming", "reqwest 0.12.4", "reqwest-middleware", + "simple_spawn_blocking", "thiserror", "tokio", "tracing", @@ -2679,7 +2710,7 @@ dependencies = [ [[package]] name = "rattler_conda_types" -version = "0.27.2" +version = "0.27.6" dependencies = [ "chrono", "dirs", @@ -2713,7 +2744,7 @@ dependencies = [ [[package]] name = "rattler_digest" -version = "1.0.1" +version = "1.0.2" dependencies = [ "blake2", "digest", @@ -2728,7 +2759,7 @@ dependencies = [ [[package]] name = "rattler_index" -version = "0.19.24" +version = "0.19.28" dependencies = [ "fs-err", "rattler_conda_types", @@ -2741,7 +2772,7 @@ dependencies = [ [[package]] name = "rattler_lock" -version = "0.22.20" +version = "0.22.24" dependencies = [ "chrono", "file_url", @@ -2762,7 +2793,7 @@ dependencies = [ [[package]] name = "rattler_macros" -version = "1.0.1" +version = "1.0.2" dependencies = [ "quote", "syn 2.0.66", @@ -2770,7 +2801,7 @@ dependencies = [ [[package]] name = "rattler_networking" -version = "0.21.2" +version = "0.21.4" dependencies = [ "anyhow", "async-trait", @@ -2796,7 +2827,7 @@ dependencies = [ [[package]] name = "rattler_package_streaming" -version = "0.22.3" +version = "0.22.7" dependencies = [ "bzip2", "chrono", @@ -2822,7 +2853,7 @@ dependencies = [ [[package]] name = "rattler_redaction" -version = "0.1.1" +version = "0.1.2" dependencies = [ "reqwest 0.12.4", "reqwest-middleware", @@ -2831,10 +2862,11 @@ dependencies = [ [[package]] name = "rattler_repodata_gateway" -version = "0.21.8" +version = "0.21.13" dependencies = [ "anyhow", "async-compression", + "async-fd-lock", "async-trait", "blake2", "bytes", @@ -2882,7 +2914,7 @@ dependencies = [ [[package]] name = "rattler_shell" -version = "0.21.6" +version = "0.22.1" dependencies = [ "enum_dispatch", "indexmap 2.2.6", @@ -2897,7 +2929,7 @@ dependencies = [ [[package]] name = "rattler_solve" -version = "1.0.3" +version = "1.0.7" dependencies = [ "chrono", "futures", @@ -2913,7 +2945,7 @@ dependencies = [ [[package]] name = "rattler_virtual_packages" -version = "1.0.4" +version = "1.1.4" dependencies = [ "archspec", "libloading", @@ -3125,9 +3157,9 @@ dependencies = [ [[package]] name = "resolvo" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "014783b06e2d02bee01fe3c3247454fb34d0fc35765334e825034cdadec422fa" +checksum = "1a472ebbac5a18c9e235e874df3aa0c8fb0b55611155dd5e5515a55a16520d76" dependencies = [ "ahash", "bitvec", @@ -3980,9 +4012,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typed-path" -version = "0.9.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3023f4683cd1a846dbd2666e8c34f54338ee5cebae578cda981a87cecd7aa" +checksum = "50c0c7479c430935701ff2532e3091e6680ec03f2f89ffcd9988b08e885b90a5" [[package]] name = "typeid"