diff --git a/Cargo.lock b/Cargo.lock index fa819372c..cf2a6e88e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1062,9 +1062,9 @@ dependencies = [ [[package]] name = "cargo-mobile2" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9faa9fae5ccf60d68e6b766293be17bbce2de0aece38886f2eb1ac8da8718942" +checksum = "24b5acda005352ad50a3e58c8777781732d6ac1e8a82ab90d5ffd70b69c665f1" dependencies = [ "colored", "core-foundation 0.10.0", @@ -1355,7 +1355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -2347,7 +2347,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5792,7 +5792,7 @@ dependencies = [ "aes-gcm", "aes-kw", "argon2", - "base64 0.21.7", + "base64 0.22.1", "bitfield", "block-padding", "blowfish", @@ -6372,7 +6372,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -7057,7 +7057,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -8917,7 +8917,7 @@ dependencies = [ "getrandom 0.2.15", "once_cell", "rustix 0.38.43", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -10178,7 +10178,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/crates/tauri-cli/Cargo.toml b/crates/tauri-cli/Cargo.toml index 579e120d3..e5ca3c50b 100644 --- a/crates/tauri-cli/Cargo.toml +++ b/crates/tauri-cli/Cargo.toml @@ -36,7 +36,7 @@ name = "cargo-tauri" path = "src/main.rs" [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\", target_os = \"windows\", target_os = \"macos\"))".dependencies] -cargo-mobile2 = { version = "0.18", default-features = false } +cargo-mobile2 = { version = "0.19", default-features = false } [dependencies] jsonrpsee = { version = "0.24", features = ["server"] } diff --git a/crates/tauri-cli/src/helpers/mod.rs b/crates/tauri-cli/src/helpers/mod.rs index 5eaa06475..3f0a9fc60 100644 --- a/crates/tauri-cli/src/helpers/mod.rs +++ b/crates/tauri-cli/src/helpers/mod.rs @@ -119,3 +119,23 @@ pub fn run_hook( Ok(()) } + +#[cfg(target_os = "macos")] +pub fn strip_semver_prerelease_tag(version: &mut semver::Version) -> crate::Result<()> { + if !version.pre.is_empty() { + if let Some((_prerelease_tag, number)) = version.pre.as_str().to_string().split_once('.') { + version.pre = semver::Prerelease::EMPTY; + version.build = semver::BuildMetadata::new(&format!( + "{prefix}{number}", + prefix = if version.build.is_empty() { + "".to_string() + } else { + format!(".{}", version.build.as_str()) + } + )) + .with_context(|| format!("bundle version {number:?} prerelease is invalid"))?; + } + } + + Ok(()) +} diff --git a/crates/tauri-cli/src/mobile/ios/build.rs b/crates/tauri-cli/src/mobile/ios/build.rs index 31d9f7244..6b641eba4 100644 --- a/crates/tauri-cli/src/mobile/ios/build.rs +++ b/crates/tauri-cli/src/mobile/ios/build.rs @@ -14,7 +14,7 @@ use crate::{ config::{get as get_tauri_config, ConfigHandle}, flock, }, - interface::{AppInterface, AppSettings, Interface, Options as InterfaceOptions}, + interface::{AppInterface, Interface, Options as InterfaceOptions}, mobile::{write_options, CliOptions}, ConfigValue, Result, }; @@ -36,7 +36,6 @@ use std::{ env::{set_current_dir, var, var_os}, fs, path::PathBuf, - str::FromStr, }; #[derive(Debug, Clone, Parser)] @@ -183,36 +182,10 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> { inject_resources(&config, tauri_config.lock().unwrap().as_ref().unwrap())?; let mut plist = plist::Dictionary::new(); - { - let tauri_config_guard = tauri_config.lock().unwrap(); - let tauri_config_ = tauri_config_guard.as_ref().unwrap(); - let app_version = tauri_config_ - .version - .clone() - .unwrap_or_else(|| interface.app_settings().get_package_settings().version); - - let mut version = semver::Version::from_str(&app_version) - .with_context(|| format!("failed to parse {app_version:?} as a semver string"))?; - if !version.pre.is_empty() { - log::info!( - "CFBundleShortVersionString cannot have prerelease identifier; stripping {}", - version.pre.as_str() - ); - version.pre = semver::Prerelease::EMPTY; - } - if !version.build.is_empty() { - log::info!( - "CFBundleShortVersionString cannot have build number; stripping {}", - version.build.as_str() - ); - version.build = semver::BuildMetadata::EMPTY; - } - - plist.insert( - "CFBundleShortVersionString".into(), - version.to_string().into(), - ); - }; + plist.insert( + "CFBundleShortVersionString".into(), + config.bundle_version_short().into(), + ); let info_plist_path = config .project_dir() @@ -338,9 +311,10 @@ fn run_build( &detect_target_ok, env, |target: &Target| -> Result<()> { - let mut app_version = config.bundle_version().clone(); + let mut app_version = config.bundle_version().to_string(); if let Some(build_number) = options.build_number { - app_version.push_extra(build_number); + app_version.push('.'); + app_version.push_str(&build_number.to_string()); } let credentials = auth_credentials_from_env()?; diff --git a/crates/tauri-cli/src/mobile/ios/mod.rs b/crates/tauri-cli/src/mobile/ios/mod.rs index 23fc24ff5..8bdd88337 100644 --- a/crates/tauri-cli/src/mobile/ios/mod.rs +++ b/crates/tauri-cli/src/mobile/ios/mod.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use anyhow::Context; use cargo_mobile2::{ apple::{ config::{ @@ -31,7 +30,7 @@ use crate::{ helpers::{ app_paths::tauri_dir, config::{BundleResources, Config as TauriConfig, ConfigHandle}, - pbxproj, + pbxproj, strip_semver_prerelease_tag, }, Result, }; @@ -130,30 +129,72 @@ pub fn get_config( .clone() .or_else(|| tauri_config.version.clone()) { - let mut version = semver::Version::from_str(&bundle_version) - .with_context(|| format!("failed to parse {bundle_version:?} as a semver string"))?; - if !version.pre.is_empty() { - if let Some((_prerelease_tag, number)) = version.pre.as_str().to_string().split_once('.') { - version.pre = semver::Prerelease::EMPTY; - if version.build.is_empty() { - version.build = semver::BuildMetadata::new(number) - .with_context(|| format!("bundle version {number:?} prerelease is invalid"))?; - } else { - anyhow::bail!("bundle version {bundle_version:?} is invalid, it cannot have both prerelease and build metadata"); - } + // if it's a semver string, we must strip the prerelease tag + if let Ok(mut version) = semver::Version::from_str(&bundle_version) { + if !version.pre.is_empty() { + log::warn!("CFBundleVersion cannot have prerelease tag; stripping from {bundle_version}"); + strip_semver_prerelease_tag(&mut version)?; } + // correctly serialize version - cannot contain `+` as build metadata separator + Some(format!( + "{}.{}.{}{}", + version.major, + version.minor, + version.patch, + if version.build.is_empty() { + "".to_string() + } else { + format!(".{}", version.build.as_str()) + } + )) + } else { + // let it go as is - cargo-mobile2 will validate it + Some(bundle_version) + } + } else { + None + }; + let full_bundle_version_short = if let Some(app_version) = &tauri_config.version { + if let Ok(mut version) = semver::Version::from_str(app_version) { + if !version.pre.is_empty() { + log::warn!( + "CFBundleShortVersionString cannot have prerelease tag; stripping from {app_version}" + ); + strip_semver_prerelease_tag(&mut version)?; + } + // correctly serialize version - cannot contain `+` as build metadata separator + Some(format!( + "{}.{}.{}{}", + version.major, + version.minor, + version.patch, + if version.build.is_empty() { + "".to_string() + } else { + format!(".{}", version.build.as_str()) + } + )) + } else { + // let it go as is - cargo-mobile2 will validate it + Some(app_version.clone()) + } + } else { + bundle_version.clone() + }; + let bundle_version_short = if let Some(full_version) = full_bundle_version_short.as_deref() { + let mut s = full_version.split('.'); + let short_version = format!( + "{}.{}.{}", + s.next().unwrap_or("0"), + s.next().unwrap_or("0"), + s.next().unwrap_or("0") + ); + + if short_version != full_version { + log::warn!("{full_version:?} is not a valid CFBundleShortVersionString since it must contain exactly three dot separated integers; setting it to {short_version} instead"); } - let maybe_build_number = if version.build.is_empty() { - "".to_string() - } else { - format!(".{}", version.build.as_str()) - }; - - Some(format!( - "{}.{}.{}{}", - version.major, version.minor, version.patch, maybe_build_number - )) + Some(short_version) } else { None }; @@ -178,6 +219,7 @@ pub fn get_config( }), ios_features: ios_options.features.clone(), bundle_version, + bundle_version_short, ios_version: Some(tauri_config.bundle.ios.minimum_system_version.clone()), ..Default::default() };