Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changes/info-plist-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"tauri-utils": minor:feat
"tauri-cli": minor:feat
"@tauri-apps/cli": minor:feat
---

Added `bundle > macOS > infoPlist` and `bundle > iOS > infoPlist` configurations to allow defining custom Info.plist extensions.

5 changes: 5 additions & 0 deletions .changes/refactor-info-plist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-bundler": minor:breaking
---

Changed `MacOsSettings::info_plist_path` to `MacOsSettings::info_plist`.
7 changes: 7 additions & 0 deletions crates/tauri-build/src/codegen/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ impl CodegenContext {
if info_plist_path.exists() {
println!("cargo:rerun-if-changed={}", info_plist_path.display());
}

if let Some(plist_path) = &config.bundle.macos.info_plist {
let info_plist_path = config_parent.join(plist_path);
if info_plist_path.exists() {
println!("cargo:rerun-if-changed={}", info_plist_path.display());
}
}
}

let code = context_codegen(ContextData {
Expand Down
2 changes: 1 addition & 1 deletion crates/tauri-bundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ url = "2"
uuid = { version = "1", features = ["v4", "v5"] }
regex = "1"
goblin = "0.9"
plist = "1"

[target."cfg(target_os = \"windows\")".dependencies]
bitness = "0.4"
Expand All @@ -57,7 +58,6 @@ features = ["Win32_System_SystemInformation", "Win32_System_Diagnostics_Debug"]
[target."cfg(target_os = \"macos\")".dependencies]
icns = { package = "tauri-icns", version = "0.1" }
time = { version = "0.3", features = ["formatting"] }
plist = "1"
tauri-macos-sign = { version = "2.2.0", path = "../tauri-macos-sign" }

[target."cfg(target_os = \"linux\")".dependencies]
Expand Down
4 changes: 2 additions & 2 deletions crates/tauri-bundler/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ pub use self::{
category::AppCategory,
settings::{
AppImageSettings, BundleBinary, BundleSettings, CustomSignCommandSettings, DebianSettings,
DmgSettings, IosSettings, MacOsSettings, PackageSettings, PackageType, Position, RpmSettings,
Settings, SettingsBuilder, Size, UpdaterSettings,
DmgSettings, IosSettings, MacOsSettings, PackageSettings, PackageType, PlistKind, Position,
RpmSettings, Settings, SettingsBuilder, Size, UpdaterSettings,
},
};
pub use settings::{NsisSettings, WindowsSettings, WixLanguage, WixLanguageConfig, WixSettings};
Expand Down
8 changes: 6 additions & 2 deletions crates/tauri-bundler/src/bundle/macos/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use super::{
sign::{notarize, notarize_auth, notarize_without_stapling, sign, SignTarget},
};
use crate::{
bundle::settings::PlistKind,
error::{Context, ErrorExt, NotarizeAuthError},
utils::{fs_utils, CommandExt},
Error::GenericError,
Expand Down Expand Up @@ -361,8 +362,11 @@ fn create_info_plist(
plist.insert("NSAppTransportSecurity".into(), security.into());
}

if let Some(user_plist_path) = &settings.macos().info_plist_path {
let user_plist = plist::Value::from_file(user_plist_path)?;
if let Some(user_plist) = &settings.macos().info_plist {
let user_plist = match user_plist {
PlistKind::Path(path) => plist::Value::from_file(path)?,
PlistKind::Plist(value) => value.clone(),
};
if let Some(dict) = user_plist.into_dictionary() {
for (key, value) in dict {
plist.insert(key, value);
Expand Down
13 changes: 11 additions & 2 deletions crates/tauri-bundler/src/bundle/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,17 @@ pub struct MacOsSettings {
pub provider_short_name: Option<String>,
/// Path to the entitlements.plist file.
pub entitlements: Option<String>,
/// Path to the Info.plist file for the bundle.
pub info_plist_path: Option<PathBuf>,
/// Path to the Info.plist file or raw plist value to merge with the bundle Info.plist.
pub info_plist: Option<PlistKind>,
}

/// Plist format.
#[derive(Debug, Clone)]
pub enum PlistKind {
/// Path to a .plist file.
Path(PathBuf),
/// Raw plist value.
Plist(plist::Value),
}

/// Configuration for a target language for the WiX build.
Expand Down
14 changes: 14 additions & 0 deletions crates/tauri-cli/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3572,6 +3572,13 @@
"null"
]
},
"infoPlist": {
"description": "Path to a Info.plist file to merge with the default Info.plist.\n\n Note that Tauri also looks for a `Info.plist` file in the same directory as the Tauri configuration file.",
"type": [
"string",
"null"
]
},
"dmg": {
"description": "DMG-specific settings.",
"default": {
Expand Down Expand Up @@ -3743,6 +3750,13 @@
"description": "A version string indicating the minimum iOS version that the bundled application supports. Defaults to `13.0`.\n\n Maps to the IPHONEOS_DEPLOYMENT_TARGET value.",
"default": "14.0",
"type": "string"
},
"infoPlist": {
"description": "Path to a Info.plist file to merge with the default Info.plist.\n\n Note that Tauri also looks for a `Info.plist` and `Info.ios.plist` file in the same directory as the Tauri configuration file.",
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
Expand Down
2 changes: 2 additions & 0 deletions crates/tauri-cli/src/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub mod http;
pub mod npm;
#[cfg(target_os = "macos")]
pub mod pbxproj;
#[cfg(target_os = "macos")]
pub mod plist;
pub mod plugins;
pub mod prompts;
pub mod template;
Expand Down
42 changes: 42 additions & 0 deletions crates/tauri-cli/src/helpers/plist.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use std::path::PathBuf;

use crate::error::Context;

pub enum PlistKind {
Path(PathBuf),
Plist(plist::Value),
}

impl From<PathBuf> for PlistKind {
fn from(p: PathBuf) -> Self {
Self::Path(p)
}
}
impl From<plist::Value> for PlistKind {
fn from(p: plist::Value) -> Self {
Self::Plist(p)
}
}

pub fn merge_plist(src: Vec<PlistKind>) -> crate::Result<plist::Value> {
let mut merged_plist = plist::Dictionary::new();

for plist_kind in src {
let src_plist = match plist_kind {
PlistKind::Path(p) => plist::Value::from_file(&p)
.with_context(|| format!("failed to parse plist from {}", p.display()))?,
PlistKind::Plist(v) => v,
};
if let Some(dict) = src_plist.into_dictionary() {
for (key, value) in dict {
merged_plist.insert(key, value);
}
}
}

Ok(plist::Value::Dictionary(merged_plist))
}
18 changes: 14 additions & 4 deletions crates/tauri-cli/src/interface/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1488,13 +1488,23 @@ fn tauri_config_to_bundle_settings(
hardened_runtime: config.macos.hardened_runtime,
provider_short_name,
entitlements: config.macos.entitlements,
info_plist_path: {
#[cfg(not(target_os = "macos"))]
info_plist: None,
#[cfg(target_os = "macos")]
info_plist: {
let mut src_plists = vec![];

let path = tauri_dir().join("Info.plist");
if path.exists() {
Some(path)
} else {
None
src_plists.push(path.into());
}
if let Some(info_plist) = &config.macos.info_plist {
src_plists.push(info_plist.clone().into());
}

Some(tauri_bundler::bundle::PlistKind::Plist(
crate::helpers::plist::merge_plist(src_plists)?,
))
},
},
windows: WindowsSettings {
Expand Down
32 changes: 23 additions & 9 deletions crates/tauri-cli/src/mobile/ios/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

use super::{
detect_target_ok, ensure_init, env, get_app, get_config, inject_resources, load_pbxproj,
log_finished, merge_plist, open_and_wait, project_config, synchronize_project_config,
MobileTarget, OptionsHandle,
log_finished, open_and_wait, project_config, synchronize_project_config, MobileTarget,
OptionsHandle,
};
use crate::{
build::Options as BuildOptions,
Expand All @@ -14,6 +14,7 @@ use crate::{
app_paths::tauri_dir,
config::{get as get_tauri_config, ConfigHandle},
flock,
plist::merge_plist,
},
interface::{AppInterface, Interface, Options as InterfaceOptions},
mobile::{ios::ensure_ios_runtime_installed, write_options, CliOptions},
Expand Down Expand Up @@ -215,12 +216,26 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
.project_dir()
.join(config.scheme())
.join("Info.plist");
let merged_info_plist = merge_plist(vec![
info_plist_path.clone().into(),
tauri_path.join("Info.plist").into(),
tauri_path.join("Info.ios.plist").into(),
plist::Value::Dictionary(plist).into(),
])?;
let mut src_plists = vec![info_plist_path.clone().into()];
src_plists.push(plist::Value::Dictionary(plist).into());
if tauri_path.join("Info.plist").exists() {
src_plists.push(tauri_path.join("Info.plist").into());
}
if tauri_path.join("Info.ios.plist").exists() {
src_plists.push(tauri_path.join("Info.ios.plist").into());
}
if let Some(info_plist) = &tauri_config
.lock()
.unwrap()
.as_ref()
.unwrap()
.bundle
.ios
.info_plist
{
src_plists.push(info_plist.clone().into());
}
let merged_info_plist = merge_plist(src_plists)?;
merged_info_plist
.to_file_xml(&info_plist_path)
.map_err(std::io::Error::other)
Expand Down Expand Up @@ -283,7 +298,6 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
tempfile::NamedTempFile::new().context("failed to create temporary file")?;

let merged_plist = merge_plist(vec![
export_options.path().to_owned().into(),
export_options_plist_path.clone().into(),
plist::Value::from(export_options_plist).into(),
])?;
Expand Down
27 changes: 21 additions & 6 deletions crates/tauri-cli/src/mobile/ios/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use super::{
device_prompt, ensure_init, env, get_app, get_config, inject_resources, load_pbxproj,
merge_plist, open_and_wait, synchronize_project_config, MobileTarget, ProjectConfig,
open_and_wait, synchronize_project_config, MobileTarget, ProjectConfig,
};
use crate::{
dev::Options as DevOptions,
Expand All @@ -13,6 +13,7 @@ use crate::{
app_paths::tauri_dir,
config::{get as get_tauri_config, ConfigHandle},
flock,
plist::merge_plist,
},
interface::{AppInterface, Interface, MobileOptions, Options as InterfaceOptions},
mobile::{
Expand Down Expand Up @@ -217,11 +218,25 @@ fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
.project_dir()
.join(config.scheme())
.join("Info.plist");
let merged_info_plist = merge_plist(vec![
info_plist_path.clone().into(),
tauri_path.join("Info.plist").into(),
tauri_path.join("Info.ios.plist").into(),
])?;
let mut src_plists = vec![info_plist_path.clone().into()];
if tauri_path.join("Info.plist").exists() {
src_plists.push(tauri_path.join("Info.plist").into());
}
if tauri_path.join("Info.ios.plist").exists() {
src_plists.push(tauri_path.join("Info.ios.plist").into());
}
if let Some(info_plist) = &tauri_config
.lock()
.unwrap()
.as_ref()
.unwrap()
.bundle
.ios
.info_plist
{
src_plists.push(info_plist.clone().into());
}
let merged_info_plist = merge_plist(src_plists)?;
merged_info_plist
.to_file_xml(&info_plist_path)
.map_err(std::io::Error::other)
Expand Down
36 changes: 0 additions & 36 deletions crates/tauri-cli/src/mobile/ios/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,42 +488,6 @@ fn inject_resources(config: &AppleConfig, tauri_config: &TauriConfig) -> Result<
Ok(())
}

enum PlistKind {
Path(PathBuf),
Plist(plist::Value),
}

impl From<PathBuf> for PlistKind {
fn from(p: PathBuf) -> Self {
Self::Path(p)
}
}
impl From<plist::Value> for PlistKind {
fn from(p: plist::Value) -> Self {
Self::Plist(p)
}
}

fn merge_plist(src: Vec<PlistKind>) -> Result<plist::Value> {
let mut merged_plist = plist::Dictionary::new();

for plist_kind in src {
let plist = match plist_kind {
PlistKind::Path(p) => plist::Value::from_file(p).context("failed to read plist file"),
PlistKind::Plist(v) => Ok(v),
};
if let Ok(src_plist) = plist {
if let Some(dict) = src_plist.into_dictionary() {
for (key, value) in dict {
merged_plist.insert(key, value);
}
}
}
}

Ok(plist::Value::Dictionary(merged_plist))
}

pub fn signing_from_env() -> Result<(
Option<tauri_macos_sign::Keychain>,
Option<tauri_macos_sign::ProvisioningProfile>,
Expand Down
14 changes: 14 additions & 0 deletions crates/tauri-schema-generator/schemas/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3572,6 +3572,13 @@
"null"
]
},
"infoPlist": {
"description": "Path to a Info.plist file to merge with the default Info.plist.\n\n Note that Tauri also looks for a `Info.plist` file in the same directory as the Tauri configuration file.",
"type": [
"string",
"null"
]
},
"dmg": {
"description": "DMG-specific settings.",
"default": {
Expand Down Expand Up @@ -3743,6 +3750,13 @@
"description": "A version string indicating the minimum iOS version that the bundled application supports. Defaults to `13.0`.\n\n Maps to the IPHONEOS_DEPLOYMENT_TARGET value.",
"default": "14.0",
"type": "string"
},
"infoPlist": {
"description": "Path to a Info.plist file to merge with the default Info.plist.\n\n Note that Tauri also looks for a `Info.plist` and `Info.ios.plist` file in the same directory as the Tauri configuration file.",
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
Expand Down
Loading
Loading