refactor: apply CLAUDE.md code quality improvements and add packaging
- Add #![forbid(unsafe_code)] to main.rs (issue #3) - Replace raw ANSI escape codes with owo-colors crate (issue #2) - Replace manual HOME path construction with dirs::home_dir() (issue #5) - Ship umutray.service as a static file; service::install() substitutes the binary path at install time instead of generating the unit at runtime - Add packaging/PKGBUILD following Arch Rust package guidelines - Add CLAUDE.md tracking refactor tasks - setup.rs: clean up downloaded temp files on abort/back, save launcher to config only after successful install, auto-start download when a preset has an installer_url - util.rs: add pick_folder() using zenity/kdialog subprocesses (no rfd) - config.rs: populate installer_url for all 6 built-in presets with official download URLs - Document the Option<Option<Vec<String>>> gamescope pattern at main.rs:307 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+27
-16
@@ -1,5 +1,6 @@
|
||||
use anyhow::{Context, Result};
|
||||
use directories::ProjectDirs;
|
||||
use owo_colors::OwoColorize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
|
||||
@@ -86,9 +87,7 @@ pub struct Config {
|
||||
}
|
||||
|
||||
fn home_dir() -> PathBuf {
|
||||
std::env::var("HOME")
|
||||
.map(PathBuf::from)
|
||||
.expect("$HOME is not set; cannot determine default paths")
|
||||
dirs::home_dir().expect("Cannot determine home directory")
|
||||
}
|
||||
|
||||
fn default_compat_dir() -> PathBuf {
|
||||
@@ -128,7 +127,9 @@ pub fn presets() -> Vec<Launcher> {
|
||||
),
|
||||
gameid: "umu-battlenet".into(),
|
||||
process_pattern: r"Battle\.net".into(),
|
||||
installer_url: None,
|
||||
installer_url: Some(
|
||||
"https://www.battle.net/download/getInstallerForGame?os=win&gameProgram=BATTLENET_APP&version=Live".into(),
|
||||
),
|
||||
proton_version: None,
|
||||
games: vec![],
|
||||
},
|
||||
@@ -141,7 +142,9 @@ pub fn presets() -> Vec<Launcher> {
|
||||
),
|
||||
gameid: "umu-eaapp".into(),
|
||||
process_pattern: r"EADesktop\.exe".into(),
|
||||
installer_url: None,
|
||||
installer_url: Some(
|
||||
"https://origin-a.akamaihd.net/EA-Desktop-Client-Download/installer-releases/EAappInstaller.exe".into(),
|
||||
),
|
||||
proton_version: None,
|
||||
games: vec![],
|
||||
},
|
||||
@@ -154,7 +157,9 @@ pub fn presets() -> Vec<Launcher> {
|
||||
),
|
||||
gameid: "umu-epicgameslauncher".into(),
|
||||
process_pattern: r"EpicGamesLauncher\.exe".into(),
|
||||
installer_url: None,
|
||||
installer_url: Some(
|
||||
"https://launcher-public-service-prod06.ol.epicgames.com/launcher/api/installer/download/EpicGamesLauncherInstaller.msi".into(),
|
||||
),
|
||||
proton_version: None,
|
||||
games: vec![],
|
||||
},
|
||||
@@ -167,7 +172,9 @@ pub fn presets() -> Vec<Launcher> {
|
||||
),
|
||||
gameid: "umu-uplay".into(),
|
||||
process_pattern: r"UbisoftConnect\.exe|upc\.exe".into(),
|
||||
installer_url: None,
|
||||
installer_url: Some(
|
||||
"https://ubistatic3-a.akamaihd.net/orbit/launcher_installer/UbisoftConnectInstaller.exe".into(),
|
||||
),
|
||||
proton_version: None,
|
||||
games: vec![],
|
||||
},
|
||||
@@ -180,7 +187,9 @@ pub fn presets() -> Vec<Launcher> {
|
||||
),
|
||||
gameid: "umu-gog".into(),
|
||||
process_pattern: r"GalaxyClient\.exe".into(),
|
||||
installer_url: None,
|
||||
installer_url: Some(
|
||||
"https://webinstallers.gog-statics.com/download/GOG_Galaxy_2.0.exe".into(),
|
||||
),
|
||||
proton_version: None,
|
||||
games: vec![],
|
||||
},
|
||||
@@ -193,7 +202,9 @@ pub fn presets() -> Vec<Launcher> {
|
||||
),
|
||||
gameid: "umu-rockstar".into(),
|
||||
process_pattern: r"Rockstar Games.*Launcher\.exe".into(),
|
||||
installer_url: None,
|
||||
installer_url: Some(
|
||||
"https://gamedownloads.rockstargames.com/public/installer/Rockstar-Games-Launcher.exe".into(),
|
||||
),
|
||||
proton_version: None,
|
||||
games: vec![],
|
||||
},
|
||||
@@ -320,7 +331,7 @@ impl Config {
|
||||
games: vec![],
|
||||
});
|
||||
self.save()?;
|
||||
println!("\x1b[1;32m✓\x1b[0m Added launcher '{name}'.");
|
||||
println!("{} Added launcher '{name}'.", "✓".green().bold());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -354,7 +365,7 @@ impl Config {
|
||||
gamescope,
|
||||
});
|
||||
self.save()?;
|
||||
println!("\x1b[1;32m✓\x1b[0m Added game '{name}' under launcher '{launcher}'.");
|
||||
println!("{} Added game '{name}' under launcher '{launcher}'.", "✓".green().bold());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -370,7 +381,7 @@ impl Config {
|
||||
anyhow::bail!("launcher '{launcher}' has no game named '{name}'");
|
||||
}
|
||||
self.save()?;
|
||||
println!("\x1b[1;32m✓\x1b[0m Removed game '{name}' from '{launcher}'.");
|
||||
println!("{} Removed game '{name}' from '{launcher}'.", "✓".green().bold());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -408,7 +419,7 @@ impl Config {
|
||||
g.gamescope = v;
|
||||
}
|
||||
self.save()?;
|
||||
println!("\x1b[1;32m✓\x1b[0m Updated flags for '{launcher}/{name}'.");
|
||||
println!("{} Updated flags for '{launcher}/{name}'.", "✓".green().bold());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -420,8 +431,8 @@ impl Config {
|
||||
}
|
||||
self.save()?;
|
||||
println!(
|
||||
"\x1b[1;32m✓\x1b[0m Removed '{name}'. \
|
||||
The Wine prefix on disk was left untouched."
|
||||
"{} Removed '{name}'. The Wine prefix on disk was left untouched.",
|
||||
"✓".green().bold()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
@@ -443,7 +454,7 @@ impl Config {
|
||||
self.proton_compat_dir = d;
|
||||
}
|
||||
self.save()?;
|
||||
println!("\x1b[1;32m✓\x1b[0m Config saved.");
|
||||
println!("{} Config saved.", "✓".green().bold());
|
||||
println!();
|
||||
self.show()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user