Skip to content

Commit

Permalink
fix everything up on linux
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv committed Feb 20, 2025
1 parent 37d57b0 commit 1528a37
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 55 deletions.
6 changes: 4 additions & 2 deletions crates/rattler/src/install/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use std::{

use indexmap::IndexSet;
use itertools::Itertools;
use rattler_conda_types::{prefix_record::PathType, PackageRecord, Platform, PrefixRecord};
use rattler_conda_types::{
menuinst::MenuMode, prefix_record::PathType, PackageRecord, Platform, PrefixRecord,
};
use simple_spawn_blocking::{tokio::run_blocking_task, Cancelled};
use thiserror::Error;
use tokio::sync::{AcquireError, OwnedSemaphorePermit, Semaphore};
Expand Down Expand Up @@ -276,7 +278,7 @@ impl InstallDriver {
target_prefix,
target_prefix,
Platform::current(),
rattler_menuinst::MenuMode::User,
MenuMode::User,
) {
Ok(tracker_vec) => {
// Store tracker in the prefix record
Expand Down
2 changes: 1 addition & 1 deletion crates/rattler/src/install/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub async fn install_package_to_environment(
paths_data: paths.into(),
requested_spec: None,
link: None,
menuinst_tracker: None,
installed_system_menus: Vec::new(),
};

// Create the conda-meta directory if it doesnt exist yet.
Expand Down
2 changes: 2 additions & 0 deletions crates/rattler_conda_types/src/menuinst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub enum Tracker {
pub struct LinuxRegisteredMimeFile {
/// The application that was registered
pub application: String,
/// Path to use when calling `update-mime-database`
pub database_path: PathBuf,
/// The location of the config file that was edited
pub config_file: PathBuf,
/// The MIME types that were associated to the application
Expand Down
13 changes: 4 additions & 9 deletions crates/rattler_menuinst/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use std::path::Path;
#[cfg(target_os = "linux")]
use std::path::PathBuf;

use rattler_conda_types::{menuinst::Tracker, Platform};
use rattler_conda_types::{
menuinst::{MenuMode, Tracker},
Platform,
};

#[cfg(target_os = "linux")]
mod linux;
Expand All @@ -16,20 +19,12 @@ mod util;
mod windows;

pub mod slugify;
use serde::{Deserialize, Serialize};
pub use slugify::slugify;

use crate::{render::BaseMenuItemPlaceholders, schema::MenuInstSchema};

pub mod utils;

#[derive(Default, Debug, Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
pub enum MenuMode {
System,
#[default]
User,
}

#[derive(thiserror::Error, Debug)]
pub enum MenuInstError {
#[error("IO error: {0}")]
Expand Down
76 changes: 43 additions & 33 deletions crates/rattler_menuinst/src/linux.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use fs_err as fs;
use fs_err::File;
use mime_config::MimeConfig;
use rattler_conda_types::menuinst::{LinuxRegisteredMimeFile, LinuxTracker, MenuMode};
use std::collections::HashMap;
use std::io::Write;
use std::path::{Path, PathBuf};
Expand All @@ -16,11 +17,10 @@ use rattler_shell::shell;

use crate::render::{BaseMenuItemPlaceholders, MenuItemPlaceholders, PlaceholderString};
use crate::slugify;
use crate::tracker::LinuxTracker;
use crate::util::{log_output, run_pre_create_command};
use crate::{
schema::{Linux, MenuItemCommand},
MenuInstError, MenuMode,
MenuInstError,
};

pub struct LinuxMenu {
Expand Down Expand Up @@ -164,6 +164,7 @@ pub enum XdgMimeError {
IoError(#[from] std::io::Error),
}

/// Run `xdg-mime` with the given arguments
fn xdg_mime(
xml_file: &Path,
mode: MenuMode,
Expand Down Expand Up @@ -206,6 +207,14 @@ fn xdg_mime(
Ok(())
}

/// Update the desktop database by running `update-desktop-database`
fn update_desktop_database() -> Result<(), MenuInstError> {
// We don't care about the output of update-desktop-database
let _ = Command::new("update-desktop-database").output();

Ok(())
}

impl LinuxMenu {
fn new(
menu_name: &str,
Expand Down Expand Up @@ -434,19 +443,12 @@ impl LinuxMenu {
Ok(())
}

fn update_desktop_database() -> Result<(), MenuInstError> {
// We don't care about the output of update-desktop-database
let _ = Command::new("update-desktop-database").output();

Ok(())
}

fn install(&self, tracker: &mut LinuxTracker) -> Result<(), MenuInstError> {
self.directories.ensure_directories_exist()?;
self.pre_create()?;
self.create_desktop_entry(tracker)?;
self.register_mime_types(tracker)?;
Self::update_desktop_database()?;
update_desktop_database()?;
Ok(())
}

Expand Down Expand Up @@ -477,17 +479,21 @@ impl LinuxMenu {

let mimeapps = self.directories.config_directory.join("mimeapps.list");

let mut config = MimeConfig::new(mimeapps);
config.load()?;
for mime_type in mime_types {
let mut config = MimeConfig::load(&mimeapps)?;
for mime_type in &mime_types {
tracing::info!("Registering mime type {} for {}", mime_type, &self.name);
config.register_mime_type(&mime_type, &self.name);
tracker
.mime_types
.push((mime_type.clone(), self.name.clone()));
config.register_mime_type(mime_type, &self.name);
}
config.save()?;

// Store the data so that we can remove it later
tracker.mime_types = Some(LinuxRegisteredMimeFile {
mime_types: mime_types.clone(),
database_path: self.directories.mime_directory(),
application: self.name.clone(),
config_file: mimeapps,
});

update_mime_database(&self.directories.mime_directory())?;

Ok(())
Expand Down Expand Up @@ -575,6 +581,9 @@ impl LinuxMenu {
tracker.registered_mime_files.push(file_path);
}
Err(_) => {
if let Some(parent) = xml_path.parent() {
fs::create_dir_all(parent)?;
}
fs::write(&xml_path, xml)?;
tracker.paths.push(xml_path);
}
Expand Down Expand Up @@ -612,26 +621,26 @@ pub fn remove_menu_item(tracker: &LinuxTracker) -> Result<(), MenuInstError> {
}

for path in &tracker.registered_mime_files {
let _ = xdg_mime(path, tracker.install_mode, XdgMimeOperation::Uninstall)
.map_err(|e| tracing::warn!("Could not uninstall mime type: {}", e));
match xdg_mime(path, tracker.install_mode, XdgMimeOperation::Uninstall) {
Ok(_) => {}
Err(e) => {
tracing::warn!("Could not uninstall mime type: {}", e);
}
}
// Remove the temporary directory we created for the glob file
fs::remove_dir_all(path.parent().unwrap())?;
}

// invoke xdg-mime uninstall ...
if !tracker.mime_types.is_empty() {
if let Some(installed_mime_types) = tracker.mime_types.as_ref() {
// load mimetype config
// TODO - store path to mime config
let mut config = MimeConfig::new(PathBuf::from("/tmp/mimeapps.list"));
for mime_type in &tracker.mime_types {
tracing::info!(
"Unregistering mime type {} for {}",
mime_type.0,
mime_type.1
);
config.deregister_mime_type(&mime_type.0, &mime_type.1);
let mut config = MimeConfig::load(&installed_mime_types.config_file)?;
let application = &installed_mime_types.application;
for mime_type in &installed_mime_types.mime_types {
config.deregister_mime_type(&mime_type, &application);

Check failure on line 639 in crates/rattler_menuinst/src/linux.rs

View workflow job for this annotation

GitHub Actions / Format and Lint

this expression creates a reference which is immediately dereferenced by the compiler

Check failure on line 639 in crates/rattler_menuinst/src/linux.rs

View workflow job for this annotation

GitHub Actions / Format and Lint

this expression creates a reference which is immediately dereferenced by the compiler
}
config.save()?;
// TODO use `mime directory`.
update_mime_database(&PathBuf::from("/tmp/mime"))?;

update_mime_database(&installed_mime_types.database_path)?;
}

Ok(())
Expand All @@ -640,13 +649,14 @@ pub fn remove_menu_item(tracker: &LinuxTracker) -> Result<(), MenuInstError> {
#[cfg(test)]
mod tests {
use fs_err as fs;
use rattler_conda_types::menuinst::LinuxTracker;
use std::{
collections::HashMap,
path::{Path, PathBuf},
};
use tempfile::TempDir;

use crate::{schema::MenuInstSchema, test::test_data, tracker::LinuxTracker};
use crate::{schema::MenuInstSchema, test::test_data};

use super::{Directories, LinuxMenu};

Expand Down
20 changes: 10 additions & 10 deletions crates/rattler_menuinst/src/linux/mime_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@ pub struct MimeConfig {
impl MimeConfig {
pub fn new<P: AsRef<Path>>(path: P) -> Self {
Self {
// cs == case-sensitive
config: Ini::new_cs(),
path: path.as_ref().to_path_buf(),
}
}

pub fn load(&mut self) -> Result<(), std::io::Error> {
if self.path.exists() {
self.config
.load(&self.path)
/// Create a new MimeConfig instance and load the configuration from the given path
pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, std::io::Error> {
let mut this = Self::new(path);

if this.path.exists() {
this.config
.load(&this.path)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
}
Ok(())
Ok(this)
}

pub fn save(&self) -> Result<(), std::io::Error> {
Expand Down Expand Up @@ -169,8 +171,7 @@ mod tests {
config.register_mime_type("text/plain", "notepad.desktop");
config.save()?;

let mut new_config = MimeConfig::new(file.path());
new_config.load()?;
let new_config = MimeConfig::load(file.path())?;

assert_eq!(
new_config.get_default_application("text/plain"),
Expand Down Expand Up @@ -278,8 +279,7 @@ mod tests {
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();
let mut mimeapps = MimeConfig::load(path).unwrap();

insta::assert_debug_snapshot!(mimeapps.config.get_map());

Expand Down

0 comments on commit 1528a37

Please sign in to comment.