Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add glob support for icons field #99

Merged
merged 6 commits into from
Dec 13, 2023
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
5 changes: 5 additions & 0 deletions .changes/glob-icons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"cargo-packager": "patch"
---

Add glob patterns support for the icons option in config.
2 changes: 1 addition & 1 deletion crates/packager/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
]
},
"icons": {
"description": "The app's icon list.",
"description": "The app's icon list. Supports glob patterns.",
"type": [
"array",
"null"
Expand Down
6 changes: 3 additions & 3 deletions crates/packager/src/config/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,10 @@ impl ConfigBuilder {
}

/// Sets [`Config::icons`].
pub fn icons<I, P>(mut self, icons: I) -> Self
pub fn icons<I, S>(mut self, icons: I) -> Self
where
I: IntoIterator<Item = P>,
P: Into<PathBuf>,
I: IntoIterator<Item = S>,
S: Into<String>,
{
self.0
.icons
Expand Down
26 changes: 21 additions & 5 deletions crates/packager/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1488,8 +1488,8 @@ pub struct Config {
pub copyright: Option<String>,
/// The app's category.
pub category: Option<AppCategory>,
/// The app's icon list.
pub icons: Option<Vec<PathBuf>>,
/// The app's icon list. Supports glob patterns.
pub icons: Option<Vec<String>>,
/// The file associations
#[serde(alias = "file-associations", alias = "file_associations")]
pub file_associations: Option<Vec<FileAssociation>>,
Expand Down Expand Up @@ -1653,6 +1653,20 @@ impl Config {
.map(|b| b.path.file_stem().unwrap().to_string_lossy().into_owned())
.ok_or_else(|| crate::Error::MainBinaryNotFound)
}

/// Returns all icons path.
pub fn icons(&self) -> crate::Result<Option<Vec<PathBuf>>> {
let Some(patterns) = &self.icons else {
return Ok(None);
};
let mut paths = Vec::new();
for pattern in patterns {
for icon_path in glob::glob(pattern)? {
paths.push(icon_path?);
}
}
Ok(Some(paths))
}
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -1737,8 +1751,9 @@ impl Config {
}

#[allow(unused)]
pub(crate) fn find_ico(&self) -> Option<PathBuf> {
self.icons
pub(crate) fn find_ico(&self) -> crate::Result<Option<PathBuf>> {
let icon = self
.icons()?
.as_ref()
.and_then(|icons| {
icons
Expand All @@ -1750,7 +1765,8 @@ impl Config {
})
})
})
.map(PathBuf::from)
.map(PathBuf::from);
Ok(icon)
}

#[allow(unused)]
Expand Down
3 changes: 1 addition & 2 deletions crates/packager/src/package/deb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ fn generate_icon_files(config: &Config, data_dir: &Path) -> crate::Result<BTreeS
))
};
let mut icons_set = BTreeSet::new();
if let Some(icons) = &config.icons {
if let Some(icons) = config.icons()? {
for icon_path in icons {
let icon_path = PathBuf::from(icon_path);
if icon_path.extension() != Some(OsStr::new("png")) {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion crates/packager/src/package/wix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ fn build_wix_app_installer(ctx: &Context, wix_path: &Path) -> crate::Result<Vec<
data.insert("app_exe_source", to_json(&main_binary_path));

// copy icon from `settings.windows().icon_path` folder to resource folder near msi
if let Some(icon) = config.find_ico() {
if let Some(icon) = config.find_ico()? {
let icon_path = dunce::canonicalize(icon)?;
data.insert("icon_path", to_json(icon_path));
}
Expand Down
11 changes: 5 additions & 6 deletions crates/packager/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,16 +279,15 @@ pub(crate) fn is_retina<P: AsRef<Path>>(path: P) -> bool {
pub fn create_icns_file(out_dir: &Path, config: &crate::Config) -> crate::Result<Option<PathBuf>> {
use image::GenericImageView;

if config.icons.as_ref().map(|i| i.len()).unwrap_or_default() == 0 {
let icons = config.icons()?;
if icons.as_ref().map(|i| i.len()).unwrap_or_default() == 0 {
return Ok(None);
}

// If one of the icon files is already an ICNS file, just use that.
if let Some(icons) = &config.icons {
if let Some(icons) = icons {
std::fs::create_dir_all(out_dir)?;

for icon_path in icons {
let icon_path = PathBuf::from(icon_path);
if icon_path.extension() == Some(std::ffi::OsStr::new("icns")) {
let dest_path = out_dir.join(
icon_path
Expand Down Expand Up @@ -330,8 +329,8 @@ pub fn create_icns_file(out_dir: &Path, config: &crate::Config) -> crate::Result
}

let mut images_to_resize: Vec<(image::DynamicImage, u32, u32)> = vec![];
if let Some(icons) = &config.icons {
for icon_path in icons {
if let Some(icons) = config.icons()? {
for icon_path in &icons {
let icon = image::open(icon_path)?;
let density = if is_retina(icon_path) { 2 } else { 1 };
let (w, h) = icon.dimensions();
Expand Down