support portage build-id extension

This commit is contained in:
John Turner
2025-11-18 03:21:44 +00:00
parent e2cc948803
commit 2dc5df6112
2 changed files with 32 additions and 4 deletions

View File

@@ -64,6 +64,7 @@ pub struct Version {
letter: Option<char>, letter: Option<char>,
suffixes: VersionSuffixes, suffixes: VersionSuffixes,
rev: Option<VersionNumber>, rev: Option<VersionNumber>,
build_id: Option<VersionNumber>,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -374,6 +375,13 @@ impl PartialEq for Version {
(Some(_), None) | (None, Some(_)) => false, (Some(_), None) | (None, Some(_)) => false,
(None, None) => true, (None, None) => true,
} }
&& match (&self.build_id, &other.build_id) {
(Some(a), Some(b)) => {
a.get().parse::<u64>().unwrap() == b.get().parse::<u64>().unwrap()
}
(Some(_), None) | (None, Some(_)) => false,
(None, None) => true,
}
} }
} }
@@ -410,14 +418,30 @@ impl Ord for Version {
} }
match (&self.rev, &other.rev) { match (&self.rev, &other.rev) {
(Some(a), Some(b)) => match a
.get()
.parse::<u64>()
.unwrap()
.cmp(&b.get().parse().unwrap())
{
Ordering::Less => return Ordering::Less,
Ordering::Greater => return Ordering::Greater,
Ordering::Equal => (),
},
(Some(a), None) if a.get().chars().all(|c| c == '0') => (),
(Some(_), None) => return Ordering::Greater,
(None, Some(b)) if b.get().chars().all(|c| c == '0') => (),
(None, Some(_)) => return Ordering::Less,
(None, None) => (),
}
match (&self.build_id, &other.build_id) {
(Some(a), Some(b)) => a (Some(a), Some(b)) => a
.get() .get()
.parse::<u64>() .parse::<u64>()
.unwrap() .unwrap()
.cmp(&b.get().parse().unwrap()), .cmp(&b.get().parse::<u64>().unwrap()),
(Some(a), None) if a.get().chars().all(|c| c == '0') => Ordering::Equal,
(Some(_), None) => Ordering::Greater, (Some(_), None) => Ordering::Greater,
(None, Some(b)) if b.get().chars().all(|c| c == '0') => Ordering::Equal,
(None, Some(_)) => Ordering::Less, (None, Some(_)) => Ordering::Less,
(None, None) => Ordering::Equal, (None, None) => Ordering::Equal,
} }
@@ -759,6 +783,7 @@ mod test {
("1.0.0_alpha", "1.0.0_alpha_p", Ordering::Less), ("1.0.0_alpha", "1.0.0_alpha_p", Ordering::Less),
("1.0.0-r0", "1.0.0", Ordering::Equal), ("1.0.0-r0", "1.0.0", Ordering::Equal),
("1.0.0-r0000", "1.0.0", Ordering::Equal), ("1.0.0-r0000", "1.0.0", Ordering::Equal),
("1.0.0-r1-1", "1.0.0-r1-2", Ordering::Less),
]; ];
for (a, b, ordering) in versions.iter().map(|(a, b, ordering)| { for (a, b, ordering) in versions.iter().map(|(a, b, ordering)| {

View File

@@ -94,16 +94,19 @@ impl<'a> Parseable<'a, &'a str> for Version {
fn parser() -> Self::Parser { fn parser() -> Self::Parser {
let rev = VersionNumber::parser().preceded_by(tag("-r")); let rev = VersionNumber::parser().preceded_by(tag("-r"));
let build_id = VersionNumber::parser().preceded_by(tag("-"));
VersionNumbers::parser() VersionNumbers::parser()
.and(r#if(|c: &char| c.is_ascii_alphabetic() && c.is_ascii_lowercase()).opt()) .and(r#if(|c: &char| c.is_ascii_alphabetic() && c.is_ascii_lowercase()).opt())
.and(VersionSuffixes::parser().preceded_by(tag("_")).opt()) .and(VersionSuffixes::parser().preceded_by(tag("_")).opt())
.and(rev.opt()) .and(rev.opt())
.map(|(((numbers, letter), suffixes), rev)| Version { .and(build_id.opt())
.map(|((((numbers, letter), suffixes), rev), build_id)| Version {
numbers, numbers,
letter, letter,
suffixes: suffixes.unwrap_or(VersionSuffixes(Vec::new())), suffixes: suffixes.unwrap_or(VersionSuffixes(Vec::new())),
rev, rev,
build_id,
}) })
} }
} }