Skip to content

Commit

Permalink
fix(codegen): icon rewriting always triggering build to rerun (#10268)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Jul 12, 2024
1 parent 4c23972 commit 5d29229
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changes/rerun-if-changed-icons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-codegen": patch:bug
---

Fix icon rewriting always triggering build to rerun due to conflicts between file names.
13 changes: 8 additions & 5 deletions core/tauri-codegen/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,15 +221,17 @@ pub fn context_codegen(data: ContextData) -> EmbeddedAssetsResult<TokenStream> {
"icons/icon.ico",
);
if icon_path.exists() {
ico_icon(&root, &out_dir, &icon_path).map(|i| quote!(::std::option::Option::Some(#i)))?
ico_icon(&root, &out_dir, &icon_path, "default-window-icon.png")
.map(|i| quote!(::std::option::Option::Some(#i)))?
} else {
let icon_path = find_icon(
&config,
&config_parent,
|i| i.ends_with(".png"),
"icons/icon.png",
);
png_icon(&root, &out_dir, &icon_path).map(|i| quote!(::std::option::Option::Some(#i)))?
png_icon(&root, &out_dir, &icon_path, "default-window-icon.png")
.map(|i| quote!(::std::option::Option::Some(#i)))?
}
} else {
// handle default window icons for Unix targets
Expand All @@ -239,7 +241,8 @@ pub fn context_codegen(data: ContextData) -> EmbeddedAssetsResult<TokenStream> {
|i| i.ends_with(".png"),
"icons/icon.png",
);
png_icon(&root, &out_dir, &icon_path).map(|i| quote!(::std::option::Option::Some(#i)))?
png_icon(&root, &out_dir, &icon_path, "default-window-icon.png")
.map(|i| quote!(::std::option::Option::Some(#i)))?
}
};

Expand All @@ -258,7 +261,7 @@ pub fn context_codegen(data: ContextData) -> EmbeddedAssetsResult<TokenStream> {
"icons/icon.png",
);
}
raw_icon(&out_dir, &icon_path)?
raw_icon(&out_dir, &icon_path, "dev-macos-icon.png")?
} else {
quote!(::std::option::Option::None)
};
Expand Down Expand Up @@ -287,7 +290,7 @@ pub fn context_codegen(data: ContextData) -> EmbeddedAssetsResult<TokenStream> {
let with_tray_icon_code = if target.is_desktop() {
if let Some(tray) = &config.app.tray_icon {
let tray_icon_icon_path = config_parent.join(&tray.icon_path);
image_icon(&root, &out_dir, &tray_icon_icon_path)
image_icon(&root, &out_dir, &tray_icon_icon_path, "tray-icon")
.map(|i| quote!(context.set_tray_icon(Some(#i));))?
} else {
quote!()
Expand Down
40 changes: 23 additions & 17 deletions core/tauri-codegen/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use quote::{quote, ToTokens};
use std::path::Path;
use syn::{punctuated::Punctuated, Ident, PathArguments, PathSegment, Token};

pub fn include_image_codegen(path: &Path) -> EmbeddedAssetsResult<TokenStream> {
pub fn include_image_codegen(
path: &Path,
out_file_name: &str,
) -> EmbeddedAssetsResult<TokenStream> {
let out_dir = ensure_out_dir()?;

let mut segments = Punctuated::new();
Expand All @@ -21,19 +24,20 @@ pub fn include_image_codegen(path: &Path) -> EmbeddedAssetsResult<TokenStream> {
segments,
};

image_icon(&root.to_token_stream(), &out_dir, path)
image_icon(&root.to_token_stream(), &out_dir, path, out_file_name)
}

pub(crate) fn image_icon(
root: &TokenStream,
out_dir: &Path,
path: &Path,
out_file_name: &str,
) -> EmbeddedAssetsResult<TokenStream> {
let extension = path.extension().unwrap_or_default();
if extension == "ico" {
ico_icon(root, out_dir, path)
ico_icon(root, out_dir, path, out_file_name)
} else if extension == "png" {
png_icon(root, out_dir, path)
png_icon(root, out_dir, path, out_file_name)
} else {
Err(EmbeddedAssetsError::InvalidImageExtension {
extension: extension.into(),
Expand All @@ -42,19 +46,22 @@ pub(crate) fn image_icon(
}
}

pub(crate) fn raw_icon(out_dir: &Path, path: &Path) -> EmbeddedAssetsResult<TokenStream> {
pub(crate) fn raw_icon(
out_dir: &Path,
path: &Path,
out_file_name: &str,
) -> EmbeddedAssetsResult<TokenStream> {
let bytes =
std::fs::read(path).unwrap_or_else(|e| panic!("failed to read icon {}: {}", path.display(), e));

let out_path = out_dir.join(path.file_name().unwrap());
let out_path = out_dir.join(out_file_name);
write_if_changed(&out_path, &bytes).map_err(|error| EmbeddedAssetsError::AssetWrite {
path: path.to_owned(),
error,
})?;

let icon_path = path.file_name().unwrap().to_str().unwrap().to_string();
let icon = quote!(::std::option::Option::Some(
include_bytes!(concat!(std::env!("OUT_DIR"), "/", #icon_path)).to_vec()
include_bytes!(concat!(std::env!("OUT_DIR"), "/", #out_file_name)).to_vec()
));
Ok(icon)
}
Expand All @@ -63,6 +70,7 @@ pub(crate) fn ico_icon(
root: &TokenStream,
out_dir: &Path,
path: &Path,
out_file_name: &str,
) -> EmbeddedAssetsResult<TokenStream> {
let file = std::fs::File::open(path)
.unwrap_or_else(|e| panic!("failed to open icon {}: {}", path.display(), e));
Expand All @@ -77,22 +85,21 @@ pub(crate) fn ico_icon(
let width = entry.width();
let height = entry.height();

let icon_file_name = path.file_name().unwrap();
let out_path = out_dir.join(icon_file_name);
let out_path = out_dir.join(out_file_name);
write_if_changed(&out_path, &rgba).map_err(|error| EmbeddedAssetsError::AssetWrite {
path: path.to_owned(),
error,
})?;

let icon_file_name = icon_file_name.to_str().unwrap();
let icon = quote!(#root::image::Image::new(include_bytes!(concat!(std::env!("OUT_DIR"), "/", #icon_file_name)), #width, #height));
let icon = quote!(#root::image::Image::new(include_bytes!(concat!(std::env!("OUT_DIR"), "/", #out_file_name)), #width, #height));
Ok(icon)
}

pub(crate) fn png_icon(
root: &TokenStream,
out_dir: &Path,
path: &Path,
out_file_name: &str,
) -> EmbeddedAssetsResult<TokenStream> {
let file = std::fs::File::open(path)
.unwrap_or_else(|e| panic!("failed to open icon {}: {}", path.display(), e));
Expand All @@ -114,23 +121,22 @@ pub(crate) fn png_icon(
let width = reader.info().width;
let height = reader.info().height;

let icon_file_name = path.file_name().unwrap();
let out_path = out_dir.join(icon_file_name);
let out_path = out_dir.join(out_file_name);
write_if_changed(&out_path, &buffer).map_err(|error| EmbeddedAssetsError::AssetWrite {
path: path.to_owned(),
error,
})?;

let icon_file_name = icon_file_name.to_str().unwrap();
let icon = quote!(#root::image::Image::new(include_bytes!(concat!(std::env!("OUT_DIR"), "/", #icon_file_name)), #width, #height));
let icon = quote!(#root::image::Image::new(include_bytes!(concat!(std::env!("OUT_DIR"), "/", #out_file_name)), #width, #height));
Ok(icon)
}

pub(crate) fn write_if_changed(out_path: &Path, data: &[u8]) -> std::io::Result<()> {
fn write_if_changed(out_path: &Path, data: &[u8]) -> std::io::Result<()> {
if let Ok(curr) = std::fs::read(out_path) {
if curr == data {
return Ok(());
}
}

std::fs::write(out_path, data)
}
7 changes: 6 additions & 1 deletion core/tauri-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,12 @@ pub fn include_image(tokens: TokenStream) -> TokenStream {
);
return quote!(compile_error!(#error_string)).into();
}
match tauri_codegen::include_image_codegen(&resolved_path).map_err(|error| error.to_string()) {
match tauri_codegen::include_image_codegen(
&resolved_path,
resolved_path.file_name().unwrap().to_str().unwrap(),
)
.map_err(|error| error.to_string())
{
Ok(output) => output,
Err(error) => quote!(compile_error!(#error)),
}
Expand Down

0 comments on commit 5d29229

Please sign in to comment.