Skip to content

Commit 1b6b2fd

Browse files
committed
fix: don't try to parse inexistent icons
When Tauri is explicitly configured to use no icons via: "bundle": { "icon": [] } It still tries to compile icons in a fallback path of `icons/icon.png`. This blocks compiling any project unless artwork is in place, even though this might be entirely beyond scope for a project. This issue stems from the fact that `Vec<String>` is used to deserialise icons, so there is no way to distinguish "no explicit value" from "explicitly instructed to use no value". Use an `Option<Vec<String>>` to deserialise configured icons, where no value (None) means "nothing explicitly specified; use the default), and Some(EmptyVec) means "explicitly requested no icons". This allows compiling small proof of concept projects without having to worry about artwork. Fixes: #14355
1 parent 67c7418 commit 1b6b2fd

File tree

7 files changed

+85
-56
lines changed

7 files changed

+85
-56
lines changed

crates/tauri-build/src/codegen/context.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,13 @@ impl CodegenContext {
101101
}
102102
_ => (),
103103
}
104-
for icon in &config.bundle.icon {
105-
println!(
106-
"cargo:rerun-if-changed={}",
107-
config_parent.join(icon).display()
108-
);
104+
if let Some(icons) = &config.bundle.icon {
105+
for icon in icons {
106+
println!(
107+
"cargo:rerun-if-changed={}",
108+
config_parent.join(icon).display()
109+
);
110+
}
109111
}
110112
if let Some(tray_icon) = config.app.tray_icon.as_ref().map(|t| &t.icon_path) {
111113
println!(

crates/tauri-build/src/lib.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -592,13 +592,14 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
592592
use tauri_winres::{VersionInfo, WindowsResource};
593593

594594
fn find_icon<F: Fn(&&String) -> bool>(config: &Config, predicate: F, default: &str) -> PathBuf {
595-
let icon_path = config
596-
.bundle
597-
.icon
598-
.iter()
599-
.find(|i| predicate(i))
600-
.cloned()
601-
.unwrap_or_else(|| default.to_string());
595+
let icon_path = match &config.bundle.icon {
596+
None => default.to_string(),
597+
Some(icons) => icons
598+
.iter()
599+
.find(|i| predicate(i))
600+
.cloned()
601+
.unwrap_or_else(|| default.to_string()),
602+
};
602603
icon_path.into()
603604
}
604605

crates/tauri-cli/config.schema.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@
9191
"iOS": {
9292
"minimumSystemVersion": "14.0"
9393
},
94-
"icon": [],
9594
"linux": {
9695
"appimage": {
9796
"bundleMediaFramework": false,
@@ -2114,8 +2113,10 @@
21142113
},
21152114
"icon": {
21162115
"description": "The app's icons",
2117-
"default": [],
2118-
"type": "array",
2116+
"type": [
2117+
"array",
2118+
"null"
2119+
],
21192120
"items": {
21202121
"type": "string"
21212122
}

crates/tauri-cli/src/interface/rust.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1461,7 +1461,7 @@ fn tauri_config_to_bundle_settings(
14611461
identifier: Some(tauri_config.identifier.clone()),
14621462
publisher: config.publisher,
14631463
homepage: config.homepage,
1464-
icon: Some(config.icon),
1464+
icon: config.icon,
14651465
resources,
14661466
resources_map,
14671467
copyright: config.copyright,

crates/tauri-codegen/src/context.rs

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -213,56 +213,74 @@ pub fn context_codegen(data: ContextData) -> EmbeddedAssetsResult<TokenStream> {
213213
let default_window_icon = {
214214
if target == Target::Windows {
215215
// handle default window icons for Windows targets
216-
let icon_path = find_icon(
216+
let icon_path_opt = find_icon(
217217
&config,
218218
&config_parent,
219219
|i| i.ends_with(".ico"),
220220
"icons/icon.ico",
221221
);
222-
if icon_path.exists() {
223-
let icon = CachedIcon::new(&root, &icon_path)?;
224-
quote!(::std::option::Option::Some(#icon))
222+
if let Some(icon_path) = icon_path_opt {
223+
if icon_path.exists() {
224+
let icon = CachedIcon::new(&root, &icon_path)?;
225+
quote!(::std::option::Option::Some(#icon))
226+
} else {
227+
let icon_path_opt = find_icon(
228+
&config,
229+
&config_parent,
230+
|i| i.ends_with(".png"),
231+
"icons/icon.png",
232+
);
233+
if let Some(icon_path) = icon_path_opt {
234+
let icon = CachedIcon::new(&root, &icon_path)?;
235+
quote!(::std::option::Option::Some(#icon))
236+
} else {
237+
quote!(::std::option::Option::None)
238+
}
239+
}
225240
} else {
226-
let icon_path = find_icon(
227-
&config,
228-
&config_parent,
229-
|i| i.ends_with(".png"),
230-
"icons/icon.png",
231-
);
232-
let icon = CachedIcon::new(&root, &icon_path)?;
233-
quote!(::std::option::Option::Some(#icon))
241+
quote!(::std::option::Option::None)
234242
}
235243
} else {
236244
// handle default window icons for Unix targets
237-
let icon_path = find_icon(
245+
let icon_path_opt = find_icon(
238246
&config,
239247
&config_parent,
240248
|i| i.ends_with(".png"),
241249
"icons/icon.png",
242250
);
243-
let icon = CachedIcon::new(&root, &icon_path)?;
244-
quote!(::std::option::Option::Some(#icon))
251+
if let Some(icon_path) = icon_path_opt {
252+
let icon = CachedIcon::new(&root, &icon_path)?;
253+
quote!(::std::option::Option::Some(#icon))
254+
} else {
255+
quote!(::std::option::Option::None)
256+
}
245257
}
246258
};
247259

248260
let app_icon = if target == Target::MacOS && dev {
249-
let mut icon_path = find_icon(
261+
let mut icon_path_opt = find_icon(
250262
&config,
251263
&config_parent,
252264
|i| i.ends_with(".icns"),
253265
"icons/icon.png",
254266
);
255-
if !icon_path.exists() {
256-
icon_path = find_icon(
257-
&config,
258-
&config_parent,
259-
|i| i.ends_with(".png"),
260-
"icons/icon.png",
261-
);
267+
if let Some(ref icon_path) = icon_path_opt {
268+
if !icon_path.exists() {
269+
icon_path_opt = find_icon(
270+
&config,
271+
&config_parent,
272+
|i| i.ends_with(".png"),
273+
"icons/icon.png",
274+
);
275+
}
262276
}
263277

264-
let icon = CachedIcon::new_raw(&root, &icon_path)?;
265-
quote!(::std::option::Option::Some(#icon.to_vec()))
278+
if let Some(icon_path) = icon_path_opt {
279+
let icon = CachedIcon::new_raw(&root, &icon_path)?;
280+
quote!(::std::option::Option::Some(#icon.to_vec()))
281+
} else {
282+
quote!(::std::option::Option::None)
283+
}
266284
} else {
267285
quote!(::std::option::Option::None)
268286
};
@@ -490,13 +508,14 @@ fn find_icon(
490508
config_parent: &Path,
491509
predicate: impl Fn(&&String) -> bool,
492510
default: &str,
493-
) -> PathBuf {
494-
let icon_path = config
495-
.bundle
496-
.icon
497-
.iter()
498-
.find(predicate)
499-
.map(AsRef::as_ref)
500-
.unwrap_or(default);
501-
config_parent.join(icon_path)
511+
) -> Option<PathBuf> {
512+
match &config.bundle.icon {
513+
// None => No specified, fall back to default.
514+
None => Some(config_parent.join(default)),
515+
// Some(_) => Use explicitly specified icon set.
516+
Some(icons) => icons
517+
.iter()
518+
.find(predicate)
519+
.map(|s| config_parent.join(s)),
520+
}
502521
}

crates/tauri-schema-generator/schemas/config.schema.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@
9191
"iOS": {
9292
"minimumSystemVersion": "14.0"
9393
},
94-
"icon": [],
9594
"linux": {
9695
"appimage": {
9796
"bundleMediaFramework": false,
@@ -2114,8 +2113,10 @@
21142113
},
21152114
"icon": {
21162115
"description": "The app's icons",
2117-
"default": [],
2118-
"type": "array",
2116+
"type": [
2117+
"array",
2118+
"null"
2119+
],
21192120
"items": {
21202121
"type": "string"
21212122
}

crates/tauri-utils/src/config.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,7 @@ pub struct BundleConfig {
13211321
pub homepage: Option<String>,
13221322
/// The app's icons
13231323
#[serde(default)]
1324-
pub icon: Vec<String>,
1324+
pub icon: Option<Vec<String>>,
13251325
/// App resources to bundle.
13261326
/// Each resource is a path to a file or directory.
13271327
/// Glob patterns are supported.
@@ -3713,7 +3713,12 @@ mod build {
37133713
fn to_tokens(&self, tokens: &mut TokenStream) {
37143714
let publisher = quote!(None);
37153715
let homepage = quote!(None);
3716-
let icon = vec_lit(&self.icon, str_lit);
3716+
let icon = if let Some(ref icons) = self.icon {
3717+
let vec = vec_lit(icons, str_lit);
3718+
quote!(Some(#vec))
3719+
} else {
3720+
quote!(None)
3721+
};
37173722
let active = self.active;
37183723
let targets = quote!(Default::default());
37193724
let create_updater_artifacts = quote!(Default::default());
@@ -4161,7 +4166,7 @@ mod test {
41614166
create_updater_artifacts: Default::default(),
41624167
publisher: None,
41634168
homepage: None,
4164-
icon: Vec::new(),
4169+
icon: Some(Vec::new()),
41654170
resources: None,
41664171
copyright: None,
41674172
category: None,

0 commit comments

Comments
 (0)