Skip to content

Commit 45076b3

Browse files
authored
refactor(bundler): use the plist crate to create and merge Info.plist (#4412)
1 parent 079b1cc commit 45076b3

File tree

7 files changed

+106
-116
lines changed

7 files changed

+106
-116
lines changed

.changes/refactor-bundler-plist.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-bundler": patch
3+
---
4+
5+
Use the plist crate instead of the `PlistBuddy` binary to merge user Info.plist file.

tooling/bundler/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ zip = "0.6"
5151
[target."cfg(target_os = \"macos\")".dependencies]
5252
icns = "0.3"
5353
time = { version = "0.3", features = [ "formatting" ] }
54+
plist = "1"
5455

5556
[target."cfg(any(target_os = \"macos\", target_os = \"windows\"))".dependencies]
5657
regex = "1"

tooling/bundler/src/bundle/macos/app.rs

Lines changed: 57 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,14 @@ use super::{
2626
icon::create_icns_file,
2727
sign::{notarize, notarize_auth_args, sign},
2828
};
29-
use crate::{bundle::common::CommandExt, Settings};
29+
use crate::Settings;
3030

3131
use anyhow::Context;
3232
use log::{info, warn};
3333

3434
use std::{
3535
fs,
36-
io::prelude::*,
3736
path::{Path, PathBuf},
38-
process::Command,
3937
};
4038

4139
/// Bundles the project.
@@ -124,130 +122,75 @@ fn create_info_plist(
124122
.format(&format)
125123
.map_err(time::error::Error::from)?;
126124

127-
let bundle_plist_path = bundle_dir.join("Info.plist");
128-
let file = &mut common::create_file(&bundle_plist_path)?;
129-
write!(
130-
file,
131-
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
132-
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \
133-
\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\
134-
<plist version=\"1.0\">\n\
135-
<dict>\n"
136-
)?;
137-
write!(
138-
file,
139-
" <key>CFBundleDevelopmentRegion</key>\n \
140-
<string>English</string>\n"
141-
)?;
142-
write!(
143-
file,
144-
" <key>CFBundleDisplayName</key>\n <string>{}</string>\n",
145-
settings.product_name()
146-
)?;
147-
write!(
148-
file,
149-
" <key>CFBundleExecutable</key>\n <string>{}</string>\n",
150-
settings.main_binary_name()
151-
)?;
125+
let mut plist = plist::Dictionary::new();
126+
plist.insert("CFBundleDevelopmentRegion".into(), "English".into());
127+
plist.insert("CFBundleDisplayName".into(), settings.product_name().into());
128+
plist.insert(
129+
"CFBundleExecutable".into(),
130+
settings.main_binary_name().into(),
131+
);
152132
if let Some(path) = bundle_icon_file {
153-
write!(
154-
file,
155-
" <key>CFBundleIconFile</key>\n <string>{}</string>\n",
156-
path.file_name().expect("No file name").to_string_lossy()
157-
)?;
133+
plist.insert(
134+
"CFBundleIconFile".into(),
135+
path
136+
.file_name()
137+
.expect("No file name")
138+
.to_string_lossy()
139+
.into_owned()
140+
.into(),
141+
);
158142
}
159-
write!(
160-
file,
161-
" <key>CFBundleIdentifier</key>\n <string>{}</string>\n",
162-
settings.bundle_identifier()
163-
)?;
164-
write!(
165-
file,
166-
" <key>CFBundleInfoDictionaryVersion</key>\n \
167-
<string>6.0</string>\n"
168-
)?;
169-
write!(
170-
file,
171-
" <key>CFBundleName</key>\n <string>{}</string>\n",
172-
settings.product_name()
173-
)?;
174-
write!(
175-
file,
176-
" <key>CFBundlePackageType</key>\n <string>APPL</string>\n"
177-
)?;
178-
write!(
179-
file,
180-
" <key>CFBundleShortVersionString</key>\n <string>{}</string>\n",
181-
settings.version_string()
182-
)?;
183-
write!(
184-
file,
185-
" <key>CFBundleVersion</key>\n <string>{}</string>\n",
186-
build_number
187-
)?;
188-
write!(file, " <key>CSResourcesFileMapped</key>\n <true/>\n")?;
143+
plist.insert(
144+
"CFBundleIdentifier".into(),
145+
settings.bundle_identifier().into(),
146+
);
147+
plist.insert("CFBundleInfoDictionaryVersion".into(), "6.0".into());
148+
plist.insert("CFBundleName".into(), settings.product_name().into());
149+
plist.insert("CFBundlePackageType".into(), "APPL".into());
150+
plist.insert(
151+
"CFBundleShortVersionString".into(),
152+
settings.version_string().into(),
153+
);
154+
plist.insert("CFBundleVersion".into(), build_number.into());
155+
plist.insert("CSResourcesFileMapped".into(), true.into());
189156
if let Some(category) = settings.app_category() {
190-
write!(
191-
file,
192-
" <key>LSApplicationCategoryType</key>\n \
193-
<string>{}</string>\n",
194-
category.macos_application_category_type()
195-
)?;
157+
plist.insert(
158+
"LSApplicationCategoryType".into(),
159+
category.macos_application_category_type().into(),
160+
);
196161
}
197-
if let Some(version) = &settings.macos().minimum_system_version {
198-
write!(
199-
file,
200-
" <key>LSMinimumSystemVersion</key>\n \
201-
<string>{}</string>\n",
202-
version
203-
)?;
162+
if let Some(version) = settings.macos().minimum_system_version.clone() {
163+
plist.insert("LSMinimumSystemVersion".into(), version.into());
204164
}
205-
write!(file, " <key>LSRequiresCarbon</key>\n <true/>\n")?;
206-
write!(file, " <key>NSHighResolutionCapable</key>\n <true/>\n")?;
165+
plist.insert("LSRequiresCarbon".into(), true.into());
166+
plist.insert("NSHighResolutionCapable".into(), true.into());
207167
if let Some(copyright) = settings.copyright_string() {
208-
write!(
209-
file,
210-
" <key>NSHumanReadableCopyright</key>\n \
211-
<string>{}</string>\n",
212-
copyright
213-
)?;
168+
plist.insert("NSHumanReadableCopyright".into(), copyright.into());
214169
}
215170

216-
if let Some(exception_domain) = &settings.macos().exception_domain {
217-
write!(
218-
file,
219-
" <key>NSAppTransportSecurity</key>\n \
220-
<dict>\n \
221-
<key>NSExceptionDomains</key>\n \
222-
<dict>\n \
223-
<key>{}</key>\n \
224-
<dict>\n \
225-
<key>NSExceptionAllowsInsecureHTTPLoads</key>\n \
226-
<true/>\n \
227-
<key>NSIncludesSubdomains</key>\n \
228-
<true/>\n \
229-
</dict>\n \
230-
</dict>\n \
231-
</dict>",
232-
exception_domain
233-
)?;
234-
}
171+
if let Some(exception_domain) = settings.macos().exception_domain.clone() {
172+
let mut security = plist::Dictionary::new();
173+
let mut domain = plist::Dictionary::new();
174+
domain.insert("NSExceptionAllowsInsecureHTTPLoads".into(), true.into());
175+
domain.insert("NSIncludesSubdomains".into(), true.into());
235176

236-
write!(file, "</dict>\n</plist>\n")?;
237-
file.flush()?;
177+
let mut exception_domains = plist::Dictionary::new();
178+
exception_domains.insert(exception_domain, domain.into());
179+
security.insert("NSExceptionDomains".into(), exception_domains.into());
180+
plist.insert("NSAppTransportSecurity".into(), security.into());
181+
}
238182

239183
if let Some(user_plist_path) = &settings.macos().info_plist_path {
240-
// TODO: use the plist crate instead
241-
Command::new("/usr/libexec/PlistBuddy")
242-
.args(&[
243-
"-c".into(),
244-
format!("Merge {}", user_plist_path.display()),
245-
bundle_plist_path.display().to_string(),
246-
])
247-
.output_ok()
248-
.context("error running PlistBuddy")?;
184+
let user_plist = plist::Value::from_file(user_plist_path)?;
185+
if let Some(dict) = user_plist.into_dictionary() {
186+
for (key, value) in dict {
187+
plist.insert(key, value);
188+
}
189+
}
249190
}
250191

192+
plist::Value::Dictionary(plist).to_file_xml(bundle_dir.join("Info.plist"))?;
193+
251194
Ok(())
252195
}
253196

tooling/bundler/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ pub enum Error {
106106
#[cfg(target_os = "macos")]
107107
#[error("`{0}`")]
108108
TimeError(#[from] time::error::Error),
109+
/// Plist error.
110+
#[cfg(target_os = "macos")]
111+
#[error(transparent)]
112+
Plist(#[from] plist::Error),
109113
}
110114

111115
/// Convenient type alias of Result type.

tooling/cli/Cargo.lock

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tooling/cli/schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@
607607
"type": "boolean"
608608
},
609609
"theme": {
610-
"description": "The initial window theme. Defaults to the system theme. Only implemented on Windows and macOs 10.14+.",
610+
"description": "The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+.",
611611
"anyOf": [
612612
{
613613
"$ref": "#/definitions/Theme"

tooling/cli/src/build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use crate::helpers::{
66
app_paths::{app_dir, tauri_dir},
77
command_env,
8-
config::{get as get_config, AppUrl, ShellAllowlistOpen, WindowUrl},
8+
config::{get as get_config, AppUrl, WindowUrl},
99
manifest::rewrite_manifest,
1010
updater_signature::sign_file_from_env_variables,
1111
};
@@ -314,6 +314,7 @@ pub fn command(options: Options) -> Result<()> {
314314
// set env vars used by the bundler
315315
#[cfg(target_os = "linux")]
316316
{
317+
use crate::helpers::config::ShellAllowlistOpen;
317318
if matches!(
318319
config_.tauri.allowlist.shell.open,
319320
ShellAllowlistOpen::Flag(true) | ShellAllowlistOpen::Validate(_)

0 commit comments

Comments
 (0)