From 35cd751adc6fef1f792696fa0cfb471b0bf99374 Mon Sep 17 00:00:00 2001 From: Francis The Basilisk <36006338+snorkysnark@users.noreply.github.com> Date: Wed, 24 May 2023 21:04:54 +0200 Subject: [PATCH] feat(bundler): custom desktop file template, closes #5176 (#5180) Co-authored-by: Fabian-Lars Co-authored-by: Lucas Nogueira --- .changes/deb-custom-desktop-file-config.md | 7 +++ .changes/deb-custom-desktop-file.md | 5 ++ core/tauri-config-schema/schema.json | 7 +++ core/tauri-utils/src/config.rs | 4 ++ tooling/bundler/src/bundle/linux/debian.rs | 56 ++++++++++++++----- .../src/bundle/linux/templates/main.desktop | 10 ++++ tooling/bundler/src/bundle/settings.rs | 9 +++ tooling/cli/schema.json | 7 +++ tooling/cli/src/interface/rust.rs | 1 + 9 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 .changes/deb-custom-desktop-file-config.md create mode 100644 .changes/deb-custom-desktop-file.md create mode 100644 tooling/bundler/src/bundle/linux/templates/main.desktop diff --git a/.changes/deb-custom-desktop-file-config.md b/.changes/deb-custom-desktop-file-config.md new file mode 100644 index 000000000..96f0d81b9 --- /dev/null +++ b/.changes/deb-custom-desktop-file-config.md @@ -0,0 +1,7 @@ +--- +"tauri-utils": patch +"tauri-cli": patch +"@tauri-apps/cli": patch +--- + +Added the `desktop_template` option on `tauri.conf.json > tauri > bundle > deb`. diff --git a/.changes/deb-custom-desktop-file.md b/.changes/deb-custom-desktop-file.md new file mode 100644 index 000000000..ba66f4a20 --- /dev/null +++ b/.changes/deb-custom-desktop-file.md @@ -0,0 +1,5 @@ +--- +"tauri-bundler": "minor:feat" +--- + +Added `desktop_template` option on `DebianSettings`. diff --git a/core/tauri-config-schema/schema.json b/core/tauri-config-schema/schema.json index ca60fb912..9de891e30 100644 --- a/core/tauri-config-schema/schema.json +++ b/core/tauri-config-schema/schema.json @@ -1270,6 +1270,13 @@ "additionalProperties": { "type": "string" } + }, + "desktopTemplate": { + "description": "Path to a custom desktop file Handlebars template.\n\nAvailable variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.", + "type": [ + "string", + "null" + ] } }, "additionalProperties": false diff --git a/core/tauri-utils/src/config.rs b/core/tauri-utils/src/config.rs index 5754cda9e..2f94c8ff5 100644 --- a/core/tauri-utils/src/config.rs +++ b/core/tauri-utils/src/config.rs @@ -276,6 +276,10 @@ pub struct DebConfig { /// The files to include on the package. #[serde(default)] pub files: HashMap, + /// Path to a custom desktop file Handlebars template. + /// + /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`. + pub desktop_template: Option, } fn de_minimum_system_version<'de, D>(deserializer: D) -> Result, D::Error> diff --git a/tooling/bundler/src/bundle/linux/debian.rs b/tooling/bundler/src/bundle/linux/debian.rs index a318a0131..6e54325ba 100644 --- a/tooling/bundler/src/bundle/linux/debian.rs +++ b/tooling/bundler/src/bundle/linux/debian.rs @@ -26,16 +26,18 @@ use super::super::common; use crate::Settings; use anyhow::Context; +use handlebars::Handlebars; use heck::AsKebabCase; use image::{self, codecs::png::PngDecoder, ImageDecoder}; use libflate::gzip; use log::info; +use serde::Serialize; use walkdir::WalkDir; use std::{ collections::BTreeSet, ffi::OsStr, - fs::{self, File}, + fs::{self, read_to_string, File}, io::{self, Write}, path::{Path, PathBuf}, }; @@ -141,23 +143,51 @@ fn generate_desktop_file(settings: &Settings, data_dir: &Path) -> crate::Result< let desktop_file_path = data_dir .join("usr/share/applications") .join(desktop_file_name); - let file = &mut common::create_file(&desktop_file_path)?; + // For more information about the format of this file, see // https://developer.gnome.org/integration-guide/stable/desktop-files.html.en - writeln!(file, "[Desktop Entry]")?; - if let Some(category) = settings.app_category() { - writeln!(file, "Categories={}", category.gnome_desktop_categories())?; + let file = &mut common::create_file(&desktop_file_path)?; + + let mut handlebars = Handlebars::new(); + handlebars.register_escape_fn(handlebars::no_escape); + if let Some(template) = &settings.deb().desktop_template { + handlebars + .register_template_string("main.desktop", read_to_string(template)?) + .with_context(|| "Failed to setup custom handlebar template")?; } else { - writeln!(file, "Categories=")?; + handlebars + .register_template_string("main.desktop", include_str!("./templates/main.desktop")) + .with_context(|| "Failed to setup custom handlebar template")?; } - if !settings.short_description().is_empty() { - writeln!(file, "Comment={}", settings.short_description())?; + + #[derive(Serialize)] + struct DesktopTemplateParams<'a> { + categories: &'a str, + comment: Option<&'a str>, + exec: &'a str, + icon: &'a str, + name: &'a str, } - writeln!(file, "Exec={}", bin_name)?; - writeln!(file, "Icon={}", bin_name)?; - writeln!(file, "Name={}", settings.product_name())?; - writeln!(file, "Terminal=false")?; - writeln!(file, "Type=Application")?; + + handlebars.render_to_write( + "main.desktop", + &DesktopTemplateParams { + categories: settings + .app_category() + .map(|app_category| app_category.gnome_desktop_categories()) + .unwrap_or(""), + comment: if !settings.short_description().is_empty() { + Some(settings.short_description()) + } else { + None + }, + exec: bin_name, + icon: bin_name, + name: settings.product_name(), + }, + file, + )?; + Ok(()) } diff --git a/tooling/bundler/src/bundle/linux/templates/main.desktop b/tooling/bundler/src/bundle/linux/templates/main.desktop new file mode 100644 index 000000000..574cd598e --- /dev/null +++ b/tooling/bundler/src/bundle/linux/templates/main.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Categories={{categories}} +{{#if comment}} +Comment={{comment}} +{{/if}} +Exec={{exec}} +Icon={{icon}} +Name={{name}} +Terminal=false +Type=Application diff --git a/tooling/bundler/src/bundle/settings.rs b/tooling/bundler/src/bundle/settings.rs index d250c3943..ed09964c6 100644 --- a/tooling/bundler/src/bundle/settings.rs +++ b/tooling/bundler/src/bundle/settings.rs @@ -156,6 +156,15 @@ pub struct DebianSettings { /// List of custom files to add to the deb package. /// Maps the path on the debian package to the path of the file to include (relative to the current working directory). pub files: HashMap, + /// Path to a custom desktop file Handlebars template. + /// + /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`. + /// + /// Default file contents: + /// ```text + #[doc = include_str!("./linux/templates/main.desktop")] + /// ``` + pub desktop_template: Option, } /// The macOS bundle settings. diff --git a/tooling/cli/schema.json b/tooling/cli/schema.json index ca60fb912..9de891e30 100644 --- a/tooling/cli/schema.json +++ b/tooling/cli/schema.json @@ -1270,6 +1270,13 @@ "additionalProperties": { "type": "string" } + }, + "desktopTemplate": { + "description": "Path to a custom desktop file Handlebars template.\n\nAvailable variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.", + "type": [ + "string", + "null" + ] } }, "additionalProperties": false diff --git a/tooling/cli/src/interface/rust.rs b/tooling/cli/src/interface/rust.rs index 8ed4bde81..2e07f9214 100644 --- a/tooling/cli/src/interface/rust.rs +++ b/tooling/cli/src/interface/rust.rs @@ -1067,6 +1067,7 @@ fn tauri_config_to_bundle_settings( Some(depends) }, files: config.deb.files, + desktop_template: config.deb.desktop_template, }, macos: MacOsSettings { frameworks: config.macos.frameworks,