Skip to content

Commit

Permalink
refactor: use WheelTag in Distribution (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
baszalmstra authored Oct 21, 2023
1 parent 5e7b4f6 commit 99701a9
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
2 changes: 1 addition & 1 deletion crates/rattler_installs_packages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ html-escape = "0.2.13"
http = "0.2.9"
http-cache-semantics = { version = "1.0.1", default-features = false, features = ["with_serde", "reqwest"] }
include_dir = "0.7.3"
indexmap = "2.0.1"
indexmap = { version = "2.0.1", features = ["serde"] }
itertools = "0.11.0"
miette = "5.10.0"
mime = "0.3.17"
Expand Down
19 changes: 17 additions & 2 deletions crates/rattler_installs_packages/src/distribution_finder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
//! The implementation is based on the <https://packaging.python.org/en/latest/specifications/recording-installed-packages>
//! which is based on [PEP 376](https://peps.python.org/pep-0376/) and [PEP 627](https://peps.python.org/pep-0627/).
use crate::tags::WheelTag;
use crate::{rfc822ish::RFC822ish, InstallPaths, NormalizedPackageName, PackageName};
use indexmap::IndexSet;
use itertools::Itertools;
use pep440_rs::Version;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -32,7 +34,7 @@ pub struct Distribution {

/// The specific tags of the distribution that was installed or `None` if this information
/// could not be retrieved.
pub tags: Option<Vec<String>>,
pub tags: Option<IndexSet<WheelTag>>,
}

/// An error that can occur when running `find_distributions_in_venv`.
Expand All @@ -45,6 +47,10 @@ pub enum FindDistributionError {
/// Failed to parse a WHEEL file
#[error("failed to parse '{0}'")]
FailedToParseWheel(PathBuf, #[source] <RFC822ish as FromStr>::Err),

/// Failed to parse WHEEL tags
#[error("failed to parse wheel tag {0}")]
FailedToParseWheelTag(String),
}

/// Locates the python distributions (packages) that have been installed in the virtualenv rooted at
Expand Down Expand Up @@ -123,7 +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"))
Some(
parsed
.take_all("Tag")
.into_iter()
.map(|tag| {
WheelTag::from_str(&tag)
.map_err(|_| FindDistributionError::FailedToParseWheelTag(tag))
})
.collect::<Result<IndexSet<_>, _>>()?,
)
} else {
None
};
Expand Down
35 changes: 34 additions & 1 deletion crates/rattler_installs_packages/src/tags/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
mod from_env;

use indexmap::IndexSet;
use itertools::Itertools;
use serde_with::{DeserializeFromStr, SerializeDisplay};
use std::fmt::{Debug, Display, Formatter};
use std::str::FromStr;

/// A representation of a tag triple for a wheel.
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
#[derive(Debug, Clone, Hash, Eq, PartialEq, SerializeDisplay, DeserializeFromStr)]
pub struct WheelTag {
/// The interpreter name, e.g. "py"
pub interpreter: String,
Expand All @@ -20,6 +23,23 @@ pub struct WheelTag {
pub platform: String,
}

impl FromStr for WheelTag {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let Some((interpreter, abi, platform)) =
s.split('-').map(ToOwned::to_owned).collect_tuple()
else {
return Err(String::from("not enough '-' separators"));
};
Ok(Self {
interpreter,
abi,
platform,
})
}
}

impl Display for WheelTag {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}-{}-{}", &self.interpreter, &self.abi, &self.platform)
Expand Down Expand Up @@ -60,3 +80,16 @@ impl FromIterator<WheelTag> for WheelTags {
}
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_from_str() {
let tag = WheelTag::from_str("py2-none-any").unwrap();
assert_eq!(tag.interpreter, "py2");
assert_eq!(tag.abi, "none");
assert_eq!(tag.platform, "any");
}
}

0 comments on commit 99701a9

Please sign in to comment.