From 202cdcc6390178fc35867f4bbb007730f73b267b Mon Sep 17 00:00:00 2001 From: Olivier Lemasle Date: Sat, 23 Dec 2023 18:38:15 +0100 Subject: [PATCH] feat(bundler): Add RPM packaging, closes #4402 (#5202) * feat(bundler): Add RPM packaging * feat(bundler): Update 'rpm' to 0.13.1 * Fix fmt --- .changes/bundler-rpm.md | 8 + core/tauri-config-schema/schema.json | 83 +- core/tauri-utils/src/config.rs | 55 +- tooling/bundler/Cargo.toml | 1 + tooling/bundler/src/bundle.rs | 2 +- tooling/bundler/src/bundle/category.rs | 6 +- tooling/bundler/src/bundle/linux/appimage.rs | 1 - tooling/bundler/src/bundle/linux/debian.rs | 121 +-- .../bundler/src/bundle/linux/freedesktop.rs | 147 ++++ tooling/bundler/src/bundle/linux/mod.rs | 1 + tooling/bundler/src/bundle/linux/rpm.rs | 147 +++- tooling/bundler/src/bundle/settings.rs | 42 +- tooling/bundler/src/error.rs | 4 + tooling/bundler/src/lib.rs | 2 +- tooling/cli/Cargo.lock | 745 +++++++++++++++++- tooling/cli/ENVIRONMENT_VARIABLES.md | 2 + tooling/cli/schema.json | 83 +- tooling/cli/src/build.rs | 2 +- tooling/cli/src/interface/rust.rs | 52 +- 19 files changed, 1357 insertions(+), 147 deletions(-) create mode 100644 .changes/bundler-rpm.md create mode 100644 tooling/bundler/src/bundle/linux/freedesktop.rs diff --git a/.changes/bundler-rpm.md b/.changes/bundler-rpm.md new file mode 100644 index 000000000000..1ade9dddaca6 --- /dev/null +++ b/.changes/bundler-rpm.md @@ -0,0 +1,8 @@ +--- +"tauri-bundler": 'patch:minor' +"tauri-cli": 'patch:minor' +"tauri-utils": 'patch:minor' +"@tauri-apps/cli": 'patch:minor' +--- + +Add RPM packaging diff --git a/core/tauri-config-schema/schema.json b/core/tauri-config-schema/schema.json index 3ad96747ea7f..8ad752c5e2c7 100644 --- a/core/tauri-config-schema/schema.json +++ b/core/tauri-config-schema/schema.json @@ -144,6 +144,11 @@ "macOS": { "minimumSystemVersion": "10.13" }, + "rpm": { + "epoch": 0, + "files": {}, + "release": "1" + }, "targets": "all", "windows": { "allowDowngrades": true, @@ -283,6 +288,11 @@ "macOS": { "minimumSystemVersion": "10.13" }, + "rpm": { + "epoch": 0, + "files": {}, + "release": "1" + }, "targets": "all", "windows": { "allowDowngrades": true, @@ -1046,7 +1056,7 @@ "type": "boolean" }, "targets": { - "description": "The bundle targets, currently supports [\"deb\", \"appimage\", \"nsis\", \"msi\", \"app\", \"dmg\", \"updater\"] or \"all\".", + "description": "The bundle targets, currently supports [\"deb\", \"rpm\", \"appimage\", \"nsis\", \"msi\", \"app\", \"dmg\", \"updater\"] or \"all\".", "default": "all", "allOf": [ { @@ -1134,6 +1144,19 @@ } ] }, + "rpm": { + "description": "Configuration for the RPM bundle.", + "default": { + "epoch": 0, + "files": {}, + "release": "1" + }, + "allOf": [ + { + "$ref": "#/definitions/RpmConfig" + } + ] + }, "macOS": { "description": "Configuration for the macOS bundles.", "default": { @@ -1216,6 +1239,13 @@ "deb" ] }, + { + "description": "The RPM bundle (.rpm).", + "type": "string", + "enum": [ + "rpm" + ] + }, { "description": "The AppImage bundle (.appimage).", "type": "string", @@ -1344,6 +1374,57 @@ }, "additionalProperties": false }, + "RpmConfig": { + "description": "Configuration for RPM bundles.", + "type": "object", + "properties": { + "license": { + "description": "The package's license identifier. If not set, defaults to the license from the Cargo.toml file.", + "type": [ + "string", + "null" + ] + }, + "depends": { + "description": "The list of RPM dependencies your application relies on.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "release": { + "description": "The RPM release tag.", + "default": "1", + "type": "string" + }, + "epoch": { + "description": "The RPM epoch.", + "default": 0, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "files": { + "description": "The files to include on the package.", + "default": {}, + "type": "object", + "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 + }, "MacConfig": { "description": "Configuration for the macOS bundles.\n\nSee more: https://tauri.app/v1/api/config#macconfig", "type": "object", diff --git a/core/tauri-utils/src/config.rs b/core/tauri-utils/src/config.rs index cb60dc30445b..86eb3ca622b0 100644 --- a/core/tauri-utils/src/config.rs +++ b/core/tauri-utils/src/config.rs @@ -78,6 +78,8 @@ impl Default for WindowUrl { pub enum BundleType { /// The debian bundle (.deb). Deb, + /// The RPM bundle (.rpm). + Rpm, /// The AppImage bundle (.appimage). AppImage, /// The Microsoft Installer bundle (.msi). @@ -99,6 +101,7 @@ impl Display for BundleType { "{}", match self { Self::Deb => "deb", + Self::Rpm => "rpm", Self::AppImage => "appimage", Self::Msi => "msi", Self::Nsis => "nsis", @@ -127,6 +130,7 @@ impl<'de> Deserialize<'de> for BundleType { let s = String::deserialize(deserializer)?; match s.to_lowercase().as_str() { "deb" => Ok(Self::Deb), + "rpm" => Ok(Self::Rpm), "appimage" => Ok(Self::AppImage), "msi" => Ok(Self::Msi), "nsis" => Ok(Self::Nsis), @@ -284,6 +288,49 @@ pub struct DebConfig { pub changelog: Option, } +/// Configuration for RPM bundles. +#[skip_serializing_none] +#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct RpmConfig { + /// The package's license identifier. If not set, defaults to the license from + /// the Cargo.toml file. + pub license: Option, + /// The list of RPM dependencies your application relies on. + pub depends: Option>, + /// The RPM release tag. + #[serde(default = "default_release")] + pub release: String, + /// The RPM epoch. + #[serde(default)] + pub epoch: u32, + /// 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, +} + +impl Default for RpmConfig { + fn default() -> Self { + Self { + license: None, + depends: None, + release: default_release(), + epoch: 0, + files: Default::default(), + desktop_template: None, + } + } +} + +fn default_release() -> String { + "1".into() +} + fn de_minimum_system_version<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, @@ -681,7 +728,7 @@ pub struct BundleConfig { /// Whether Tauri should bundle your application or just output the executable. #[serde(default)] pub active: bool, - /// The bundle targets, currently supports ["deb", "appimage", "nsis", "msi", "app", "dmg", "updater"] or "all". + /// The bundle targets, currently supports ["deb", "rpm", "appimage", "nsis", "msi", "app", "dmg", "updater"] or "all". #[serde(default)] pub targets: BundleTarget, /// The application identifier in reverse domain name notation (e.g. `com.tauri.example`). @@ -719,6 +766,9 @@ pub struct BundleConfig { /// Configuration for the Debian bundle. #[serde(default)] pub deb: DebConfig, + /// Configuration for the RPM bundle. + #[serde(default)] + pub rpm: RpmConfig, /// Configuration for the macOS bundles. #[serde(rename = "macOS", default)] pub macos: MacConfig, @@ -3546,6 +3596,7 @@ mod build { let long_description = quote!(None); let appimage = quote!(Default::default()); let deb = quote!(Default::default()); + let rpm = quote!(Default::default()); let macos = quote!(Default::default()); let external_bin = opt_vec_str_lit(self.external_bin.as_ref()); let windows = &self.windows; @@ -3565,6 +3616,7 @@ mod build { long_description, appimage, deb, + rpm, macos, external_bin, windows @@ -4007,6 +4059,7 @@ mod test { long_description: None, appimage: Default::default(), deb: Default::default(), + rpm: Default::default(), macos: Default::default(), external_bin: None, windows: Default::default(), diff --git a/tooling/bundler/Cargo.toml b/tooling/bundler/Cargo.toml index 8047132a8f6e..ae94c2a5c1d9 100644 --- a/tooling/bundler/Cargo.toml +++ b/tooling/bundler/Cargo.toml @@ -65,6 +65,7 @@ regex = "1" heck = "0.5" ar = "0.9.0" md5 = "0.7.0" +rpm = "0.14.0" [lib] name = "tauri_bundler" diff --git a/tooling/bundler/src/bundle.rs b/tooling/bundler/src/bundle.rs index 763ca75b7696..9616e3201e9a 100644 --- a/tooling/bundler/src/bundle.rs +++ b/tooling/bundler/src/bundle.rs @@ -21,7 +21,7 @@ pub use self::{ category::AppCategory, settings::{ BundleBinary, BundleSettings, DebianSettings, MacOsSettings, PackageSettings, PackageType, - Settings, SettingsBuilder, UpdaterSettings, + RpmSettings, Settings, SettingsBuilder, UpdaterSettings, }, }; #[cfg(target_os = "macos")] diff --git a/tooling/bundler/src/bundle/category.rs b/tooling/bundler/src/bundle/category.rs index 39933c745547..d59d0df124d7 100644 --- a/tooling/bundler/src/bundle/category.rs +++ b/tooling/bundler/src/bundle/category.rs @@ -142,9 +142,11 @@ impl AppCategory { } } - /// Map an AppCategory to the closest set of GNOME desktop registered + /// Map an AppCategory to the closest set of Freedesktop registered /// categories that matches that category. - pub fn gnome_desktop_categories(self) -> &'static str { + /// + /// Cf https://specifications.freedesktop.org/menu-spec/latest/ + pub fn freedesktop_categories(self) -> &'static str { match &self { AppCategory::Business => "Office;", AppCategory::DeveloperTool => "Development;", diff --git a/tooling/bundler/src/bundle/linux/appimage.rs b/tooling/bundler/src/bundle/linux/appimage.rs index 90f6665ab0cc..331a83303f3b 100644 --- a/tooling/bundler/src/bundle/linux/appimage.rs +++ b/tooling/bundler/src/bundle/linux/appimage.rs @@ -31,7 +31,6 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { // generate deb_folder structure let (_, icons) = debian::generate_data(settings, &package_dir)?; - let icons: Vec = icons.into_iter().collect(); let output_path = settings.project_out_directory().join("bundle/appimage"); if output_path.exists() { diff --git a/tooling/bundler/src/bundle/linux/debian.rs b/tooling/bundler/src/bundle/linux/debian.rs index 23b76af95dd8..f0e7dbe58ecd 100644 --- a/tooling/bundler/src/bundle/linux/debian.rs +++ b/tooling/bundler/src/bundle/linux/debian.rs @@ -23,21 +23,16 @@ // metadata, as well as generating the md5sums file. Currently we do not // generate postinst or prerm files. -use super::super::common; +use super::{super::common, freedesktop}; use crate::Settings; use anyhow::Context; -use handlebars::Handlebars; use heck::AsKebabCase; -use image::{self, codecs::png::PngDecoder, ImageDecoder}; use log::info; -use serde::Serialize; use tar::HeaderMode; use walkdir::WalkDir; use std::{ - collections::BTreeSet, - ffi::OsStr, - fs::{self, read_to_string, File}, + fs::{self, File}, io::{self, Write}, os::unix::fs::MetadataExt, path::{Path, PathBuf}, @@ -45,14 +40,6 @@ use std::{ use flate2::{write::GzEncoder, Compression}; -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct DebIcon { - pub width: u32, - pub height: u32, - pub is_high_density: bool, - pub path: PathBuf, -} - /// Bundles the project. /// Returns a vector of PathBuf that shows where the DEB was created. pub fn bundle_project(settings: &Settings) -> crate::Result> { @@ -115,7 +102,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { pub fn generate_data( settings: &Settings, package_dir: &Path, -) -> crate::Result<(PathBuf, BTreeSet)> { +) -> crate::Result<(PathBuf, Vec)> { // Generate data files. let data_dir = package_dir.join("data"); let bin_dir = data_dir.join("usr/bin"); @@ -132,9 +119,10 @@ pub fn generate_data( .copy_binaries(&bin_dir) .with_context(|| "Failed to copy external binaries")?; - let icons = - generate_icon_files(settings, &data_dir).with_context(|| "Failed to create icon files")?; - generate_desktop_file(settings, &data_dir).with_context(|| "Failed to create desktop file")?; + let icons = freedesktop::copy_icon_files(settings, &data_dir) + .with_context(|| "Failed to create icon files")?; + freedesktop::generate_desktop_file(settings, &settings.deb().desktop_template, &data_dir) + .with_context(|| "Failed to create desktop file")?; generate_changelog_file(settings, &data_dir) .with_context(|| "Failed to create changelog.gz file")?; @@ -159,61 +147,6 @@ fn generate_changelog_file(settings: &Settings, data_dir: &Path) -> crate::Resul Ok(()) } -/// Generate the application desktop file and store it under the `data_dir`. -fn generate_desktop_file(settings: &Settings, data_dir: &Path) -> crate::Result<()> { - let bin_name = settings.main_binary_name(); - let desktop_file_name = format!("{}.desktop", bin_name); - let desktop_file_path = data_dir - .join("usr/share/applications") - .join(desktop_file_name); - - // For more information about the format of this file, see - // https://developer.gnome.org/integration-guide/stable/desktop-files.html.en - 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 { - handlebars - .register_template_string("main.desktop", include_str!("./templates/main.desktop")) - .with_context(|| "Failed to setup custom handlebar template")?; - } - - #[derive(Serialize)] - struct DesktopTemplateParams<'a> { - categories: &'a str, - comment: Option<&'a str>, - exec: &'a str, - icon: &'a str, - name: &'a str, - } - - 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(()) -} - /// Generates the debian control file and stores it under the `control_dir`. fn generate_control_file( settings: &Settings, @@ -326,46 +259,6 @@ fn copy_custom_files(settings: &Settings, data_dir: &Path) -> crate::Result<()> Ok(()) } -/// Generate the icon files and store them under the `data_dir`. -fn generate_icon_files(settings: &Settings, data_dir: &Path) -> crate::Result> { - let base_dir = data_dir.join("usr/share/icons/hicolor"); - let get_dest_path = |width: u32, height: u32, is_high_density: bool| { - base_dir.join(format!( - "{}x{}{}/apps/{}.png", - width, - height, - if is_high_density { "@2" } else { "" }, - settings.main_binary_name() - )) - }; - let mut icons = BTreeSet::new(); - for icon_path in settings.icon_files() { - let icon_path = icon_path?; - if icon_path.extension() != Some(OsStr::new("png")) { - continue; - } - // Put file in scope so that it's closed when copying it - let deb_icon = { - let decoder = PngDecoder::new(File::open(&icon_path)?)?; - let width = decoder.dimensions().0; - let height = decoder.dimensions().1; - let is_high_density = common::is_retina(&icon_path); - let dest_path = get_dest_path(width, height, is_high_density); - DebIcon { - width, - height, - is_high_density, - path: dest_path, - } - }; - if !icons.contains(&deb_icon) { - common::copy_file(&icon_path, &deb_icon.path)?; - icons.insert(deb_icon); - } - } - Ok(icons) -} - /// Create an empty file at the given path, creating any parent directories as /// needed, then write `data` into the file. fn create_file_with_data>(path: P, data: &str) -> crate::Result<()> { diff --git a/tooling/bundler/src/bundle/linux/freedesktop.rs b/tooling/bundler/src/bundle/linux/freedesktop.rs new file mode 100644 index 000000000000..d72f77be5baf --- /dev/null +++ b/tooling/bundler/src/bundle/linux/freedesktop.rs @@ -0,0 +1,147 @@ +// Copyright 2016-2019 Cargo-Bundle developers +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +//! This module provides utilities helping the packaging of desktop +//! applications for Linux: +//! +//! - Generation of [desktop entries] (`.desktop` files) +//! - Copy of icons in the [icons file hierarchy] +//! +//! The specifications are developed and hosted at [freedesktop.org]. +//! +//! [freedesktop.org]: https://www.freedesktop.org +//! [desktop entries]: https://www.freedesktop.org/wiki/Specifications/desktop-entry-spec/ +//! [icons file hierarchy]: https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html#icon_lookup + +use std::collections::BTreeMap; +use std::ffi::OsStr; +use std::fs::{read_to_string, File}; +use std::path::{Path, PathBuf}; + +use anyhow::Context; +use handlebars::Handlebars; +use image::{self, codecs::png::PngDecoder, ImageDecoder}; +use serde::Serialize; + +use crate::bundle::common; +use crate::Settings; + +#[derive(PartialEq, Eq, PartialOrd, Ord)] +pub struct Icon { + pub width: u32, + pub height: u32, + pub is_high_density: bool, + pub path: PathBuf, +} + +/// Generate the icon files, and returns a map where keys are the icons and +/// values are their current (source) path. +pub fn list_icon_files( + settings: &Settings, + data_dir: &Path, +) -> crate::Result> { + let base_dir = data_dir.join("usr/share/icons/hicolor"); + let get_dest_path = |width: u32, height: u32, is_high_density: bool| { + base_dir.join(format!( + "{}x{}{}/apps/{}.png", + width, + height, + if is_high_density { "@2" } else { "" }, + settings.main_binary_name() + )) + }; + let mut icons = BTreeMap::new(); + for icon_path in settings.icon_files() { + let icon_path = icon_path?; + if icon_path.extension() != Some(OsStr::new("png")) { + continue; + } + // Put file in scope so that it's closed when copying it + let icon = { + let decoder = PngDecoder::new(File::open(&icon_path)?)?; + let width = decoder.dimensions().0; + let height = decoder.dimensions().1; + let is_high_density = common::is_retina(&icon_path); + let dest_path = get_dest_path(width, height, is_high_density); + Icon { + width, + height, + is_high_density, + path: dest_path, + } + }; + icons.entry(icon).or_insert(icon_path); + } + + Ok(icons) +} + +/// Generate the icon files and store them under the `data_dir`. +pub fn copy_icon_files(settings: &Settings, data_dir: &Path) -> crate::Result> { + let icons = self::list_icon_files(settings, data_dir)?; + for (icon, src) in &icons { + common::copy_file(src, &icon.path)?; + } + + Ok(icons.into_keys().collect()) +} + +/// Generate the application desktop file and store it under the `data_dir`. +/// Returns the path of the resulting file (source path) and the destination +/// path in the package. +pub fn generate_desktop_file( + settings: &Settings, + template_settings: &Option, + data_dir: &Path, +) -> crate::Result<(PathBuf, PathBuf)> { + let bin_name = settings.main_binary_name(); + let desktop_file_name = format!("{bin_name}.desktop"); + let path = PathBuf::from("usr/share/applications").join(desktop_file_name); + let dest_path = PathBuf::from("/").join(&path); + let file_path = data_dir.join(&path); + let file = &mut common::create_file(&file_path)?; + + let mut handlebars = Handlebars::new(); + handlebars.register_escape_fn(handlebars::no_escape); + if let Some(template) = template_settings { + handlebars + .register_template_string("main.desktop", read_to_string(template)?) + .with_context(|| "Failed to setup custom handlebar template")?; + } else { + handlebars + .register_template_string("main.desktop", include_str!("./templates/main.desktop")) + .with_context(|| "Failed to setup default handlebar template")?; + } + + #[derive(Serialize)] + struct DesktopTemplateParams<'a> { + categories: &'a str, + comment: Option<&'a str>, + exec: &'a str, + icon: &'a str, + name: &'a str, + } + + handlebars.render_to_write( + "main.desktop", + &DesktopTemplateParams { + categories: settings + .app_category() + .map(|app_category| app_category.freedesktop_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((file_path, dest_path)) +} diff --git a/tooling/bundler/src/bundle/linux/mod.rs b/tooling/bundler/src/bundle/linux/mod.rs index 5c745aebd363..c25b0e77d310 100644 --- a/tooling/bundler/src/bundle/linux/mod.rs +++ b/tooling/bundler/src/bundle/linux/mod.rs @@ -5,4 +5,5 @@ pub mod appimage; pub mod debian; +pub mod freedesktop; pub mod rpm; diff --git a/tooling/bundler/src/bundle/linux/rpm.rs b/tooling/bundler/src/bundle/linux/rpm.rs index 169c3c4c57d3..fc06e2af93eb 100644 --- a/tooling/bundler/src/bundle/linux/rpm.rs +++ b/tooling/bundler/src/bundle/linux/rpm.rs @@ -5,10 +5,149 @@ use crate::Settings; -use std::path::PathBuf; +use anyhow::Context; +use log::info; +use rpm::{self, signature::pgp, Dependency, FileMode, FileOptions}; +use std::{ + env, + fs::{self, File}, + path::{Path, PathBuf}, +}; + +use super::freedesktop; /// Bundles the project. -/// Not implemented yet. -pub fn bundle_project(_settings: &Settings) -> crate::Result> { - unimplemented!(); +/// Returns a vector of PathBuf that shows where the RPM was created. +pub fn bundle_project(settings: &Settings) -> crate::Result> { + let name = settings.main_binary_name(); + let version = settings.version_string(); + let release = settings.rpm().release.as_str(); + let epoch = settings.rpm().epoch; + let arch = match settings.binary_arch() { + "x86" => "i386", + "arm" => "armhfp", + other => other, + }; + + let license = settings + .rpm() + .license + .as_deref() + .or_else(|| settings.license()) + .unwrap_or_default(); + + let summary = settings.short_description().trim(); + + let package_base_name = format!("{name}-{version}-{release}.{arch}"); + let package_name = format!("{package_base_name}.rpm"); + + let base_dir = settings.project_out_directory().join("bundle/rpm"); + let package_dir = base_dir.join(&package_base_name); + if package_dir.exists() { + fs::remove_dir_all(&package_dir) + .with_context(|| format!("Failed to remove old {package_base_name}"))?; + } + fs::create_dir_all(&package_dir)?; + let package_path = base_dir.join(&package_name); + + info!(action = "Bundling"; "{} ({})", package_name, package_path.display()); + + let mut builder = rpm::PackageBuilder::new(name, version, license, arch, summary) + .epoch(epoch) + .release(release) + // This matches .deb compression. On a 240MB source binary the bundle will be 100KB larger than rpm's default while reducing build times by ~25%. + .compression(rpm::CompressionWithLevel::Gzip(6)); + + if let Some(description) = settings.long_description() { + builder = builder.description(description.trim()) + } + + // Add requirements + for dep in settings.rpm().depends.as_ref().cloned().unwrap_or_default() { + builder = builder.requires(Dependency::any(dep)); + } + + // Add binaries + for bin in settings.binaries() { + let src = settings.binary_path(bin); + let dest = Path::new("/usr/bin").join(bin.name()); + builder = builder.with_file(src, FileOptions::new(dest.to_string_lossy()))?; + } + + // Add external binaries + for src in settings.external_binaries() { + let src = src?; + let dest = Path::new("/usr/bin").join( + src + .file_name() + .expect("failed to extract external binary filename") + .to_string_lossy() + .replace(&format!("-{}", settings.target()), ""), + ); + builder = builder.with_file(&src, FileOptions::new(dest.to_string_lossy()))?; + } + + // Add resources + if settings.resource_files().count() > 0 { + let resource_dir = Path::new("/usr/lib").join(settings.main_binary_name()); + // Create an empty file, needed to add a directory to the RPM package + // (cf https://github.com/rpm-rs/rpm/issues/177) + let empty_file_path = &package_dir.join("empty"); + File::create(empty_file_path)?; + // Then add the resource directory `/usr/lib/` to the package. + builder = builder.with_file( + empty_file_path, + FileOptions::new(resource_dir.to_string_lossy()).mode(FileMode::Dir { permissions: 0o755 }), + )?; + // Then add the resources files in that directory + for src in settings.resource_files() { + let src = src?; + let dest = resource_dir.join(tauri_utils::resources::resource_relpath(&src)); + builder = builder.with_file(&src, FileOptions::new(dest.to_string_lossy()))?; + } + } + + // Add Desktop entry file + let (desktop_src_path, desktop_dest_path) = + freedesktop::generate_desktop_file(settings, &settings.rpm().desktop_template, &package_dir)?; + builder = builder.with_file( + desktop_src_path, + FileOptions::new(desktop_dest_path.to_string_lossy()), + )?; + + // Add icons + for (icon, src) in &freedesktop::list_icon_files(settings, &PathBuf::from("/"))? { + builder = builder.with_file(src, FileOptions::new(icon.path.to_string_lossy()))?; + } + + // Add custom files + for (rpm_path, src_path) in settings.rpm().files.iter() { + if src_path.is_file() { + builder = builder.with_file(src_path, FileOptions::new(rpm_path.to_string_lossy()))?; + } else { + for entry in walkdir::WalkDir::new(src_path) { + let entry_path = entry?.into_path(); + if entry_path.is_file() { + let dest_path = rpm_path.join(entry_path.strip_prefix(src_path).unwrap()); + builder = + builder.with_file(&entry_path, FileOptions::new(dest_path.to_string_lossy()))?; + } + } + } + } + + let pkg = if let Ok(raw_secret_key) = env::var("RPM_SIGN_KEY") { + let mut signer = pgp::Signer::load_from_asc(&raw_secret_key)?; + if let Ok(passphrase) = env::var("RPM_SIGN_KEY_PASSPHRASE") { + signer = signer.with_key_passphrase(passphrase); + } + builder.build_and_sign(signer)? + } else { + builder.build()? + }; + + let mut f = fs::File::create(&package_path)?; + pkg.write(&mut f)?; + + Ok(vec![package_path]) } diff --git a/tooling/bundler/src/bundle/settings.rs b/tooling/bundler/src/bundle/settings.rs index 1eed1163f2e7..4331172481a7 100644 --- a/tooling/bundler/src/bundle/settings.rs +++ b/tooling/bundler/src/bundle/settings.rs @@ -44,6 +44,7 @@ impl From for PackageType { fn from(bundle: BundleType) -> Self { match bundle { BundleType::Deb => Self::Deb, + BundleType::Rpm => Self::Rpm, BundleType::AppImage => Self::AppImage, BundleType::Msi => Self::WindowsMsi, BundleType::Nsis => Self::Nsis, @@ -148,6 +149,8 @@ pub struct PackageSettings { pub homepage: Option, /// the package's authors. pub authors: Option>, + /// the package's license. + pub license: Option, /// the default binary to run. pub default_run: Option, } @@ -195,6 +198,31 @@ pub struct DebianSettings { pub changelog: Option, } +/// The RPM bundle settings. +#[derive(Clone, Debug, Default)] +pub struct RpmSettings { + /// The name of the package's license. + pub license: Option, + /// The list of RPM dependencies your application relies on. + pub depends: Option>, + /// The RPM release tag. + pub release: String, + /// The RPM epoch. + pub epoch: u32, + /// List of custom files to add to the RPM package. + /// Maps the path on the RPM 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. #[derive(Clone, Debug, Default)] pub struct MacOsSettings { @@ -426,6 +454,8 @@ pub struct BundleSettings { pub external_bin: Option>, /// Debian-specific settings. pub deb: DebianSettings, + /// Rpm-specific settings. + pub rpm: RpmSettings, /// MacOS-specific settings. pub macos: MacOsSettings, /// Updater configuration. @@ -689,7 +719,7 @@ impl Settings { let mut platform_types = match target_os.as_str() { "macos" => vec![PackageType::MacOsBundle, PackageType::Dmg], "ios" => vec![PackageType::IosBundle], - "linux" => vec![PackageType::Deb, PackageType::AppImage], + "linux" => vec![PackageType::Deb, PackageType::Rpm, PackageType::AppImage], "windows" => vec![PackageType::WindowsMsi, PackageType::Nsis], os => { return Err(crate::Error::GenericError(format!( @@ -827,6 +857,11 @@ impl Settings { } } + /// Returns the package's license. + pub fn license(&self) -> Option<&str> { + self.package.license.as_deref() + } + /// Returns the package's homepage URL, defaulting to "" if not defined. pub fn homepage_url(&self) -> &str { self.package.homepage.as_deref().unwrap_or("") @@ -856,6 +891,11 @@ impl Settings { &self.bundle_settings.deb } + /// Returns the RPM settings. + pub fn rpm(&self) -> &RpmSettings { + &self.bundle_settings.rpm + } + /// Returns the MacOS settings. pub fn macos(&self) -> &MacOsSettings { &self.bundle_settings.macos diff --git a/tooling/bundler/src/error.rs b/tooling/bundler/src/error.rs index ad73de876813..f061d6bc8a61 100644 --- a/tooling/bundler/src/error.rs +++ b/tooling/bundler/src/error.rs @@ -105,6 +105,10 @@ pub enum Error { #[cfg(target_os = "macos")] #[error(transparent)] Plist(#[from] plist::Error), + /// Rpm error. + #[cfg(target_os = "linux")] + #[error("{0}")] + RpmError(#[from] rpm::Error), } /// Convenient type alias of Result type. diff --git a/tooling/bundler/src/lib.rs b/tooling/bundler/src/lib.rs index 057b7f908b7c..92dd13a21fb2 100644 --- a/tooling/bundler/src/lib.rs +++ b/tooling/bundler/src/lib.rs @@ -12,7 +12,7 @@ //! - macOS //! - DMG and App bundles //! - Linux -//! - Appimage and Debian packages +//! - Appimage, Debian and RPM packages //! - Windows //! - MSI using WiX diff --git a/tooling/cli/Cargo.lock b/tooling/cli/Cargo.lock index 727ec34514aa..a8575d7eaa37 100644 --- a/tooling/cli/Cargo.lock +++ b/tooling/cli/Cargo.lock @@ -234,6 +234,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.21.5" @@ -267,6 +273,12 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" +[[package]] +name = "bitfield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" + [[package]] name = "bitflags" version = "1.3.2" @@ -288,6 +300,25 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + [[package]] name = "bstr" version = "1.8.0" @@ -298,6 +329,15 @@ dependencies = [ "serde", ] +[[package]] +name = "buffer-redux" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c9f8ddd22e0a12391d1e7ada69ec3b0da1914f1cec39c5cf977143c5b2854f5" +dependencies = [ + "memchr", +] + [[package]] name = "bumpalo" version = "3.14.0" @@ -349,6 +389,25 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "camellia" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3264e2574e9ef2b53ce6f536dea83a69ac0bc600b762d1523ff83fe07230ce30" +dependencies = [ + "byteorder", + "cipher", +] + +[[package]] +name = "cast5" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b07d673db1ccf000e90f54b819db9e75a8348d6eb056e9b8ab53231b7a9911" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.0.83" @@ -370,6 +429,15 @@ dependencies = [ "uuid", ] +[[package]] +name = "cfb-mode" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738b8d467867f80a71351933f70461f5b56f24d5c93e0cf216e59229c968d330" +dependencies = [ + "cipher", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -384,8 +452,10 @@ checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", "serde", + "wasm-bindgen", "windows-targets 0.48.5", ] @@ -490,6 +560,12 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -527,6 +603,12 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cpio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27e77cfc4543efb4837662cb7cd53464ae66f0fd5c708d71e0f338b1c11d62d3" + [[package]] name = "cpufeatures" version = "0.2.11" @@ -536,6 +618,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crc24" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd121741cf3eb82c08dd3023eb55bf2665e5f60ec20f89760cf836ae4562e6a0" + [[package]] name = "crc32fast" version = "1.3.2" @@ -594,6 +682,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -661,14 +761,66 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core 0.14.4", + "darling_macro 0.14.4", +] + [[package]] name = "darling" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.20.3", + "darling_macro 0.20.3", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", ] [[package]] @@ -685,13 +837,24 @@ dependencies = [ "syn 2.0.52", ] +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core 0.14.4", + "quote", + "syn 1.0.109", +] + [[package]] name = "darling_macro" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ - "darling_core", + "darling_core 0.20.3", "quote", "syn 2.0.52", ] @@ -702,6 +865,17 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.9" @@ -712,6 +886,37 @@ dependencies = [ "serde", ] +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling 0.14.4", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -725,6 +930,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "des" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" +dependencies = [ + "cipher", +] + [[package]] name = "dialoguer" version = "0.11.0" @@ -745,6 +959,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -797,12 +1012,71 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + [[package]] name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "encode_unicode" version = "0.3.6" @@ -818,6 +1092,28 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-display-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ef37b2a9b242295d61a154ee91ae884afff6b8b933b486b12481cc58310ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "enum-primitive-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba7795da175654fe16979af73f81f26a8ea27638d8d9823d317016888a63dc4c" +dependencies = [ + "num-traits", + "quote", + "syn 2.0.52", +] + [[package]] name = "env_logger" version = "0.10.1" @@ -897,6 +1193,22 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "filetime" version = "0.2.22" @@ -925,7 +1237,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ - "spin", + "spin 0.9.8", ] [[package]] @@ -1053,6 +1365,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -1124,6 +1437,17 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "h2" version = "0.3.22" @@ -1202,6 +1526,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -1312,6 +1645,15 @@ dependencies = [ "cc", ] +[[package]] +name = "idea" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "075557004419d7f2031b8bb7f44bb43e55a83ca7b63076a8fb8fe75753836477" +dependencies = [ + "cipher", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1477,6 +1819,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -1569,6 +1920,15 @@ dependencies = [ "uuid", ] +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + [[package]] name = "kqueue" version = "1.0.8" @@ -1607,6 +1967,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] [[package]] name = "lebe" @@ -1630,6 +1993,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libredox" version = "0.0.1" @@ -1675,6 +2044,17 @@ dependencies = [ "value-bag", ] +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "mac" version = "0.1.1" @@ -1707,6 +2087,16 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + [[package]] name = "md5" version = "0.7.0" @@ -1936,6 +2326,24 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "serde", + "smallvec", + "zeroize", +] + [[package]] name = "num-cmp" version = "0.1.0" @@ -1951,6 +2359,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -1991,6 +2410,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -2108,6 +2528,30 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -2164,6 +2608,15 @@ dependencies = [ "hmac", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -2215,6 +2668,58 @@ dependencies = [ "sha2", ] +[[package]] +name = "pgp" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27e1f8e085bfa9b85763fe3ddaacbe90a09cd847b3833129153a6cb063bbe132" +dependencies = [ + "aes", + "base64", + "bitfield", + "block-padding", + "blowfish", + "bstr", + "buffer-redux", + "byteorder", + "camellia", + "cast5", + "cfb-mode", + "chrono", + "cipher", + "crc24", + "curve25519-dalek", + "derive_builder", + "des", + "digest", + "ed25519-dalek", + "elliptic-curve", + "flate2", + "generic-array", + "hex", + "idea", + "log", + "md-5", + "nom", + "num-bigint-dig", + "num-derive", + "num-traits", + "p256", + "p384", + "rand 0.8.5", + "ripemd", + "rsa", + "sha1", + "sha2", + "sha3", + "signature", + "smallvec", + "thiserror", + "twofish", + "x25519-dalek", + "zeroize", +] + [[package]] name = "phf" version = "0.8.0" @@ -2381,12 +2886,39 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "platforms" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" + [[package]] name = "plist" version = "1.6.0" @@ -2444,6 +2976,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -2680,6 +3221,16 @@ dependencies = [ "winreg 0.50.0", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ring" version = "0.17.6" @@ -2689,11 +3240,20 @@ dependencies = [ "cc", "getrandom 0.2.11", "libc", - "spin", + "spin 0.9.8", "untrusted", "windows-sys 0.48.0", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest", +] + [[package]] name = "rpassword" version = "7.3.1" @@ -2705,6 +3265,56 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rpm" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a681f5d3dc43f62b636c8e2d0b709e85673cf12eb036cde5a48b26e930a6777" +dependencies = [ + "bitflags 2.4.1", + "bzip2", + "chrono", + "cpio", + "digest", + "enum-display-derive", + "enum-primitive-derive", + "flate2", + "hex", + "itertools 0.12.1", + "log", + "md-5", + "nom", + "num", + "num-derive", + "num-traits", + "pgp", + "sha1", + "sha2", + "thiserror", + "xz2", + "zstd 0.13.1", +] + +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rtoolbox" version = "0.0.2" @@ -2862,6 +3472,20 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "security-framework" version = "2.9.2" @@ -3026,7 +3650,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" dependencies = [ - "darling", + "darling 0.20.3", "proc-macro2", "quote", "syn 2.0.52", @@ -3092,6 +3716,16 @@ dependencies = [ "digest", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "shared_child" version = "1.0.0" @@ -3108,6 +3742,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -3166,6 +3810,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spin" version = "0.9.8" @@ -3175,6 +3825,16 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -3367,6 +4027,7 @@ dependencies = [ "os_pipe", "plist", "regex", + "rpm", "semver", "serde", "serde_json", @@ -3409,7 +4070,7 @@ dependencies = [ "ignore", "image", "include_dir", - "itertools", + "itertools 0.11.0", "json-patch", "jsonschema", "kuchikiki", @@ -3801,6 +4462,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "twofish" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78e83a30223c757c3947cd144a31014ff04298d8719ae10d03c31c0448c8013" +dependencies = [ + "cipher", +] + [[package]] name = "typenum" version = "1.17.0" @@ -4357,6 +5027,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core 0.6.4", + "serde", + "zeroize", +] + [[package]] name = "xattr" version = "1.0.1" @@ -4366,6 +5048,15 @@ dependencies = [ "libc", ] +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + [[package]] name = "zerocopy" version = "0.7.27" @@ -4391,6 +5082,20 @@ name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] [[package]] name = "zip" @@ -4409,7 +5114,7 @@ dependencies = [ "pbkdf2 0.11.0", "sha1", "time", - "zstd", + "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -4418,7 +5123,16 @@ version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ - "zstd-safe", + "zstd-safe 5.0.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" +dependencies = [ + "zstd-safe 7.1.0", ] [[package]] @@ -4431,11 +5145,20 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "zstd-safe" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" +dependencies = [ + "zstd-sys", +] + [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.10+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" dependencies = [ "cc", "pkg-config", diff --git a/tooling/cli/ENVIRONMENT_VARIABLES.md b/tooling/cli/ENVIRONMENT_VARIABLES.md index f065e79d8536..b5d011e6ddc7 100644 --- a/tooling/cli/ENVIRONMENT_VARIABLES.md +++ b/tooling/cli/ENVIRONMENT_VARIABLES.md @@ -33,6 +33,8 @@ These environment variables are inputs to the CLI which may have an equivalent C - `APPLE_SIGNING_IDENTITY` — The identity used to code sign. Overwrites `tauri.conf.json > tauri > bundle > macOS > signingIdentity`. - `APPLE_PROVIDER_SHORT_NAME` — If your Apple ID is connected to multiple teams, you have to specify the provider short name of the team you want to use to notarize your app. Overwrites `tauri.conf.json > tauri > bundle > macOS > providerShortName`. - `CI` — If set, the CLI will run in CI mode and won't require any user interaction. +- `RPM_SIGN_KEY` — The private GPG key used to sign the RPM bundle, exported to its ASCII-armored format. +- `RPM_SIGN_KEY_PASSPHRASE` — The GPG key passphrase for `RPM_SIGN_KEY`, if needed. ### Tauri CLI Hook Commands diff --git a/tooling/cli/schema.json b/tooling/cli/schema.json index 3ad96747ea7f..8ad752c5e2c7 100644 --- a/tooling/cli/schema.json +++ b/tooling/cli/schema.json @@ -144,6 +144,11 @@ "macOS": { "minimumSystemVersion": "10.13" }, + "rpm": { + "epoch": 0, + "files": {}, + "release": "1" + }, "targets": "all", "windows": { "allowDowngrades": true, @@ -283,6 +288,11 @@ "macOS": { "minimumSystemVersion": "10.13" }, + "rpm": { + "epoch": 0, + "files": {}, + "release": "1" + }, "targets": "all", "windows": { "allowDowngrades": true, @@ -1046,7 +1056,7 @@ "type": "boolean" }, "targets": { - "description": "The bundle targets, currently supports [\"deb\", \"appimage\", \"nsis\", \"msi\", \"app\", \"dmg\", \"updater\"] or \"all\".", + "description": "The bundle targets, currently supports [\"deb\", \"rpm\", \"appimage\", \"nsis\", \"msi\", \"app\", \"dmg\", \"updater\"] or \"all\".", "default": "all", "allOf": [ { @@ -1134,6 +1144,19 @@ } ] }, + "rpm": { + "description": "Configuration for the RPM bundle.", + "default": { + "epoch": 0, + "files": {}, + "release": "1" + }, + "allOf": [ + { + "$ref": "#/definitions/RpmConfig" + } + ] + }, "macOS": { "description": "Configuration for the macOS bundles.", "default": { @@ -1216,6 +1239,13 @@ "deb" ] }, + { + "description": "The RPM bundle (.rpm).", + "type": "string", + "enum": [ + "rpm" + ] + }, { "description": "The AppImage bundle (.appimage).", "type": "string", @@ -1344,6 +1374,57 @@ }, "additionalProperties": false }, + "RpmConfig": { + "description": "Configuration for RPM bundles.", + "type": "object", + "properties": { + "license": { + "description": "The package's license identifier. If not set, defaults to the license from the Cargo.toml file.", + "type": [ + "string", + "null" + ] + }, + "depends": { + "description": "The list of RPM dependencies your application relies on.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "release": { + "description": "The RPM release tag.", + "default": "1", + "type": "string" + }, + "epoch": { + "description": "The RPM epoch.", + "default": 0, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "files": { + "description": "The files to include on the package.", + "default": {}, + "type": "object", + "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 + }, "MacConfig": { "description": "Configuration for the macOS bundles.\n\nSee more: https://tauri.app/v1/api/config#macconfig", "type": "object", diff --git a/tooling/cli/src/build.rs b/tooling/cli/src/build.rs index dc961006014c..7eca16ea1142 100644 --- a/tooling/cli/src/build.rs +++ b/tooling/cli/src/build.rs @@ -44,7 +44,7 @@ pub struct Options { pub features: Option>, /// Space or comma separated list of bundles to package. /// - /// Each bundle must be one of `deb`, `appimage`, `msi`, `app` or `dmg` on MacOS and `updater` on all platforms. + /// Each bundle must be one of `deb`, `rpm`, `appimage`, `msi`, `app` or `dmg` on MacOS and `updater` on all platforms. /// If `none` is specified, the bundler will be skipped. /// /// Note that the `updater` bundle is not automatically added so you must specify it if the updater is enabled. diff --git a/tooling/cli/src/interface/rust.rs b/tooling/cli/src/interface/rust.rs index 6f1e6427ddac..6ee5de4aee25 100644 --- a/tooling/cli/src/interface/rust.rs +++ b/tooling/cli/src/interface/rust.rs @@ -29,7 +29,7 @@ use serde::Deserialize; use shared_child::SharedChild; use tauri_bundler::{ AppCategory, BundleBinary, BundleSettings, DebianSettings, MacOsSettings, PackageSettings, - UpdaterSettings, WindowsSettings, + RpmSettings, UpdaterSettings, WindowsSettings, }; use tauri_utils::config::parse::is_configuration_file; @@ -629,6 +629,8 @@ pub struct CargoPackageSettings { pub homepage: Option>, /// the package's authors. pub authors: Option>>, + /// the package's license. + pub license: Option, /// the default binary to run. pub default_run: Option, } @@ -682,12 +684,16 @@ impl AppSettings for RustAppSettings { config: &Config, features: &[String], ) -> crate::Result { + let arch64bits = + self.target_triple.starts_with("x86_64") || self.target_triple.starts_with("aarch64"); + tauri_config_to_bundle_settings( &self.manifest, features, config.tauri.bundle.clone(), config.tauri.system_tray.clone(), config.tauri.updater.clone(), + arch64bits, ) } @@ -904,6 +910,7 @@ impl RustAppSettings { }) .unwrap() }), + license: cargo_package_settings.license.clone(), default_run: cargo_package_settings.default_run.clone(), }; @@ -1024,6 +1031,7 @@ fn tauri_config_to_bundle_settings( config: crate::helpers::config::BundleConfig, system_tray_config: Option, updater_config: crate::helpers::config::UpdaterConfig, + arch64bits: bool, ) -> crate::Result { let enabled_features = manifest.all_enabled_features(features); @@ -1044,22 +1052,38 @@ fn tauri_config_to_bundle_settings( .resources .unwrap_or(BundleResources::List(Vec::new())); #[allow(unused_mut)] - let mut depends = config.deb.depends.unwrap_or_default(); + let mut depends_deb = config.deb.depends.unwrap_or_default(); + #[allow(unused_mut)] + let mut depends_rpm = config.rpm.depends.unwrap_or_default(); #[cfg(target_os = "linux")] { + let mut libs: Vec = Vec::new(); + if let Some(system_tray_config) = &system_tray_config { let tray = std::env::var("TAURI_TRAY").unwrap_or_else(|_| "ayatana".to_string()); if tray == "ayatana" { - depends.push("libayatana-appindicator3-1".into()); + depends_deb.push("libayatana-appindicator3-1".into()); } else { - depends.push("libappindicator3-1".into()); + depends_deb.push("libappindicator3-1".into()); + libs.push("libappindicator3.so.1".into()); } } // provides `libwebkit2gtk-4.0.so.37` and all `4.0` versions have the -37 package name - depends.push("libwebkit2gtk-4.0-37".to_string()); - depends.push("libgtk-3-0".to_string()); + depends_deb.push("libwebkit2gtk-4.0-37".to_string()); + depends_deb.push("libgtk-3-0".to_string()); + + libs.push("libwebkit2gtk-4.0.so.37".into()); + libs.push("libgtk-3.so.0".into()); + + for lib in libs { + let mut requires = lib; + if arch64bits { + requires.push_str("()(64bit)"); + } + depends_rpm.push(requires); + } } #[cfg(windows)] @@ -1116,10 +1140,10 @@ fn tauri_config_to_bundle_settings( long_description: config.long_description, external_bin: config.external_bin, deb: DebianSettings { - depends: if depends.is_empty() { + depends: if depends_deb.is_empty() { None } else { - Some(depends) + Some(depends_deb) }, files: config.deb.files, desktop_template: config.deb.desktop_template, @@ -1127,6 +1151,18 @@ fn tauri_config_to_bundle_settings( priority: config.deb.priority, changelog: config.deb.changelog, }, + rpm: RpmSettings { + license: config.rpm.license, + depends: if depends_rpm.is_empty() { + None + } else { + Some(depends_rpm) + }, + release: config.rpm.release, + epoch: config.rpm.epoch, + files: config.rpm.files, + desktop_template: config.rpm.desktop_template, + }, macos: MacOsSettings { frameworks: config.macos.frameworks, minimum_system_version: config.macos.minimum_system_version,