mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-02-06 11:22:04 +00:00
* feat(core): add config for Info.plist extensions, closes #13667 * add missing tag * do not lie :)
This commit is contained in:
parent
abf7e8850b
commit
ed7c9a4100
8
.changes/info-plist-config.md
Normal file
8
.changes/info-plist-config.md
Normal file
@ -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/refactor-info-plist.md
Normal file
5
.changes/refactor-info-plist.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri-bundler": minor:breaking
|
||||
---
|
||||
|
||||
Changed `MacOsSettings::info_plist_path` to `MacOsSettings::info_plist`.
|
||||
@ -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 {
|
||||
|
||||
@ -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"
|
||||
@ -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]
|
||||
|
||||
@ -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};
|
||||
|
||||
@ -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,
|
||||
@ -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);
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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": {
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
42
crates/tauri-cli/src/helpers/plist.rs
Normal file
42
crates/tauri-cli/src/helpers/plist.rs
Normal file
@ -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))
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
@ -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,
|
||||
@ -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},
|
||||
@ -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)
|
||||
@ -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(),
|
||||
])?;
|
||||
|
||||
@ -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,
|
||||
@ -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::{
|
||||
@ -218,11 +219,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)
|
||||
|
||||
@ -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>,
|
||||
|
||||
@ -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": {
|
||||
@ -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
|
||||
|
||||
@ -664,6 +664,11 @@ pub struct MacConfig {
|
||||
pub provider_short_name: Option<String>,
|
||||
/// Path to the entitlements file.
|
||||
pub entitlements: Option<String>,
|
||||
/// Path to a Info.plist file to merge with the default Info.plist.
|
||||
///
|
||||
/// Note that Tauri also looks for a `Info.plist` file in the same directory as the Tauri configuration file.
|
||||
#[serde(alias = "info-plist")]
|
||||
pub info_plist: Option<PathBuf>,
|
||||
/// DMG-specific settings.
|
||||
#[serde(default)]
|
||||
pub dmg: DmgConfig,
|
||||
@ -682,6 +687,7 @@ impl Default for MacConfig {
|
||||
hardened_runtime: true,
|
||||
provider_short_name: None,
|
||||
entitlements: None,
|
||||
info_plist: None,
|
||||
dmg: Default::default(),
|
||||
}
|
||||
}
|
||||
@ -2850,6 +2856,11 @@ pub struct IosConfig {
|
||||
default = "ios_minimum_system_version"
|
||||
)]
|
||||
pub minimum_system_version: String,
|
||||
/// Path to a Info.plist file to merge with the default Info.plist.
|
||||
///
|
||||
/// Note that Tauri also looks for a `Info.plist` and `Info.ios.plist` file in the same directory as the Tauri configuration file.
|
||||
#[serde(alias = "info-plist")]
|
||||
pub info_plist: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Default for IosConfig {
|
||||
@ -2860,6 +2871,7 @@ impl Default for IosConfig {
|
||||
development_team: None,
|
||||
bundle_version: None,
|
||||
minimum_system_version: ios_minimum_system_version(),
|
||||
info_plist: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user