diff --git a/.changes/deb-rpm-post-pre-scripts-bundler.md b/.changes/deb-rpm-post-pre-scripts-bundler.md new file mode 100644 index 000000000..2a7f5b942 --- /dev/null +++ b/.changes/deb-rpm-post-pre-scripts-bundler.md @@ -0,0 +1,5 @@ +--- +'tauri-bundler': 'minor:feat' +--- + +Add suport for include `preinstall`, `postinstall`, `preremove` and `postremove` scripts into Debian and RPM packages. diff --git a/.changes/deb-rpm-post-pre-scripts-config.md b/.changes/deb-rpm-post-pre-scripts-config.md new file mode 100644 index 000000000..0723d7301 --- /dev/null +++ b/.changes/deb-rpm-post-pre-scripts-config.md @@ -0,0 +1,5 @@ +--- +'tauri-utils': 'minor:feat' +--- + +Added `preInstallScript`, `postInstallScript`, `preRemoveScript` and `postRemoveScript` options for `bundler > deb` and `bundler > rpm` configs. diff --git a/core/tauri-config-schema/schema.json b/core/tauri-config-schema/schema.json index 646ab5a14..8f6b61c8a 100644 --- a/core/tauri-config-schema/schema.json +++ b/core/tauri-config-schema/schema.json @@ -2430,13 +2430,6 @@ "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" - ] - }, "section": { "description": "Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections", "type": [ @@ -2457,6 +2450,41 @@ "string", "null" ] + }, + "desktopTemplate": { + "description": "Path to a custom desktop file Handlebars template.\n\nAvailable variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.", + "type": [ + "string", + "null" + ] + }, + "preInstallScript": { + "description": "Path to script that will be executed before the package is unpacked. See https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html", + "type": [ + "string", + "null" + ] + }, + "postInstallScript": { + "description": "Path to script that will be executed after the package is unpacked. See https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html", + "type": [ + "string", + "null" + ] + }, + "preRemoveScript": { + "description": "Path to script that will be executed before the package is removed. See https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html", + "type": [ + "string", + "null" + ] + }, + "postRemoveScript": { + "description": "Path to script that will be executed after the package is removed. See https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html", + "type": [ + "string", + "null" + ] } }, "additionalProperties": false @@ -2501,6 +2529,34 @@ "string", "null" ] + }, + "preInstallScript": { + "description": "Path to script that will be executed before the package is unpacked. See http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html", + "type": [ + "string", + "null" + ] + }, + "postInstallScript": { + "description": "Path to script that will be executed after the package is unpacked. See http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html", + "type": [ + "string", + "null" + ] + }, + "preRemoveScript": { + "description": "Path to script that will be executed before the package is removed. See http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html", + "type": [ + "string", + "null" + ] + }, + "postRemoveScript": { + "description": "Path to script that will be executed after the package is removed. See http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html", + "type": [ + "string", + "null" + ] } }, "additionalProperties": false diff --git a/core/tauri-utils/src/config.rs b/core/tauri-utils/src/config.rs index f7bf3db43..2c161e6b0 100644 --- a/core/tauri-utils/src/config.rs +++ b/core/tauri-utils/src/config.rs @@ -326,10 +326,6 @@ 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, /// Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections pub section: Option, /// Change the priority of the Debian Package. By default, it is set to `optional`. @@ -338,6 +334,27 @@ pub struct DebConfig { /// Path of the uncompressed Changelog file, to be stored at /usr/share/doc/package-name/changelog.gz. See /// https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes pub changelog: Option, + /// Path to a custom desktop file Handlebars template. + /// + /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`. + #[serde(alias = "desktop-template")] + pub desktop_template: Option, + /// Path to script that will be executed before the package is unpacked. See + /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html + #[serde(alias = "pre-install-script")] + pub pre_install_script: Option, + /// Path to script that will be executed after the package is unpacked. See + /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html + #[serde(alias = "post-install-script")] + pub post_install_script: Option, + /// Path to script that will be executed before the package is removed. See + /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html + #[serde(alias = "pre-remove-script")] + pub pre_remove_script: Option, + /// Path to script that will be executed after the package is removed. See + /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html + #[serde(alias = "post-remove-script")] + pub post_remove_script: Option, } /// Configuration for Linux bundles. @@ -379,7 +396,24 @@ pub struct RpmConfig { /// Path to a custom desktop file Handlebars template. /// /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`. + #[serde(alias = "desktop-template")] pub desktop_template: Option, + /// Path to script that will be executed before the package is unpacked. See + /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html + #[serde(alias = "pre-install-script")] + pub pre_install_script: Option, + /// Path to script that will be executed after the package is unpacked. See + /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html + #[serde(alias = "post-install-script")] + pub post_install_script: Option, + /// Path to script that will be executed before the package is removed. See + /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html + #[serde(alias = "pre-remove-script")] + pub pre_remove_script: Option, + /// Path to script that will be executed after the package is removed. See + /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html + #[serde(alias = "post-remove-script")] + pub post_remove_script: Option, } impl Default for RpmConfig { @@ -390,6 +424,10 @@ impl Default for RpmConfig { epoch: 0, files: Default::default(), desktop_template: None, + pre_install_script: None, + post_install_script: None, + pre_remove_script: None, + post_remove_script: None, } } } diff --git a/tooling/bundler/src/bundle/linux/debian.rs b/tooling/bundler/src/bundle/linux/debian.rs index 1d892ea2f..95c38a376 100644 --- a/tooling/bundler/src/bundle/linux/debian.rs +++ b/tooling/bundler/src/bundle/linux/debian.rs @@ -32,9 +32,9 @@ use tar::HeaderMode; use walkdir::WalkDir; use std::{ - fs::{self, File}, + fs::{self, File, OpenOptions}, io::{self, Write}, - os::unix::fs::MetadataExt, + os::unix::fs::{MetadataExt, OpenOptionsExt}, path::{Path, PathBuf}, }; @@ -76,6 +76,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { let control_dir = package_dir.join("control"); generate_control_file(settings, arch, &control_dir, &data_dir) .with_context(|| "Failed to create control file")?; + generate_scripts(settings, &control_dir).with_context(|| "Failed to create control scripts")?; generate_md5sums(&control_dir, &data_dir).with_context(|| "Failed to create md5sums file")?; // Generate `debian-binary` file; see @@ -202,6 +203,41 @@ fn generate_control_file( Ok(()) } +fn generate_scripts(settings: &Settings, control_dir: &Path) -> crate::Result<()> { + if let Some(script_path) = &settings.deb().pre_install_script { + let dest_path = control_dir.join("preinst"); + create_script_file_from_path(script_path, &dest_path)? + } + + if let Some(script_path) = &settings.deb().post_install_script { + let dest_path = control_dir.join("postinst"); + create_script_file_from_path(script_path, &dest_path)? + } + + if let Some(script_path) = &settings.deb().pre_remove_script { + let dest_path = control_dir.join("prerm"); + create_script_file_from_path(script_path, &dest_path)? + } + + if let Some(script_path) = &settings.deb().post_remove_script { + let dest_path = control_dir.join("postrm"); + create_script_file_from_path(script_path, &dest_path)? + } + Ok(()) +} + +fn create_script_file_from_path(from: &PathBuf, to: &PathBuf) -> crate::Result<()> { + let mut from = File::open(from)?; + let mut file = OpenOptions::new() + .create(true) + .truncate(true) + .write(true) + .mode(0o755) + .open(to)?; + std::io::copy(&mut from, &mut file)?; + Ok(()) +} + /// Create an `md5sums` file in the `control_dir` containing the MD5 checksums /// for each file within the `data_dir`. fn generate_md5sums(control_dir: &Path, data_dir: &Path) -> crate::Result<()> { diff --git a/tooling/bundler/src/bundle/linux/rpm.rs b/tooling/bundler/src/bundle/linux/rpm.rs index 2eacd4d71..437fe5b68 100644 --- a/tooling/bundler/src/bundle/linux/rpm.rs +++ b/tooling/bundler/src/bundle/linux/rpm.rs @@ -78,6 +78,27 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { builder = builder.with_file(&src, FileOptions::new(dest.to_string_lossy()))?; } + // Add scripts + if let Some(script_path) = &settings.rpm().pre_install_script { + let script = fs::read_to_string(script_path)?; + builder = builder.pre_install_script(script); + } + + if let Some(script_path) = &settings.rpm().post_install_script { + let script = fs::read_to_string(script_path)?; + builder = builder.post_install_script(script); + } + + if let Some(script_path) = &settings.rpm().pre_remove_script { + let script = fs::read_to_string(script_path)?; + builder = builder.pre_uninstall_script(script); + } + + if let Some(script_path) = &settings.rpm().post_remove_script { + let script = fs::read_to_string(script_path)?; + builder = builder.post_uninstall_script(script); + } + // Add resources if settings.resource_files().count() > 0 { let resource_dir = Path::new("/usr/lib").join(settings.main_binary_name()); diff --git a/tooling/bundler/src/bundle/settings.rs b/tooling/bundler/src/bundle/settings.rs index 2a9c150d4..694305c0b 100644 --- a/tooling/bundler/src/bundle/settings.rs +++ b/tooling/bundler/src/bundle/settings.rs @@ -188,6 +188,18 @@ pub struct DebianSettings { /// Path of the uncompressed Changelog file, to be stored at /usr/share/doc/package-name/changelog.gz. See /// https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes pub changelog: Option, + /// Path to script that will be executed before the package is unpacked. See + /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html + pub pre_install_script: Option, + /// Path to script that will be executed after the package is unpacked. See + /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html + pub post_install_script: Option, + /// Path to script that will be executed before the package is removed. See + /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html + pub pre_remove_script: Option, + /// Path to script that will be executed after the package is removed. See + /// https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html + pub post_remove_script: Option, } /// The Linux AppImage bundle settings. @@ -218,6 +230,18 @@ pub struct RpmSettings { #[doc = include_str!("./linux/templates/main.desktop")] /// ``` pub desktop_template: Option, + /// Path to script that will be executed before the package is unpacked. See + /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html + pub pre_install_script: Option, + /// Path to script that will be executed after the package is unpacked. See + /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html + pub post_install_script: Option, + /// Path to script that will be executed before the package is removed. See + /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html + pub pre_remove_script: Option, + /// Path to script that will be executed after the package is removed. See + /// http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html + pub post_remove_script: Option, } /// Position coordinates struct. diff --git a/tooling/cli/schema.json b/tooling/cli/schema.json index 646ab5a14..8f6b61c8a 100644 --- a/tooling/cli/schema.json +++ b/tooling/cli/schema.json @@ -2430,13 +2430,6 @@ "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" - ] - }, "section": { "description": "Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections", "type": [ @@ -2457,6 +2450,41 @@ "string", "null" ] + }, + "desktopTemplate": { + "description": "Path to a custom desktop file Handlebars template.\n\nAvailable variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.", + "type": [ + "string", + "null" + ] + }, + "preInstallScript": { + "description": "Path to script that will be executed before the package is unpacked. See https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html", + "type": [ + "string", + "null" + ] + }, + "postInstallScript": { + "description": "Path to script that will be executed after the package is unpacked. See https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html", + "type": [ + "string", + "null" + ] + }, + "preRemoveScript": { + "description": "Path to script that will be executed before the package is removed. See https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html", + "type": [ + "string", + "null" + ] + }, + "postRemoveScript": { + "description": "Path to script that will be executed after the package is removed. See https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html", + "type": [ + "string", + "null" + ] } }, "additionalProperties": false @@ -2501,6 +2529,34 @@ "string", "null" ] + }, + "preInstallScript": { + "description": "Path to script that will be executed before the package is unpacked. See http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html", + "type": [ + "string", + "null" + ] + }, + "postInstallScript": { + "description": "Path to script that will be executed after the package is unpacked. See http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html", + "type": [ + "string", + "null" + ] + }, + "preRemoveScript": { + "description": "Path to script that will be executed before the package is removed. See http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html", + "type": [ + "string", + "null" + ] + }, + "postRemoveScript": { + "description": "Path to script that will be executed after the package is removed. See http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html", + "type": [ + "string", + "null" + ] } }, "additionalProperties": false diff --git a/tooling/cli/src/interface/rust.rs b/tooling/cli/src/interface/rust.rs index c1ce99a56..4eae3c14a 100644 --- a/tooling/cli/src/interface/rust.rs +++ b/tooling/cli/src/interface/rust.rs @@ -1335,6 +1335,10 @@ fn tauri_config_to_bundle_settings( section: config.linux.deb.section, priority: config.linux.deb.priority, changelog: config.linux.deb.changelog, + pre_install_script: config.linux.deb.pre_install_script, + post_install_script: config.linux.deb.post_install_script, + pre_remove_script: config.linux.deb.pre_remove_script, + post_remove_script: config.linux.deb.post_remove_script, }, appimage: AppImageSettings { files: config.linux.appimage.files, @@ -1349,6 +1353,10 @@ fn tauri_config_to_bundle_settings( epoch: config.linux.rpm.epoch, files: config.linux.rpm.files, desktop_template: config.linux.rpm.desktop_template, + pre_install_script: config.linux.rpm.pre_install_script, + post_install_script: config.linux.rpm.post_install_script, + pre_remove_script: config.linux.rpm.pre_remove_script, + post_remove_script: config.linux.rpm.post_remove_script, }, dmg: DmgSettings { background: config.macos.dmg.background,