From 0f26df5c0212c6d29492f89ea962f8d25f6968d5 Mon Sep 17 00:00:00 2001 From: Wanjohi Date: Wed, 2 Sep 2026 16:25:09 +0300 Subject: [PATCH] fix(nesdoctor): every Mac reported gpu=unknown, because the probe had no macOS arm Seen in the macOS CI log: nesdoctor 0.2.2 | macos/aarch64 | gpu=unknown | ... `gpus()` had a Linux arm, a Windows arm, and `Vec::new()` for everything else. Macs are clients rather than hosts, so it went unnoticed -- but 0041 wants a client vendor matrix and an unlabelled row is no use in one. An M-series integrated GPU and a discrete Radeon in an Intel Mac decode very differently, and "unknown" cannot tell them apart. `system_profiler SPDisplaysDataType` is the only place the chipset name lives. Parsed loosely: the format has changed between macOS releases, so a name we cannot find costs a field rather than the run. Vendor is matched over Apple, AMD, Radeon, NVIDIA and Intel; `render_node` stays `None` because macOS has none and a Mac cannot host regardless. Still missing on macOS and stated rather than papered over: filesystem types and the display probe. The EDID path is sysfs on Linux and WMI on Windows, and macOS exposes neither -- so Mac respondents report no colour depth or HDR capability. That is a real gap for the video work, since Mac panels are exactly the P3 and high-refresh cases worth knowing about, and it needs `CoreDisplay`/`system_profiler` parsing rather than a one-line fix. --- apps/nesdoctor/src/sys.rs | 45 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/apps/nesdoctor/src/sys.rs b/apps/nesdoctor/src/sys.rs index 2b3ea8fa..c87800aa 100644 --- a/apps/nesdoctor/src/sys.rs +++ b/apps/nesdoctor/src/sys.rs @@ -252,7 +252,50 @@ fn gpus() -> Vec { out.sort_by_key(|g| (is_virtual_adapter(&g.name), g.vendor.is_none())); return out; } - #[cfg(not(any(target_os = "linux", windows)))] + #[cfg(target_os = "macos")] + { + // Every Mac reported `gpu=unknown`, because this arm did not exist -- + // seen in the macOS CI log. Macs are clients rather than hosts, but + // 0041 wants a client vendor matrix and an unlabelled entry is no use + // in one: an M-series integrated GPU and a discrete Radeon in an Intel + // Mac decode very differently. + // + // `SPDisplaysDataType` is the only place the chipset name lives. + // Parsed loosely on purpose: the format has changed between macOS + // releases and a missing name should cost a field. + let out = sh("system_profiler", &["SPDisplaysDataType"]).unwrap_or_default(); + let mut gpus = Vec::new(); + for line in out.lines() { + let l = line.trim(); + if let Some(name) = l + .strip_prefix("Chipset Model:") + .or_else(|| l.strip_prefix("Chipset:")) + { + let name = name.trim(); + if name.is_empty() { + continue; + } + let up = name.to_uppercase(); + gpus.push(Gpu { + name: name.to_string(), + vendor: [ + ("APPLE", "Apple"), + ("AMD", "AMD"), + ("RADEON", "AMD"), + ("NVIDIA", "NVIDIA"), + ("INTEL", "Intel"), + ] + .into_iter() + .find(|(needle, _)| up.contains(needle)) + .map(|(_, v)| v.to_string()), + // macOS has no DRM render nodes; a Mac cannot host anyway. + render_node: None, + }); + } + } + return gpus; + } + #[cfg(not(any(target_os = "linux", windows, target_os = "macos")))] return Vec::new(); }