feat(m1): distro detection from /etc/os-release, update_notification_level command

This commit is contained in:
pyr0ball 2026-05-18 15:53:03 -07:00
parent cee05b5d18
commit dc45c82aba
3 changed files with 99 additions and 2 deletions

View file

@ -1,4 +1,4 @@
use crate::config::{RobinConfig, MigrationConfig, SourceOs};
use crate::config::{NotificationLevel, RobinConfig, MigrationConfig, SourceOs};
use tauri::State;
use std::sync::Mutex;
@ -33,11 +33,33 @@ pub fn complete_onboarding(
_ => SourceOs::Unknown,
};
let detected = if distro == "unknown" || distro.is_empty() {
crate::distro::detect()
} else {
distro
};
let mut config = state.config.lock().map_err(|e| e.to_string())?;
config.migration = Some(MigrationConfig {
source_os: source,
distro,
distro: detected,
fluency_level: 0,
});
config.save().map_err(|e| e.to_string())
}
#[tauri::command]
pub fn update_notification_level(
level: String,
state: State<'_, AppState>,
) -> Result<(), String> {
let parsed = match level.as_str() {
"off" => NotificationLevel::Off,
"badge_only" => NotificationLevel::BadgeOnly,
"badge_and_toast" => NotificationLevel::BadgeAndToast,
_ => return Err(format!("unknown notification level: {level}")),
};
let mut config = state.config.lock().map_err(|e| e.to_string())?;
config.display.notification_level = parsed;
config.save().map_err(|e| e.to_string())
}

73
src-tauri/src/distro.rs Normal file
View file

@ -0,0 +1,73 @@
pub fn detect() -> String {
std::fs::read_to_string("/etc/os-release")
.map(|s| parse_id(&s))
.unwrap_or_else(|_| "unknown".to_string())
}
pub fn distro_family(id: &str) -> &'static str {
match id {
"arch" | "cachyos" | "endeavouros" | "manjaro" | "garuda" => "arch",
"debian" | "ubuntu" | "linuxmint" | "pop" | "elementary" | "kali" => {
"debian"
}
"fedora" | "rhel" | "centos" | "rocky" | "alma" => "fedora",
"opensuse" | "opensuse-tumbleweed" | "opensuse-leap" => "opensuse",
_ => "unknown",
}
}
fn parse_id(content: &str) -> String {
content
.lines()
.find_map(|line| {
let (key, val) = line.split_once('=')?;
if key.trim() == "ID" {
Some(val.trim().trim_matches('"').to_lowercase())
} else {
None
}
})
.unwrap_or_else(|| "unknown".to_string())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_arch_id() {
let content = "ID=arch\nID_LIKE=\nPRETTY_NAME=Arch Linux\n";
assert_eq!(parse_id(content), "arch");
}
#[test]
fn parses_cachyos_id() {
let content = "ID=cachyos\nID_LIKE=arch\nPRETTY_NAME=CachyOS\n";
assert_eq!(parse_id(content), "cachyos");
}
#[test]
fn parses_linuxmint_id() {
let content = "ID=linuxmint\nID_LIKE=ubuntu\nPRETTY_NAME=Linux Mint 22\n";
assert_eq!(parse_id(content), "linuxmint");
}
#[test]
fn distro_family_arch_based() {
assert_eq!(distro_family("cachyos"), "arch");
assert_eq!(distro_family("arch"), "arch");
assert_eq!(distro_family("manjaro"), "arch");
}
#[test]
fn distro_family_debian_based() {
assert_eq!(distro_family("linuxmint"), "debian");
assert_eq!(distro_family("ubuntu"), "debian");
assert_eq!(distro_family("debian"), "debian");
}
#[test]
fn distro_family_unknown() {
assert_eq!(distro_family("slackware"), "unknown");
}
}

View file

@ -1,5 +1,6 @@
mod commands;
mod config;
mod distro;
mod tray;
mod watcher;
@ -29,6 +30,7 @@ pub fn run() {
commands::get_config,
commands::needs_onboarding,
commands::complete_onboarding,
commands::update_notification_level,
])
.run(tauri::generate_context!())
.expect("error while running Robin");