Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 55 additions & 57 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ git2 = "0.20.4"
nestify = "0.3.3"
gql_client = { git = "https://github.com/CodSpeedHQ/gql-client-rs" }
serde_yaml = "0.9.34"
sysinfo = { version = "0.33.1", features = ["serde"] }
sysinfo = { version = "0.38.4", features = ["serde"] }
indicatif = "0.17.8"
console = "0.15.8"
async-trait = "0.1.82"
Expand Down
5 changes: 2 additions & 3 deletions src/system/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,8 @@ impl SystemInfo {
.with_cpu(CpuRefreshKind::everything())
.with_memory(MemoryRefreshKind::everything()),
);
let cpu_cores = s
.physical_core_count()
.ok_or(anyhow!("Failed to get CPU core count"))?;
let cpu_cores =
System::physical_core_count().ok_or(anyhow!("Failed to get CPU core count"))?;
let total_memory_gb = s.total_memory().div_ceil(1024_u64.pow(3));

// take the first CPU to get the brand, name and vendor id
Expand Down
60 changes: 59 additions & 1 deletion src/system/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ impl SupportedOs {
match os {
"linux" => {
let os_id = System::distribution_id();
Ok(Self::Linux(LinuxDistribution::from_id(&os_id, &os_version)))
let os_id_like = System::distribution_id_like();
Ok(Self::Linux(LinuxDistribution::from_id_like(
&os_id,
&os_id_like,
&os_version,
)))
}
"macos" => Ok(Self::Macos {
version: os_version,
Expand Down Expand Up @@ -99,6 +104,21 @@ impl LinuxDistribution {
}
}

/// Build a [`LinuxDistribution`] from the `sysinfo`-reported `os_id` and `os_id_like` fields.
/// This is needed to handle cases like PopOS (`os_id` = "pop" and `os_id_like` = ["ubuntu"]).
fn from_id_like(os_id: &str, os_id_like: &[String], version: &str) -> Self {
let by_id = Self::from_id(os_id, version);
if matches!(by_id, Self::Other { .. }) {
for like_id in os_id_like {
let by_like_id = Self::from_id(like_id, version);
if !matches!(by_like_id, Self::Other { .. }) {
return by_like_id;
}
}
}
by_id
}

/// The distro id as it appears on the wire (matches `sysinfo::System::distribution_id()`).
pub fn id(&self) -> &str {
match self {
Expand Down Expand Up @@ -137,4 +157,42 @@ mod tests {
let err = SupportedOs::from_os("windows").unwrap_err();
assert_eq!(err.to_string(), "Unsupported operating system: windows");
}

#[test]
fn pop_os_resolves_to_ubuntu_via_id_like() {
// Pop!_OS: ID=pop, ID_LIKE="ubuntu debian"
let distro = LinuxDistribution::from_id_like(
"pop",
&[String::from("ubuntu"), String::from("debian")],
"24.04",
);
assert!(
matches!(distro, LinuxDistribution::Ubuntu { .. }),
"got {distro}"
);
}

#[test]
fn ubuntu_resolves_directly_without_id_like() {
// Ubuntu laptop: ID=ubuntu, ID_LIKE="debian" — primary id wins, no fallback needed
let distro = LinuxDistribution::from_id_like("ubuntu", &[String::from("debian")], "24.04");
assert!(
matches!(distro, LinuxDistribution::Ubuntu { .. }),
"got {distro}"
);
}

#[test]
fn centos_with_unrecognized_parents_is_other() {
// CentOS server: ID=centos, ID_LIKE="rhel fedora" — neither parent is known
let distro = LinuxDistribution::from_id_like(
"centos",
&[String::from("rhel"), String::from("fedora")],
"9",
);
assert!(
matches!(&distro, LinuxDistribution::Other { name, .. } if name == "centos"),
"got {distro}"
);
}
}