feat(bundler): add post/pre install/remove scripts for linux deb and rpm packages (#9209)

* feat(cli/add): add post/pre install/remove scripts for linux

* fix(cli): clippy errors

* fix(cli): remove script struct from deb/rpm bundle

* change files and aliases
This commit is contained in:
Vladimir Stoilov 2024-03-28 05:13:26 +02:00 committed by GitHub
parent c33f6e6cf3
commit 259d845290
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 269 additions and 20 deletions

View File

@ -0,0 +1,5 @@
---
'tauri-bundler': 'minor:feat'
---
Add suport for include `preinstall`, `postinstall`, `preremove` and `postremove` scripts into Debian and RPM packages.

View File

@ -0,0 +1,5 @@
---
'tauri-utils': 'minor:feat'
---
Added `preInstallScript`, `postInstallScript`, `preRemoveScript` and `postRemoveScript` options for `bundler > deb` and `bundler > rpm` configs.

View File

@ -2430,13 +2430,6 @@
"type": "string" "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": { "section": {
"description": "Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections", "description": "Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections",
"type": [ "type": [
@ -2457,6 +2450,41 @@
"string", "string",
"null" "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 "additionalProperties": false
@ -2501,6 +2529,34 @@
"string", "string",
"null" "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 "additionalProperties": false

View File

@ -326,10 +326,6 @@ pub struct DebConfig {
/// The files to include on the package. /// The files to include on the package.
#[serde(default)] #[serde(default)]
pub files: HashMap<PathBuf, PathBuf>, pub files: HashMap<PathBuf, PathBuf>,
/// Path to a custom desktop file Handlebars template.
///
/// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.
pub desktop_template: Option<PathBuf>,
/// Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections /// Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections
pub section: Option<String>, pub section: Option<String>,
/// Change the priority of the Debian Package. By default, it is set to `optional`. /// 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 /// 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 /// https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes
pub changelog: Option<PathBuf>, pub changelog: Option<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
} }
/// Configuration for Linux bundles. /// Configuration for Linux bundles.
@ -379,7 +396,24 @@ pub struct RpmConfig {
/// Path to a custom desktop file Handlebars template. /// Path to a custom desktop file Handlebars template.
/// ///
/// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`. /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.
#[serde(alias = "desktop-template")]
pub desktop_template: Option<PathBuf>, pub desktop_template: Option<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
} }
impl Default for RpmConfig { impl Default for RpmConfig {
@ -390,6 +424,10 @@ impl Default for RpmConfig {
epoch: 0, epoch: 0,
files: Default::default(), files: Default::default(),
desktop_template: None, desktop_template: None,
pre_install_script: None,
post_install_script: None,
pre_remove_script: None,
post_remove_script: None,
} }
} }
} }

View File

@ -32,9 +32,9 @@ use tar::HeaderMode;
use walkdir::WalkDir; use walkdir::WalkDir;
use std::{ use std::{
fs::{self, File}, fs::{self, File, OpenOptions},
io::{self, Write}, io::{self, Write},
os::unix::fs::MetadataExt, os::unix::fs::{MetadataExt, OpenOptionsExt},
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
@ -76,6 +76,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
let control_dir = package_dir.join("control"); let control_dir = package_dir.join("control");
generate_control_file(settings, arch, &control_dir, &data_dir) generate_control_file(settings, arch, &control_dir, &data_dir)
.with_context(|| "Failed to create control file")?; .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_md5sums(&control_dir, &data_dir).with_context(|| "Failed to create md5sums file")?;
// Generate `debian-binary` file; see // Generate `debian-binary` file; see
@ -202,6 +203,41 @@ fn generate_control_file(
Ok(()) 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 /// Create an `md5sums` file in the `control_dir` containing the MD5 checksums
/// for each file within the `data_dir`. /// for each file within the `data_dir`.
fn generate_md5sums(control_dir: &Path, data_dir: &Path) -> crate::Result<()> { fn generate_md5sums(control_dir: &Path, data_dir: &Path) -> crate::Result<()> {

View File

@ -78,6 +78,27 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
builder = builder.with_file(&src, FileOptions::new(dest.to_string_lossy()))?; 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 // Add resources
if settings.resource_files().count() > 0 { if settings.resource_files().count() > 0 {
let resource_dir = Path::new("/usr/lib").join(settings.main_binary_name()); let resource_dir = Path::new("/usr/lib").join(settings.main_binary_name());

View File

@ -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 /// 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 /// https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes
pub changelog: Option<PathBuf>, pub changelog: Option<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
} }
/// The Linux AppImage bundle settings. /// The Linux AppImage bundle settings.
@ -218,6 +230,18 @@ pub struct RpmSettings {
#[doc = include_str!("./linux/templates/main.desktop")] #[doc = include_str!("./linux/templates/main.desktop")]
/// ``` /// ```
pub desktop_template: Option<PathBuf>, pub desktop_template: Option<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
/// 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<PathBuf>,
} }
/// Position coordinates struct. /// Position coordinates struct.

View File

@ -2430,13 +2430,6 @@
"type": "string" "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": { "section": {
"description": "Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections", "description": "Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections",
"type": [ "type": [
@ -2457,6 +2450,41 @@
"string", "string",
"null" "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 "additionalProperties": false
@ -2501,6 +2529,34 @@
"string", "string",
"null" "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 "additionalProperties": false

View File

@ -1335,6 +1335,10 @@ fn tauri_config_to_bundle_settings(
section: config.linux.deb.section, section: config.linux.deb.section,
priority: config.linux.deb.priority, priority: config.linux.deb.priority,
changelog: config.linux.deb.changelog, 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 { appimage: AppImageSettings {
files: config.linux.appimage.files, files: config.linux.appimage.files,
@ -1349,6 +1353,10 @@ fn tauri_config_to_bundle_settings(
epoch: config.linux.rpm.epoch, epoch: config.linux.rpm.epoch,
files: config.linux.rpm.files, files: config.linux.rpm.files,
desktop_template: config.linux.rpm.desktop_template, 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 { dmg: DmgSettings {
background: config.macos.dmg.background, background: config.macos.dmg.background,