From 30aa1505c7f3ea1600d616b0c95fe1ca6229b18f Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Fri, 24 Nov 2023 14:46:18 +0100 Subject: [PATCH] fix: wheel tags can contain compound tags (#90) WHEEL files can contain compound tags like: `cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64`. --- .../src/distribution_finder.rs | 4 +- .../rattler_installs_packages/src/tags/mod.rs | 38 +++++++++++++++++++ .../Werkzeug-1.0.1.dist-info/WHEEL | 3 +- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/crates/rattler_installs_packages/src/distribution_finder.rs b/crates/rattler_installs_packages/src/distribution_finder.rs index 24ffe850..ee1ffa1c 100644 --- a/crates/rattler_installs_packages/src/distribution_finder.rs +++ b/crates/rattler_installs_packages/src/distribution_finder.rs @@ -129,14 +129,16 @@ fn analyze_distribution( let tags = if wheel_path.is_file() { let mut parsed = RFC822ish::from_str(&std::fs::read_to_string(&wheel_path)?) .map_err(move |e| FindDistributionError::FailedToParseWheel(wheel_path, e))?; + Some( parsed .take_all("Tag") .into_iter() .map(|tag| { - WheelTag::from_str(&tag) + WheelTag::from_compound_string(&tag) .map_err(|_| FindDistributionError::FailedToParseWheelTag(tag)) }) + .flatten_ok() .collect::, _>>()?, ) } else { diff --git a/crates/rattler_installs_packages/src/tags/mod.rs b/crates/rattler_installs_packages/src/tags/mod.rs index 38c7ddc1..51aa015c 100644 --- a/crates/rattler_installs_packages/src/tags/mod.rs +++ b/crates/rattler_installs_packages/src/tags/mod.rs @@ -23,6 +23,44 @@ pub struct WheelTag { pub platform: String, } +impl WheelTag { + /// Parses a compound string into a `WheelTag`. A compound string is a string that contains + /// multiple tags in a single string. + /// + /// ```rust + /// # use rattler_installs_packages::tags::WheelTag; + /// let tags = WheelTag::from_compound_string( + /// "cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64").unwrap(); + /// + /// assert_eq!(tags.len(), 2); + /// assert_eq!(tags[0].interpreter, "cp310"); + /// assert_eq!(tags[0].abi, "cp310"); + /// assert_eq!(tags[0].platform, "manylinux_2_17_x86_64"); + /// assert_eq!(tags[1].interpreter, "cp310"); + /// assert_eq!(tags[1].abi, "cp310"); + /// assert_eq!(tags[1].platform, "manylinux2014_x86_64"); + /// + /// ``` + pub fn from_compound_string(s: &str) -> Result, String> { + let Some((interpreter, abi, platform)) = + s.split('-').map(ToOwned::to_owned).collect_tuple() + else { + return Err(String::from("not enough '-' separators")); + }; + + Ok(interpreter + .split('.') + .cartesian_product(abi.split('.')) + .cartesian_product(platform.split('.')) + .map(|((interpreter, abi), platform)| Self { + interpreter: interpreter.to_string(), + abi: abi.to_string(), + platform: platform.to_string(), + }) + .collect()) + } +} + impl FromStr for WheelTag { type Err = String; diff --git a/test-data/find_distributions/Lib/site-packages/Werkzeug-1.0.1.dist-info/WHEEL b/test-data/find_distributions/Lib/site-packages/Werkzeug-1.0.1.dist-info/WHEEL index ef99c6cf..475d6eec 100644 --- a/test-data/find_distributions/Lib/site-packages/Werkzeug-1.0.1.dist-info/WHEEL +++ b/test-data/find_distributions/Lib/site-packages/Werkzeug-1.0.1.dist-info/WHEEL @@ -1,6 +1,5 @@ Wheel-Version: 1.0 Generator: bdist_wheel (0.34.2) Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any +Tag: py2.py3-none-any