This commit is contained in:
2026-08-24 11:58:19 +02:00
parent 42fcfc2dfa
commit 429429e414
10 changed files with 477 additions and 189 deletions
+369 -75
View File
@@ -99,65 +99,349 @@ struct OsEntry {
// Factual data from dpkg `data/cputable` (columns: debian name, GNU name,
// config.guess regex, bits, endianness).
static CPU_TABLE: &[CpuEntry] = &[
CpuEntry { name: "alpha", gnu: "alpha", guess: "alpha.*", bits: 64, endian: Endian::Little },
CpuEntry { name: "amd64", gnu: "x86_64", guess: "(amd64|x86_64)", bits: 64, endian: Endian::Little },
CpuEntry { name: "arc", gnu: "arc", guess: "arc", bits: 32, endian: Endian::Little },
CpuEntry { name: "armeb", gnu: "armeb", guess: "arm.*b", bits: 32, endian: Endian::Big },
CpuEntry { name: "arm", gnu: "arm", guess: "arm.*", bits: 32, endian: Endian::Little },
CpuEntry { name: "arm64", gnu: "aarch64", guess: "aarch64", bits: 64, endian: Endian::Little },
CpuEntry { name: "hppa", gnu: "hppa", guess: "hppa.*", bits: 32, endian: Endian::Big },
CpuEntry { name: "loong64", gnu: "loongarch64", guess: "loongarch64", bits: 64, endian: Endian::Little },
CpuEntry { name: "i386", gnu: "i686", guess: "(i[34567]86|pentium)", bits: 32, endian: Endian::Little },
CpuEntry { name: "ia64", gnu: "ia64", guess: "ia64", bits: 64, endian: Endian::Little },
CpuEntry { name: "m68k", gnu: "m68k", guess: "m68k", bits: 32, endian: Endian::Big },
CpuEntry { name: "mips", gnu: "mips", guess: "mips(eb)?", bits: 32, endian: Endian::Big },
CpuEntry { name: "mipsel", gnu: "mipsel", guess: "mipsel", bits: 32, endian: Endian::Little },
CpuEntry { name: "mipsr6", gnu: "mipsisa32r6", guess: "mipsisa32r6", bits: 32, endian: Endian::Big },
CpuEntry { name: "mipsr6el", gnu: "mipsisa32r6el", guess: "mipsisa32r6el", bits: 32, endian: Endian::Little },
CpuEntry { name: "mips64", gnu: "mips64", guess: "mips64", bits: 64, endian: Endian::Big },
CpuEntry { name: "mips64el", gnu: "mips64el", guess: "mips64el", bits: 64, endian: Endian::Little },
CpuEntry { name: "mips64r6", gnu: "mipsisa64r6", guess: "mipsisa64r6", bits: 64, endian: Endian::Big },
CpuEntry { name: "mips64r6el", gnu: "mipsisa64r6el", guess: "mipsisa64r6el", bits: 64, endian: Endian::Little },
CpuEntry { name: "nios2", gnu: "nios2", guess: "nios2", bits: 32, endian: Endian::Little },
CpuEntry { name: "or1k", gnu: "or1k", guess: "or1k", bits: 32, endian: Endian::Big },
CpuEntry { name: "powerpc", gnu: "powerpc", guess: "(powerpc|ppc)", bits: 32, endian: Endian::Big },
CpuEntry { name: "powerpcel", gnu: "powerpcle", guess: "powerpcle", bits: 32, endian: Endian::Little },
CpuEntry { name: "ppc64", gnu: "powerpc64", guess: "(powerpc|ppc)64", bits: 64, endian: Endian::Big },
CpuEntry { name: "ppc64el", gnu: "powerpc64le", guess: "powerpc64le", bits: 64, endian: Endian::Little },
CpuEntry { name: "riscv64", gnu: "riscv64", guess: "riscv64", bits: 64, endian: Endian::Little },
CpuEntry { name: "s390", gnu: "s390", guess: "s390", bits: 32, endian: Endian::Big },
CpuEntry { name: "s390x", gnu: "s390x", guess: "s390x", bits: 64, endian: Endian::Big },
CpuEntry { name: "sh3", gnu: "sh3", guess: "sh3", bits: 32, endian: Endian::Little },
CpuEntry { name: "sh3eb", gnu: "sh3eb", guess: "sh3eb", bits: 32, endian: Endian::Big },
CpuEntry { name: "sh4", gnu: "sh4", guess: "sh4", bits: 32, endian: Endian::Little },
CpuEntry { name: "sh4eb", gnu: "sh4eb", guess: "sh4eb", bits: 32, endian: Endian::Big },
CpuEntry { name: "sparc", gnu: "sparc", guess: "sparc", bits: 32, endian: Endian::Big },
CpuEntry { name: "sparc64", gnu: "sparc64", guess: "sparc(64|v9)", bits: 64, endian: Endian::Big },
CpuEntry {
name: "alpha",
gnu: "alpha",
guess: "alpha.*",
bits: 64,
endian: Endian::Little,
},
CpuEntry {
name: "amd64",
gnu: "x86_64",
guess: "(amd64|x86_64)",
bits: 64,
endian: Endian::Little,
},
CpuEntry {
name: "arc",
gnu: "arc",
guess: "arc",
bits: 32,
endian: Endian::Little,
},
CpuEntry {
name: "armeb",
gnu: "armeb",
guess: "arm.*b",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "arm",
gnu: "arm",
guess: "arm.*",
bits: 32,
endian: Endian::Little,
},
CpuEntry {
name: "arm64",
gnu: "aarch64",
guess: "aarch64",
bits: 64,
endian: Endian::Little,
},
CpuEntry {
name: "hppa",
gnu: "hppa",
guess: "hppa.*",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "loong64",
gnu: "loongarch64",
guess: "loongarch64",
bits: 64,
endian: Endian::Little,
},
CpuEntry {
name: "i386",
gnu: "i686",
guess: "(i[34567]86|pentium)",
bits: 32,
endian: Endian::Little,
},
CpuEntry {
name: "ia64",
gnu: "ia64",
guess: "ia64",
bits: 64,
endian: Endian::Little,
},
CpuEntry {
name: "m68k",
gnu: "m68k",
guess: "m68k",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "mips",
gnu: "mips",
guess: "mips(eb)?",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "mipsel",
gnu: "mipsel",
guess: "mipsel",
bits: 32,
endian: Endian::Little,
},
CpuEntry {
name: "mipsr6",
gnu: "mipsisa32r6",
guess: "mipsisa32r6",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "mipsr6el",
gnu: "mipsisa32r6el",
guess: "mipsisa32r6el",
bits: 32,
endian: Endian::Little,
},
CpuEntry {
name: "mips64",
gnu: "mips64",
guess: "mips64",
bits: 64,
endian: Endian::Big,
},
CpuEntry {
name: "mips64el",
gnu: "mips64el",
guess: "mips64el",
bits: 64,
endian: Endian::Little,
},
CpuEntry {
name: "mips64r6",
gnu: "mipsisa64r6",
guess: "mipsisa64r6",
bits: 64,
endian: Endian::Big,
},
CpuEntry {
name: "mips64r6el",
gnu: "mipsisa64r6el",
guess: "mipsisa64r6el",
bits: 64,
endian: Endian::Little,
},
CpuEntry {
name: "nios2",
gnu: "nios2",
guess: "nios2",
bits: 32,
endian: Endian::Little,
},
CpuEntry {
name: "or1k",
gnu: "or1k",
guess: "or1k",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "powerpc",
gnu: "powerpc",
guess: "(powerpc|ppc)",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "powerpcel",
gnu: "powerpcle",
guess: "powerpcle",
bits: 32,
endian: Endian::Little,
},
CpuEntry {
name: "ppc64",
gnu: "powerpc64",
guess: "(powerpc|ppc)64",
bits: 64,
endian: Endian::Big,
},
CpuEntry {
name: "ppc64el",
gnu: "powerpc64le",
guess: "powerpc64le",
bits: 64,
endian: Endian::Little,
},
CpuEntry {
name: "riscv64",
gnu: "riscv64",
guess: "riscv64",
bits: 64,
endian: Endian::Little,
},
CpuEntry {
name: "s390",
gnu: "s390",
guess: "s390",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "s390x",
gnu: "s390x",
guess: "s390x",
bits: 64,
endian: Endian::Big,
},
CpuEntry {
name: "sh3",
gnu: "sh3",
guess: "sh3",
bits: 32,
endian: Endian::Little,
},
CpuEntry {
name: "sh3eb",
gnu: "sh3eb",
guess: "sh3eb",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "sh4",
gnu: "sh4",
guess: "sh4",
bits: 32,
endian: Endian::Little,
},
CpuEntry {
name: "sh4eb",
gnu: "sh4eb",
guess: "sh4eb",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "sparc",
gnu: "sparc",
guess: "sparc",
bits: 32,
endian: Endian::Big,
},
CpuEntry {
name: "sparc64",
gnu: "sparc64",
guess: "sparc(64|v9)",
bits: 64,
endian: Endian::Big,
},
];
// Factual data from dpkg `data/ostable` (columns: debian `abi-libc-os`,
// GNU system name, config.guess regex).
static OS_TABLE: &[OsEntry] = &[
OsEntry { tuple: "eabi-uclibc-linux", gnu: "linux-uclibceabi", guess: "linux[^-]*-uclibceabi" },
OsEntry { tuple: "base-uclibc-linux", gnu: "linux-uclibc", guess: "linux[^-]*-uclibc" },
OsEntry { tuple: "eabihf-musl-linux", gnu: "linux-musleabihf", guess: "linux[^-]*-musleabihf" },
OsEntry { tuple: "base-musl-linux", gnu: "linux-musl", guess: "linux[^-]*-musl" },
OsEntry { tuple: "eabihf-gnu-linux", gnu: "linux-gnueabihf", guess: "linux[^-]*-gnueabihf" },
OsEntry { tuple: "eabi-gnu-linux", gnu: "linux-gnueabi", guess: "linux[^-]*-gnueabi" },
OsEntry { tuple: "abin32-gnu-linux", gnu: "linux-gnuabin32", guess: "linux[^-]*-gnuabin32" },
OsEntry { tuple: "abi64-gnu-linux", gnu: "linux-gnuabi64", guess: "linux[^-]*-gnuabi64" },
OsEntry { tuple: "spe-gnu-linux", gnu: "linux-gnuspe", guess: "linux[^-]*-gnuspe" },
OsEntry { tuple: "x32-gnu-linux", gnu: "linux-gnux32", guess: "linux[^-]*-gnux32" },
OsEntry { tuple: "base-gnu-linux", gnu: "linux-gnu", guess: "linux[^-]*(-gnu.*)?" },
OsEntry { tuple: "base-gnu-hurd", gnu: "gnu", guess: "gnu[^-]*" },
OsEntry { tuple: "base-bsd-darwin", gnu: "darwin", guess: "darwin[^-]*" },
OsEntry { tuple: "base-bsd-dragonflybsd", gnu: "dragonflybsd", guess: "dragonfly[^-]*" },
OsEntry { tuple: "base-bsd-freebsd", gnu: "freebsd", guess: "freebsd[^-]*" },
OsEntry { tuple: "base-bsd-netbsd", gnu: "netbsd", guess: "netbsd[^-]*" },
OsEntry { tuple: "base-bsd-openbsd", gnu: "openbsd", guess: "openbsd[^-]*" },
OsEntry { tuple: "base-sysv-aix", gnu: "aix", guess: "aix[^-]*" },
OsEntry { tuple: "base-sysv-solaris", gnu: "solaris", guess: "solaris[^-]*" },
OsEntry { tuple: "base-tos-mint", gnu: "mint", guess: "mint[^-]*" },
OsEntry {
tuple: "eabi-uclibc-linux",
gnu: "linux-uclibceabi",
guess: "linux[^-]*-uclibceabi",
},
OsEntry {
tuple: "base-uclibc-linux",
gnu: "linux-uclibc",
guess: "linux[^-]*-uclibc",
},
OsEntry {
tuple: "eabihf-musl-linux",
gnu: "linux-musleabihf",
guess: "linux[^-]*-musleabihf",
},
OsEntry {
tuple: "base-musl-linux",
gnu: "linux-musl",
guess: "linux[^-]*-musl",
},
OsEntry {
tuple: "eabihf-gnu-linux",
gnu: "linux-gnueabihf",
guess: "linux[^-]*-gnueabihf",
},
OsEntry {
tuple: "eabi-gnu-linux",
gnu: "linux-gnueabi",
guess: "linux[^-]*-gnueabi",
},
OsEntry {
tuple: "abin32-gnu-linux",
gnu: "linux-gnuabin32",
guess: "linux[^-]*-gnuabin32",
},
OsEntry {
tuple: "abi64-gnu-linux",
gnu: "linux-gnuabi64",
guess: "linux[^-]*-gnuabi64",
},
OsEntry {
tuple: "spe-gnu-linux",
gnu: "linux-gnuspe",
guess: "linux[^-]*-gnuspe",
},
OsEntry {
tuple: "x32-gnu-linux",
gnu: "linux-gnux32",
guess: "linux[^-]*-gnux32",
},
OsEntry {
tuple: "base-gnu-linux",
gnu: "linux-gnu",
guess: "linux[^-]*(-gnu.*)?",
},
OsEntry {
tuple: "base-gnu-hurd",
gnu: "gnu",
guess: "gnu[^-]*",
},
OsEntry {
tuple: "base-bsd-darwin",
gnu: "darwin",
guess: "darwin[^-]*",
},
OsEntry {
tuple: "base-bsd-dragonflybsd",
gnu: "dragonflybsd",
guess: "dragonfly[^-]*",
},
OsEntry {
tuple: "base-bsd-freebsd",
gnu: "freebsd",
guess: "freebsd[^-]*",
},
OsEntry {
tuple: "base-bsd-netbsd",
gnu: "netbsd",
guess: "netbsd[^-]*",
},
OsEntry {
tuple: "base-bsd-openbsd",
gnu: "openbsd",
guess: "openbsd[^-]*",
},
OsEntry {
tuple: "base-sysv-aix",
gnu: "aix",
guess: "aix[^-]*",
},
OsEntry {
tuple: "base-sysv-solaris",
gnu: "solaris",
guess: "solaris[^-]*",
},
OsEntry {
tuple: "base-tos-mint",
gnu: "mint",
guess: "mint[^-]*",
},
];
// Factual data from dpkg `data/tupletable`: bidirectional mapping between a
@@ -347,15 +631,20 @@ pub fn is(real: &str, alias: &str) -> bool {
let (Some(r), Some(a)) = (debarch_to_debtuple(real), wildcard_to_debtuple(alias)) else {
return false;
};
[a.abi.as_str(), a.libc.as_str(), a.os.as_str(), a.cpu.as_str()]
.iter()
.zip([
r.abi.as_str(),
r.libc.as_str(),
r.os.as_str(),
r.cpu.as_str(),
])
.all(|(alias_part, real_part)| *alias_part == "any" || *alias_part == real_part)
[
a.abi.as_str(),
a.libc.as_str(),
a.os.as_str(),
a.cpu.as_str(),
]
.iter()
.zip([
r.abi.as_str(),
r.libc.as_str(),
r.os.as_str(),
r.cpu.as_str(),
])
.all(|(alias_part, real_part)| *alias_part == "any" || *alias_part == real_part)
}
/// Evaluate whether a Debian architecture name is an architecture wildcard.
@@ -557,8 +846,8 @@ pub fn arch_env(host_arch: Option<&str>) -> Result<BTreeMap<String, String>, Str
env.insert(format!("DEB_{role}_ARCH_BITS"), bits.to_string());
env.insert(format!("DEB_{role}_ARCH_ENDIAN"), endian.to_string());
let multi = multiarch(&arch)
.ok_or_else(|| format!("unknown Debian architecture '{arch}'"))?;
let multi =
multiarch(&arch).ok_or_else(|| format!("unknown Debian architecture '{arch}'"))?;
env.insert(format!("DEB_{role}_MULTIARCH"), multi);
let gnu_type = debarch_to_gnutriplet(&arch)
@@ -617,14 +906,8 @@ mod tests {
Some("i686-linux-gnu")
);
assert_eq!(multiarch("i386").as_deref(), Some("i386-linux-gnu"));
assert_eq!(
multiarch("amd64").as_deref(),
Some("x86_64-linux-gnu")
);
assert_eq!(
multiarch("arm64").as_deref(),
Some("aarch64-linux-gnu")
);
assert_eq!(multiarch("amd64").as_deref(), Some("x86_64-linux-gnu"));
assert_eq!(multiarch("arm64").as_deref(), Some("aarch64-linux-gnu"));
}
#[test]
@@ -690,7 +973,15 @@ mod tests {
#[test]
fn known_arches() {
let arches = valid_arches();
for expected in ["amd64", "armhf", "armel", "i386", "riscv64", "x32", "hurd-i386"] {
for expected in [
"amd64",
"armhf",
"armel",
"i386",
"riscv64",
"x32",
"hurd-i386",
] {
assert!(arches.iter().any(|a| a == expected), "missing {expected}");
}
}
@@ -722,7 +1013,10 @@ mod tests {
assert_ne!(env.get("DEB_BUILD_ARCH").unwrap(), "armhf");
assert_eq!(env.get("DEB_HOST_ARCH").unwrap(), "armhf");
assert_eq!(env.get("DEB_HOST_GNU_TYPE").unwrap(), "arm-linux-gnueabihf");
assert_eq!(env.get("DEB_HOST_MULTIARCH").unwrap(), "arm-linux-gnueabihf");
assert_eq!(
env.get("DEB_HOST_MULTIARCH").unwrap(),
"arm-linux-gnueabihf"
);
assert_eq!(env.get("DEB_TARGET_ARCH").unwrap(), "armhf");
}
+4 -6
View File
@@ -68,9 +68,9 @@ pub fn parse_changelog_entry_from_str(
}
};
let open = header.find('(').ok_or_else(|| {
format!("invalid changelog header in '{origin}': {header}")
})?;
let open = header
.find('(')
.ok_or_else(|| format!("invalid changelog header in '{origin}': {header}"))?;
let close = header[open..]
.find(')')
.ok_or_else(|| format!("unbalanced parenthesis in changelog header '{}'", header))?;
@@ -150,9 +150,7 @@ pub fn parse_changelog_entry_from_str(
let date_raw = trailer_body[gt + 1..].trim().to_string();
let timestamp = DateTime::parse_from_rfc2822(&date_raw)
.map_err(|e| {
format!("cannot parse changelog date '{date_raw}' in '{origin}': {e}")
})?
.map_err(|e| format!("cannot parse changelog date '{date_raw}' in '{origin}': {e}"))?
.timestamp();
// Changes field value (leading `\n` marks it as a pre-wrapped multiline
+16 -17
View File
@@ -18,7 +18,7 @@ use regex::Regex;
use crate::debian::arch;
use crate::debian::control::ControlInfo;
use crate::debian::version::{compare as version_cmp, DebianVersion};
use crate::debian::version::{DebianVersion, compare as version_cmp};
/// Version relation operator between a package and a version.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -145,11 +145,11 @@ fn dep_regex() -> &'static Regex {
static REGEX: OnceLock<Regex> = OnceLock::new();
REGEX.get_or_init(|| {
Regex::new(concat!(
r"^(\s*)([a-zA-Z0-9][a-zA-Z0-9+.\-]*)", // package name
r"(?::([a-zA-Z0-9][a-zA-Z0-9\-]*))?", // optional :arch qualifier
r"^(\s*)([a-zA-Z0-9][a-zA-Z0-9+.\-]*)", // package name
r"(?::([a-zA-Z0-9][a-zA-Z0-9\-]*))?", // optional :arch qualifier
r"(\s*\(\s*(<<|<=|=|>=|>>|[<>])\s*([^\)\s]+)\s*\))?", // optional version
r"(\s*\[\s*([^\]]+?)\s*\])?", // optional [arch list]
r"((?:\s*<\s*[^>]+?\s*>)+)?(\s*)$", // optional <restrictions>
r"(\s*\[\s*([^\]]+?)\s*\])?", // optional [arch list]
r"((?:\s*<\s*[^>]+?\s*>)+)?(\s*)$", // optional <restrictions>
))
.expect("valid dependency regex")
})
@@ -291,11 +291,7 @@ impl Deps {
Self::parse_inner(input, opts, false)
}
fn parse_inner(
input: &str,
opts: &ParseOpts,
reduce_arch_only: bool,
) -> Result<Deps, String> {
fn parse_inner(input: &str, opts: &ParseOpts, reduce_arch_only: bool) -> Result<Deps, String> {
if opts.host_arch.is_empty() || arch::is_invalid(&opts.host_arch, true) {
return Err(format!("invalid host_arch {}", opts.host_arch));
}
@@ -336,9 +332,7 @@ impl Deps {
continue;
}
if opts.union && alternatives.len() > 1 {
return Err(
"an union dependency can only contain simple dependencies".to_string(),
);
return Err("an union dependency can only contain simple dependencies".to_string());
}
clauses.push(alternatives);
}
@@ -369,8 +363,7 @@ impl Deps {
self.clauses
.iter()
.map(|alts| {
alts
.iter()
alts.iter()
.map(PkgRelation::output)
.collect::<Vec<_>>()
.join(" | ")
@@ -1145,7 +1138,10 @@ Provides: old-virtual (= 0.5)
// Real packages.
assert_eq!(facts.evaluate_relation(&o("mypackage")), Some(true));
assert_eq!(facts.evaluate_relation(&o("mypackage (>= 1.3)")), Some(true));
assert_eq!(
facts.evaluate_relation(&o("mypackage (>= 1.3)")),
Some(true)
);
assert_eq!(
facts.evaluate_relation(&o("mypackage (>> 1.3.4-1)")),
Some(false)
@@ -1157,7 +1153,10 @@ Provides: old-virtual (= 0.5)
facts.evaluate_relation(&o("pkg-ma-foreign:somearch")),
Some(true)
);
assert_eq!(facts.evaluate_relation(&o("pkg-ma-allowed:any")), Some(true));
assert_eq!(
facts.evaluate_relation(&o("pkg-ma-allowed:any")),
Some(true)
);
assert_eq!(facts.evaluate_relation(&o("pkg-ma-allowed")), Some(false));
assert_eq!(facts.evaluate_relation(&o("pkg-ma-foreign2")), Some(true));
+1 -2
View File
@@ -121,8 +121,7 @@ impl FilesList {
return Err(format!("cannot read '{}': {}", path.display(), e).into());
}
};
FilesList::parse(&content)
.map_err(|e| format!("in '{}': {}", path.display(), e).into())
FilesList::parse(&content).map_err(|e| format!("in '{}': {}", path.display(), e).into())
}
/// Parse a `debian/files` registry from its textual content
+13 -8
View File
@@ -102,7 +102,8 @@ impl DebianVersion {
/// - digit chunks compare numerically (leading zeroes are irrelevant; an
/// empty digit chunk counts as `0`, so a missing revision equals `0`).
pub fn compare(a: &DebianVersion, b: &DebianVersion) -> std::cmp::Ordering {
a.epoch.unwrap_or(0)
a.epoch
.unwrap_or(0)
.cmp(&b.epoch.unwrap_or(0))
.then_with(|| verrevcmp(a.upstream.as_bytes(), b.upstream.as_bytes()))
.then_with(|| {
@@ -137,8 +138,7 @@ fn verrevcmp(mut a: &[u8], mut b: &[u8]) -> std::cmp::Ordering {
// Non-digit chunks: compare by character weight. A chunk boundary
// (end of string or start of a digit run) weighs 0, which sorts
// after `~` (-1) and before every real character.
while (!a.is_empty() && !a[0].is_ascii_digit())
|| (!b.is_empty() && !b[0].is_ascii_digit())
while (!a.is_empty() && !a[0].is_ascii_digit()) || (!b.is_empty() && !b[0].is_ascii_digit())
{
let ac = if !a.is_empty() && !a[0].is_ascii_digit() {
char_order(a[0])
@@ -276,7 +276,14 @@ pub(crate) mod test_vectors {
],
),
(
&["4", "5.0abc", "0.0alpha0", "10.100.1", "0~999.999zeta", "1.0"],
&[
"4",
"5.0abc",
"0.0alpha0",
"10.100.1",
"0~999.999zeta",
"1.0",
],
&[
"0~999.999zeta",
"0.0alpha0",
@@ -334,10 +341,8 @@ mod tests {
#[test]
fn comparison_dpkg_vectors() {
for (a, b, expected) in test_vectors::COMPARE {
let va =
DebianVersion::parse(a).unwrap_or_else(|e| panic!("parse {a}: {e}"));
let vb =
DebianVersion::parse(b).unwrap_or_else(|e| panic!("parse {b}: {e}"));
let va = DebianVersion::parse(a).unwrap_or_else(|e| panic!("parse {a}: {e}"));
let vb = DebianVersion::parse(b).unwrap_or_else(|e| panic!("parse {b}: {e}"));
assert_eq!(
cmp_sign(&va, &vb),
*expected,