From 0c533b85a3710e9bbf343ecfbfe4a6785df25510 Mon Sep 17 00:00:00 2001 From: Wolf Vollprecht Date: Wed, 18 Dec 2024 15:51:31 +0100 Subject: [PATCH] make things work --- crates/rattler_menuinst/src/linux.rs | 70 +++++++++++-------- .../rattler_menuinst/src/linux/mime_config.rs | 63 ++++++++++++----- 2 files changed, 87 insertions(+), 46 deletions(-) diff --git a/crates/rattler_menuinst/src/linux.rs b/crates/rattler_menuinst/src/linux.rs index c998c2e8f..6cb14c19c 100644 --- a/crates/rattler_menuinst/src/linux.rs +++ b/crates/rattler_menuinst/src/linux.rs @@ -252,6 +252,7 @@ impl LinuxMenu { fn create_desktop_entry(&self) -> Result<(), MenuInstError> { let file = self.location(); + tracing::info!("Creating desktop entry at {}", file.display()); let writer = File::create(file)?; let mut writer = std::io::BufWriter::new(writer); @@ -443,26 +444,35 @@ impl LinuxMenu { Ok(()) } - fn xml_path_for_mime_type(&self, mime_type: &str) -> (PathBuf, bool) { + fn xml_path_for_mime_type(&self, mime_type: &str) -> Result<(PathBuf, bool), std::io::Error> { let basename = mime_type.replace("/", "-"); - let xml_files: Vec = - fs::read_dir(self.directories.data_directory.join("mime/applications")) - .unwrap() - .filter_map(|entry| { - let path = entry.unwrap().path(); - if path - .file_name() - .unwrap() - .to_str() - .unwrap() - .contains(&basename) - { - Some(path) - } else { - None - } - }) - .collect(); + let mime_directory = self.directories.data_directory.join("mime/applications"); + if !mime_directory.is_dir() { + return Ok(( + self.directories + .data_directory + .join("mime/packages") + .join(format!("{basename}.xml")), + false, + )); + } + + let xml_files: Vec = fs::read_dir(mime_directory)? + .filter_map(|entry| { + let path = entry.unwrap().path(); + if path + .file_name() + .unwrap() + .to_str() + .unwrap() + .contains(&basename) + { + Some(path) + } else { + None + } + }) + .collect(); if !xml_files.is_empty() { if xml_files.len() > 1 { @@ -472,15 +482,15 @@ impl LinuxMenu { xml_files ); } - return (xml_files[0].clone(), true); + return Ok((xml_files[0].clone(), true)); } - ( + Ok(( self.directories .data_directory .join("mime/packages") .join(format!("{basename}.xml")), false, - ) + )) } fn glob_pattern_for_mime_type( @@ -489,7 +499,7 @@ impl LinuxMenu { glob_pattern: &str, install: bool, ) -> Result { - let (xml_path, exists) = self.xml_path_for_mime_type(mime_type); + let (xml_path, exists) = self.xml_path_for_mime_type(mime_type).unwrap(); if exists { return Ok(xml_path); } @@ -502,12 +512,12 @@ impl LinuxMenu { let xml = format!( r#" - - - - {description} - - "# + + + + {description} + +"# ); let subcommand = if install { "install" } else { "uninstall" }; @@ -564,7 +574,7 @@ impl LinuxMenu { .collect::>(); for mime in resolved { - let (xml_path, exists) = self.xml_path_for_mime_type(&mime); + let (xml_path, exists) = self.xml_path_for_mime_type(&mime).unwrap(); if !exists { continue; } diff --git a/crates/rattler_menuinst/src/linux/mime_config.rs b/crates/rattler_menuinst/src/linux/mime_config.rs index cacf0c169..b4178a19e 100644 --- a/crates/rattler_menuinst/src/linux/mime_config.rs +++ b/crates/rattler_menuinst/src/linux/mime_config.rs @@ -36,11 +36,12 @@ impl MimeConfig { self.config.write(&self.path) } - pub fn register_mime_type(&mut self, mime_type: &str, application: &str) { - // Ensure sections exist - self.config.set_default_section("Default Applications"); - self.config.set_default_section("Added Associations"); + #[cfg(test)] + pub fn to_string(&self) -> String { + self.config.writes() + } + pub fn register_mime_type(&mut self, mime_type: &str, application: &str) { // Only set default if not already set if self.config.get("Default Applications", mime_type).is_none() { self.config.set( @@ -106,6 +107,8 @@ impl MimeConfig { #[cfg(test)] mod tests { + use crate::test::test_data; + use super::*; use tempfile::NamedTempFile; @@ -193,33 +196,37 @@ mod tests { // Test progressive changes to the config config.register_mime_type("text/plain", "notepad.desktop"); insta::assert_snapshot!(get_config_contents(&config), @r###" - text/plain=notepad.desktop [Default Applications] text/plain=notepad.desktop + [Added Associations] + text/plain=notepad.desktop "###); config.register_mime_type("text/plain", "gedit.desktop"); insta::assert_snapshot!(get_config_contents(&config), @r###" - text/plain=notepad.desktop;gedit.desktop [Default Applications] text/plain=notepad.desktop + [Added Associations] + text/plain=notepad.desktop;gedit.desktop "###); config.register_mime_type("application/pdf", "pdf-reader.desktop"); insta::assert_snapshot!(get_config_contents(&config), @r###" - text/plain=notepad.desktop;gedit.desktop - application/pdf=pdf-reader.desktop [Default Applications] text/plain=notepad.desktop application/pdf=pdf-reader.desktop + [Added Associations] + text/plain=notepad.desktop;gedit.desktop + application/pdf=pdf-reader.desktop "###); config.deregister_mime_type("text/plain", "notepad.desktop"); insta::assert_snapshot!(get_config_contents(&config), @r###" - text/plain=gedit.desktop - application/pdf=pdf-reader.desktop [Default Applications] application/pdf=pdf-reader.desktop + [Added Associations] + text/plain=gedit.desktop + application/pdf=pdf-reader.desktop "###); } @@ -247,13 +254,14 @@ mod tests { } insta::assert_snapshot!(get_config_contents(&config), @r###" - text/plain=notepad.desktop;gedit.desktop;vim.desktop - application/pdf=pdf-reader.desktop;browser.desktop - image/jpeg=image-viewer.desktop;gimp.desktop [Default Applications] text/plain=notepad.desktop application/pdf=pdf-reader.desktop image/jpeg=image-viewer.desktop + [Added Associations] + text/plain=notepad.desktop;gedit.desktop;vim.desktop + application/pdf=pdf-reader.desktop;browser.desktop + image/jpeg=image-viewer.desktop;gimp.desktop "###); // Remove some applications @@ -261,12 +269,35 @@ mod tests { config.deregister_mime_type("application/pdf", "pdf-reader.desktop"); insta::assert_snapshot!(get_config_contents(&config), @r###" - text/plain=notepad.desktop;vim.desktop - application/pdf=browser.desktop - image/jpeg=image-viewer.desktop;gimp.desktop [Default Applications] text/plain=notepad.desktop image/jpeg=image-viewer.desktop + [Added Associations] + text/plain=notepad.desktop;vim.desktop + application/pdf=browser.desktop + image/jpeg=image-viewer.desktop;gimp.desktop "###); } + + #[test] + fn test_existing_mimeapps() { + // load from test-data/linux/mimeapps.list + let path = test_data().join("linux-menu/mimeapps.list"); + let mut mimeapps = MimeConfig::new(path); + mimeapps.load().unwrap(); + + insta::assert_debug_snapshot!(mimeapps.config.get_map()); + + // Test adding a new mime type + mimeapps.register_mime_type("text/pixi", "pixi-app.desktop"); + + insta::assert_debug_snapshot!(mimeapps.config.get_map()); + insta::assert_snapshot!(mimeapps.to_string()); + + // Test removing an application + mimeapps.deregister_mime_type("text/html", "google-chrome.desktop"); + mimeapps.deregister_mime_type("text/pixi", "pixi-app.desktop"); + + insta::assert_debug_snapshot!(mimeapps.config.get_map()); + } }