fix(core): Correctly detect Android Tauri configuration file, closes #7785 (#7802)

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
i-c-b 2023-09-12 11:18:23 -05:00 committed by GitHub
parent 3c66a53a9e
commit 100d9ede35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 269 additions and 165 deletions

View File

@ -0,0 +1,6 @@
---
"tauri-cli": patch:bug
"@tauri-apps/cli": patch:bug
---
Properly read platform-specific configuration files for mobile targets.

View File

@ -0,0 +1,6 @@
---
"tauri-codegen": patch:enhance
"tauri-macros": patch:enhance
---
Use `Target` enum from `tauri_utils::platform`.

View File

@ -0,0 +1,5 @@
---
"tauri-utils": patch:breaking
---
Follow file name conventions set by desktop for mobile Tauri configuration files. Added `target` argument on most `config::parse` methods.

View File

@ -294,6 +294,7 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
cfg_alias("mobile", mobile);
let mut config = serde_json::from_value(tauri_utils::config::parse::read_from(
tauri_utils::platform::Target::from_triple(&std::env::var("TARGET").unwrap()),
std::env::current_dir().unwrap(),
)?)?;
if let Ok(env) = std::env::var("TAURI_CONFIG") {

View File

@ -15,6 +15,7 @@ use tauri_utils::config::{AppUrl, Config, PatternKind, WindowUrl};
use tauri_utils::html::{
inject_nonce_token, parse as parse_html, serialize_node as serialize_html_node,
};
use tauri_utils::platform::Target;
use crate::embedded_assets::{AssetOptions, CspHashes, EmbeddedAssets, EmbeddedAssetsError};
@ -112,26 +113,6 @@ fn map_isolation(
}
}
#[derive(PartialEq, Eq, Clone, Copy)]
enum Target {
Linux,
Windows,
Darwin,
Android,
// iOS.
Ios,
}
impl Target {
fn is_mobile(&self) -> bool {
matches!(self, Target::Android | Target::Ios)
}
fn is_desktop(&self) -> bool {
!self.is_mobile()
}
}
/// Build a `tauri::Context` for including in application code.
pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsError> {
let ContextData {
@ -141,34 +122,11 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
root,
} = data;
let target =
if let Ok(target) = std::env::var("TARGET").or_else(|_| std::env::var("TAURI_TARGET_TRIPLE")) {
if target.contains("unknown-linux") {
Target::Linux
} else if target.contains("pc-windows") {
Target::Windows
} else if target.contains("apple-darwin") {
Target::Darwin
} else if target.contains("android") {
Target::Android
} else if target.contains("apple-ios") {
Target::Ios
} else {
panic!("unknown codegen target {target}");
}
} else if cfg!(target_os = "linux") {
Target::Linux
} else if cfg!(windows) {
Target::Windows
} else if cfg!(target_os = "macos") {
Target::Darwin
} else if cfg!(target_os = "android") {
Target::Android
} else if cfg!(target_os = "ios") {
Target::Ios
} else {
panic!("unknown codegen target")
};
let target = std::env::var("TARGET")
.or_else(|_| std::env::var("TAURI_TARGET_TRIPLE"))
.as_deref()
.map(Target::from_triple)
.unwrap_or_else(|_| Target::current());
let mut options = AssetOptions::new(config.tauri.pattern.clone())
.freeze_prototype(config.tauri.security.freeze_prototype)

View File

@ -67,7 +67,10 @@ pub fn get_config(path: &Path) -> Result<(Config, PathBuf), CodegenConfigError>
// it is impossible for the content of two separate configs to get mixed up. The chances are
// already unlikely unless the developer goes out of their way to run the cli on a different
// project than the target crate.
let mut config = serde_json::from_value(tauri_utils::config::parse::read_from(parent.clone())?)?;
let mut config = serde_json::from_value(tauri_utils::config::parse::read_from(
tauri_utils::platform::Target::current(),
parent.clone(),
)?)?;
if let Ok(env) = std::env::var("TAURI_CONFIG") {
let merge_config: serde_json::Value =
serde_json::from_str(&env).map_err(CodegenConfigError::FormatInline)?;

View File

@ -11,7 +11,7 @@ use syn::{
LitStr, PathArguments, PathSegment, Token,
};
use tauri_codegen::{context_codegen, get_config, ContextData};
use tauri_utils::config::parse::does_supported_file_name_exist;
use tauri_utils::{config::parse::does_supported_file_name_exist, platform::Target};
pub(crate) struct ContextItems {
config_file: PathBuf,
@ -20,6 +20,12 @@ pub(crate) struct ContextItems {
impl Parse for ContextItems {
fn parse(input: &ParseBuffer<'_>) -> syn::parse::Result<Self> {
let target = std::env::var("TARGET")
.or_else(|_| std::env::var("TAURI_TARGET_TRIPLE"))
.as_deref()
.map(Target::from_triple)
.unwrap_or_else(|_| Target::current());
let config_file = if input.is_empty() {
std::env::var("CARGO_MANIFEST_DIR").map(|m| PathBuf::from(m).join("tauri.conf.json"))
} else {
@ -36,7 +42,7 @@ impl Parse for ContextItems {
VarError::NotUnicode(_) => "CARGO_MANIFEST_DIR env var contained invalid utf8".into(),
})
.and_then(|path| {
if does_supported_file_name_exist(&path) {
if does_supported_file_name_exist(target, &path) {
Ok(path)
} else {
Err(format!(

View File

@ -3,6 +3,7 @@
// SPDX-License-Identifier: MIT
use crate::config::Config;
use crate::platform::Target;
use json_patch::merge;
use serde::de::DeserializeOwned;
use serde_json::Value;
@ -47,47 +48,29 @@ impl ConfigFormat {
}
}
fn into_platform_file_name(self) -> &'static str {
fn into_platform_file_name(self, target: Target) -> &'static str {
match self {
Self::Json => {
if cfg!(target_os = "macos") {
"tauri.macos.conf.json"
} else if cfg!(windows) {
"tauri.windows.conf.json"
} else if cfg!(target_os = "android") {
"tauri.android.conf.json"
} else if cfg!(target_os = "ios") {
"tauri.ios.conf.json"
} else {
"tauri.linux.conf.json"
}
}
Self::Json5 => {
if cfg!(target_os = "macos") {
"tauri.macos.conf.json5"
} else if cfg!(windows) {
"tauri.windows.conf.json5"
} else if cfg!(target_os = "android") {
"tauri.android.conf.json"
} else if cfg!(target_os = "ios") {
"tauri.ios.conf.json"
} else {
"tauri.linux.conf.json5"
}
}
Self::Toml => {
if cfg!(target_os = "macos") {
"Tauri.macos.toml"
} else if cfg!(windows) {
"Tauri.windows.toml"
} else if cfg!(target_os = "android") {
"tauri.android.toml"
} else if cfg!(target_os = "ios") {
"tauri.ios.toml"
} else {
"Tauri.linux.toml"
}
}
Self::Json => match target {
Target::Darwin => "tauri.macos.conf.json",
Target::Windows => "tauri.windows.conf.json",
Target::Linux => "tauri.linux.conf.json",
Target::Android => "tauri.android.conf.json",
Target::Ios => "tauri.ios.conf.json",
},
Self::Json5 => match target {
Target::Darwin => "tauri.macos.conf.json5",
Target::Windows => "tauri.windows.conf.json5",
Target::Linux => "tauri.linux.conf.json5",
Target::Android => "tauri.android.conf.json5",
Target::Ios => "tauri.ios.conf.json5",
},
Self::Toml => match target {
Target::Darwin => "Tauri.macos.toml",
Target::Windows => "Tauri.windows.toml",
Target::Linux => "Tauri.linux.toml",
Target::Android => "Tauri.android.toml",
Target::Ios => "Tauri.ios.toml",
},
}
}
}
@ -154,18 +137,18 @@ pub enum ConfigError {
}
/// Determines if the given folder has a configuration file.
pub fn folder_has_configuration_file(folder: &Path) -> bool {
pub fn folder_has_configuration_file(target: Target, folder: &Path) -> bool {
folder.join(ConfigFormat::Json.into_file_name()).exists()
|| folder.join(ConfigFormat::Json5.into_file_name()).exists()
|| folder.join(ConfigFormat::Toml.into_file_name()).exists()
// platform file names
|| folder.join(ConfigFormat::Json.into_platform_file_name()).exists()
|| folder.join(ConfigFormat::Json5.into_platform_file_name()).exists()
|| folder.join(ConfigFormat::Toml.into_platform_file_name()).exists()
|| folder.join(ConfigFormat::Json.into_platform_file_name(target)).exists()
|| folder.join(ConfigFormat::Json5.into_platform_file_name(target)).exists()
|| folder.join(ConfigFormat::Toml.into_platform_file_name(target)).exists()
}
/// Determines if the given file path represents a Tauri configuration file.
pub fn is_configuration_file(path: &Path) -> bool {
pub fn is_configuration_file(target: Target, path: &Path) -> bool {
path
.file_name()
.map(|file_name| {
@ -173,9 +156,9 @@ pub fn is_configuration_file(path: &Path) -> bool {
|| file_name == OsStr::new(ConfigFormat::Json5.into_file_name())
|| file_name == OsStr::new(ConfigFormat::Toml.into_file_name())
// platform file names
|| file_name == OsStr::new(ConfigFormat::Json.into_platform_file_name())
|| file_name == OsStr::new(ConfigFormat::Json5.into_platform_file_name())
|| file_name == OsStr::new(ConfigFormat::Toml.into_platform_file_name())
|| file_name == OsStr::new(ConfigFormat::Json.into_platform_file_name(target))
|| file_name == OsStr::new(ConfigFormat::Json5.into_platform_file_name(target))
|| file_name == OsStr::new(ConfigFormat::Toml.into_platform_file_name(target))
})
.unwrap_or_default()
}
@ -192,9 +175,9 @@ pub fn is_configuration_file(path: &Path) -> bool {
/// Merging the configurations using [JSON Merge Patch (RFC 7396)].
///
/// [JSON Merge Patch (RFC 7396)]: https://datatracker.ietf.org/doc/html/rfc7396.
pub fn read_from(root_dir: PathBuf) -> Result<Value, ConfigError> {
let mut config: Value = parse_value(root_dir.join("tauri.conf.json"))?.0;
if let Some((platform_config, _)) = read_platform(root_dir)? {
pub fn read_from(target: Target, root_dir: PathBuf) -> Result<Value, ConfigError> {
let mut config: Value = parse_value(target, root_dir.join("tauri.conf.json"))?.0;
if let Some((platform_config, _)) = read_platform(target, root_dir)? {
merge(&mut config, &platform_config);
}
Ok(config)
@ -203,10 +186,13 @@ pub fn read_from(root_dir: PathBuf) -> Result<Value, ConfigError> {
/// Reads the platform-specific configuration file from the given root directory if it exists.
///
/// Check [`read_from`] for more information.
pub fn read_platform(root_dir: PathBuf) -> Result<Option<(Value, PathBuf)>, ConfigError> {
let platform_config_path = root_dir.join(ConfigFormat::Json.into_platform_file_name());
if does_supported_file_name_exist(&platform_config_path) {
let (platform_config, path): (Value, PathBuf) = parse_value(platform_config_path)?;
pub fn read_platform(
target: Target,
root_dir: PathBuf,
) -> Result<Option<(Value, PathBuf)>, ConfigError> {
let platform_config_path = root_dir.join(ConfigFormat::Json.into_platform_file_name(target));
if does_supported_file_name_exist(target, &platform_config_path) {
let (platform_config, path): (Value, PathBuf) = parse_value(target, platform_config_path)?;
Ok(Some((platform_config, path)))
} else {
Ok(None)
@ -217,16 +203,16 @@ pub fn read_platform(root_dir: PathBuf) -> Result<Option<(Value, PathBuf)>, Conf
///
/// The passed path is expected to be the path to the "default" configuration format, in this case
/// JSON with `.json`.
pub fn does_supported_file_name_exist(path: impl Into<PathBuf>) -> bool {
pub fn does_supported_file_name_exist(target: Target, path: impl Into<PathBuf>) -> bool {
let path = path.into();
let source_file_name = path.file_name().unwrap().to_str().unwrap();
let lookup_platform_config = ENABLED_FORMATS
.iter()
.any(|format| source_file_name == format.into_platform_file_name());
.any(|format| source_file_name == format.into_platform_file_name(target));
ENABLED_FORMATS.iter().any(|format| {
path
.with_file_name(if lookup_platform_config {
format.into_platform_file_name()
format.into_platform_file_name(target)
} else {
format.into_file_name()
})
@ -248,31 +234,37 @@ pub fn does_supported_file_name_exist(path: impl Into<PathBuf>) -> bool {
/// a. Parse it with `toml`
/// b. Return error if all above steps failed
/// 4. Return error if all above steps failed
pub fn parse(path: impl Into<PathBuf>) -> Result<(Config, PathBuf), ConfigError> {
do_parse(path.into())
pub fn parse(target: Target, path: impl Into<PathBuf>) -> Result<(Config, PathBuf), ConfigError> {
do_parse(target, path.into())
}
/// See [`parse`] for specifics, returns a JSON [`Value`] instead of [`Config`].
pub fn parse_value(path: impl Into<PathBuf>) -> Result<(Value, PathBuf), ConfigError> {
do_parse(path.into())
pub fn parse_value(
target: Target,
path: impl Into<PathBuf>,
) -> Result<(Value, PathBuf), ConfigError> {
do_parse(target, path.into())
}
fn do_parse<D: DeserializeOwned>(path: PathBuf) -> Result<(D, PathBuf), ConfigError> {
fn do_parse<D: DeserializeOwned>(
target: Target,
path: PathBuf,
) -> Result<(D, PathBuf), ConfigError> {
let file_name = path
.file_name()
.map(OsStr::to_string_lossy)
.unwrap_or_default();
let lookup_platform_config = ENABLED_FORMATS
.iter()
.any(|format| file_name == format.into_platform_file_name());
.any(|format| file_name == format.into_platform_file_name(target));
let json5 = path.with_file_name(if lookup_platform_config {
ConfigFormat::Json5.into_platform_file_name()
ConfigFormat::Json5.into_platform_file_name(target)
} else {
ConfigFormat::Json5.into_file_name()
});
let toml = path.with_file_name(if lookup_platform_config {
ConfigFormat::Toml.into_platform_file_name()
ConfigFormat::Toml.into_platform_file_name(target)
} else {
ConfigFormat::Toml.into_file_name()
});

View File

@ -10,6 +10,59 @@ use crate::{Env, PackageInfo};
mod starting_binary;
/// Platform target.
#[derive(PartialEq, Eq, Copy, Clone)]
pub enum Target {
/// MacOS.
Darwin,
/// Windows.
Windows,
/// Linux.
Linux,
/// Android.
Android,
/// iOS.
Ios,
}
impl Target {
/// Parses the target from the given target triple.
pub fn from_triple(target: &str) -> Self {
if target.contains("darwin") {
Self::Darwin
} else if target.contains("windows") {
Self::Windows
} else if target.contains("android") {
Self::Android
} else if target.contains("ios") {
Self::Ios
} else {
Self::Linux
}
}
/// Gets the current build target.
pub fn current() -> Self {
if cfg!(target_os = "macos") {
Self::Darwin
} else if cfg!(target_os = "windows") {
Self::Windows
} else {
Self::Linux
}
}
/// Whether the target is mobile or not.
pub fn is_mobile(&self) -> bool {
matches!(self, Target::Android | Target::Ios)
}
/// Whether the target is desktop or not.
pub fn is_desktop(&self) -> bool {
!self.is_mobile()
}
}
/// Retrieves the currently running binary's path, taking into account security considerations.
///
/// The path is cached as soon as possible (before even `main` runs) and that value is returned

View File

@ -23,6 +23,7 @@ use std::{
process::Command,
};
use tauri_bundler::bundle::{bundle_project, Bundle, PackageType};
use tauri_utils::platform::Target;
#[derive(Debug, Clone, Parser)]
#[clap(about = "Tauri build")]
@ -65,9 +66,15 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
options.ci = options.ci || std::env::var("CI").is_ok();
let ci = options.ci;
let mut interface = setup(&mut options, false)?;
let target = options
.target
.as_deref()
.map(Target::from_triple)
.unwrap_or_else(Target::current);
let config = get_config(options.config.as_deref())?;
let mut interface = setup(target, &mut options, false)?;
let config = get_config(target, options.config.as_deref())?;
let config_guard = config.lock().unwrap();
let config_ = config_guard.as_ref().unwrap();
@ -208,11 +215,11 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
Ok(())
}
pub fn setup(options: &mut Options, mobile: bool) -> Result<AppInterface> {
pub fn setup(target: Target, options: &mut Options, mobile: bool) -> Result<AppInterface> {
let (merge_config, merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let config = get_config(options.config.as_deref())?;
let config = get_config(target, options.config.as_deref())?;
let tauri_path = tauri_dir();
set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;

View File

@ -18,6 +18,7 @@ use clap::{ArgAction, Parser};
use log::{error, info, warn};
use once_cell::sync::OnceCell;
use shared_child::SharedChild;
use tauri_utils::platform::Target;
use std::{
env::set_current_dir,
@ -84,7 +85,12 @@ pub fn command(options: Options) -> Result<()> {
}
fn command_internal(mut options: Options) -> Result<()> {
let mut interface = setup(&mut options, false)?;
let target = options
.target
.as_deref()
.map(Target::from_triple)
.unwrap_or_else(Target::current);
let mut interface = setup(target, &mut options, false)?;
let exit_on_panic = options.exit_on_panic;
let no_watch = options.no_watch;
interface.dev(options.into(), move |status, reason| {
@ -135,11 +141,11 @@ pub fn local_ip_address(force: bool) -> &'static IpAddr {
})
}
pub fn setup(options: &mut Options, mobile: bool) -> Result<AppInterface> {
pub fn setup(target: Target, options: &mut Options, mobile: bool) -> Result<AppInterface> {
let (merge_config, _merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let config = get_config(options.config.as_deref())?;
let config = get_config(target, options.config.as_deref())?;
let tauri_path = tauri_dir();
set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;

View File

@ -12,8 +12,9 @@ use std::{
use ignore::WalkBuilder;
use once_cell::sync::Lazy;
use tauri_utils::config::parse::{
folder_has_configuration_file, is_configuration_file, ConfigFormat,
use tauri_utils::{
config::parse::{folder_has_configuration_file, is_configuration_file, ConfigFormat},
platform::Target,
};
const TAURI_GITIGNORE: &[u8] = include_bytes!("../../tauri.gitignore");
@ -73,7 +74,7 @@ fn get_tauri_dir() -> PathBuf {
return cwd.join("src-tauri/");
}
lookup(&cwd, |path| folder_has_configuration_file(path) || is_configuration_file(path))
lookup(&cwd, |path| folder_has_configuration_file(Target::Linux, path) || is_configuration_file(Target::Linux, path))
.map(|p| if p.is_dir() { p } else { p.parent().unwrap().to_path_buf() })
.unwrap_or_else(||
panic!("Couldn't recognize the current folder as a Tauri project. It must contain a `{}`, `{}` or `{}` file in any subfolder.",

View File

@ -8,7 +8,7 @@ use log::error;
use once_cell::sync::Lazy;
use serde_json::Value as JsonValue;
pub use tauri_utils::config::*;
pub use tauri_utils::{config::*, platform::Target};
use std::{
collections::HashMap,
@ -21,6 +21,8 @@ use std::{
pub const MERGE_CONFIG_EXTENSION_NAME: &str = "--config";
pub struct ConfigMetadata {
/// The current target.
target: Target,
/// The actual configuration, merged with any extension.
inner: Config,
/// The config extensions (platform-specific config files or the config CLI argument).
@ -117,19 +119,23 @@ fn config_handle() -> &'static ConfigHandle {
}
/// Gets the static parsed config from `tauri.conf.json`.
fn get_internal(merge_config: Option<&str>, reload: bool) -> crate::Result<ConfigHandle> {
fn get_internal(
merge_config: Option<&str>,
reload: bool,
target: Target,
) -> crate::Result<ConfigHandle> {
if !reload && config_handle().lock().unwrap().is_some() {
return Ok(config_handle().clone());
}
let tauri_dir = super::app_paths::tauri_dir();
let (mut config, config_path) =
tauri_utils::config::parse::parse_value(tauri_dir.join("tauri.conf.json"))?;
tauri_utils::config::parse::parse_value(target, tauri_dir.join("tauri.conf.json"))?;
let config_file_name = config_path.file_name().unwrap().to_string_lossy();
let mut extensions = HashMap::new();
if let Some((platform_config, config_path)) =
tauri_utils::config::parse::read_platform(tauri_dir)?
tauri_utils::config::parse::read_platform(target, tauri_dir)?
{
merge(&mut config, &platform_config);
extensions.insert(
@ -186,6 +192,7 @@ fn get_internal(merge_config: Option<&str>, reload: bool) -> crate::Result<Confi
}
*config_handle().lock().unwrap() = Some(ConfigMetadata {
target,
inner: config,
extensions,
});
@ -193,10 +200,14 @@ fn get_internal(merge_config: Option<&str>, reload: bool) -> crate::Result<Confi
Ok(config_handle().clone())
}
pub fn get(merge_config: Option<&str>) -> crate::Result<ConfigHandle> {
get_internal(merge_config, false)
pub fn get(target: Target, merge_config: Option<&str>) -> crate::Result<ConfigHandle> {
get_internal(merge_config, false, target)
}
pub fn reload(merge_config: Option<&str>) -> crate::Result<ConfigHandle> {
get_internal(merge_config, true)
if let Some(conf) = &*config_handle().lock().unwrap() {
get_internal(merge_config, true, conf.target)
} else {
Err(anyhow::anyhow!("config not loaded"))
}
}

View File

@ -27,6 +27,7 @@ use image::{
open, ColorType, DynamicImage, ImageBuffer, ImageEncoder, Rgba,
};
use serde::Deserialize;
use tauri_utils::platform::Target;
#[derive(Debug, Deserialize)]
struct IcnsEntry {
@ -362,7 +363,7 @@ fn png(source: &DynamicImage, out_dir: &Path, ios_color: Rgba<u8>) -> Result<()>
// Android
let (config, _metadata) = {
let tauri_config = get_tauri_config(None)?;
let tauri_config = get_tauri_config(Target::current(), None)?;
let tauri_config_guard = tauri_config.lock().unwrap();
let tauri_config_ = tauri_config_guard.as_ref().unwrap();

View File

@ -8,11 +8,12 @@ use std::{
fs::read_to_string,
path::{Path, PathBuf},
};
use tauri_utils::platform::Target;
pub fn items(app_dir: Option<&PathBuf>, tauri_dir: Option<&Path>) -> Vec<SectionItem> {
let mut items = Vec::new();
if tauri_dir.is_some() {
if let Ok(config) = crate::helpers::config::get(None) {
if let Ok(config) = crate::helpers::config::get(Target::current(), None) {
let config_guard = config.lock().unwrap();
let config = config_guard.as_ref().unwrap();

View File

@ -32,7 +32,7 @@ use crate::helpers::{
app_paths::{app_dir, tauri_dir},
config::{nsis_settings, reload as reload_config, wix_settings, Config},
};
use tauri_utils::display_path;
use tauri_utils::{display_path, platform::Target};
mod cargo_config;
mod desktop;
@ -90,7 +90,7 @@ pub struct MobileOptions {
}
#[derive(Debug)]
pub struct Target {
pub struct RustupTarget {
name: String,
installed: bool,
}
@ -99,7 +99,7 @@ pub struct Rust {
app_settings: RustAppSettings,
config_features: Vec<String>,
product_name: Option<String>,
available_targets: Option<Vec<Target>>,
available_targets: Option<Vec<RustupTarget>>,
}
impl Interface for Rust {
@ -510,7 +510,7 @@ impl Rust {
let event_path = event.path;
if !ignore_matcher.is_ignore(&event_path, event_path.is_dir()) {
if is_configuration_file(&event_path) {
if is_configuration_file(self.app_settings.target, &event_path) {
match reload_config(config.as_deref()) {
Ok(config) => {
info!("Tauri configuration changed. Rewriting manifest...");
@ -685,6 +685,7 @@ pub struct RustAppSettings {
package_settings: PackageSettings,
cargo_config: CargoConfig,
target_triple: String,
target: Target,
}
impl AppSettings for RustAppSettings {
@ -954,6 +955,7 @@ impl RustAppSettings {
.to_string()
})
});
let target = Target::from_triple(&target_triple);
Ok(Self {
manifest,
@ -962,6 +964,7 @@ impl RustAppSettings {
package_settings,
cargo_config,
target_triple,
target,
})
}

View File

@ -2,7 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use super::{get_profile, AppSettings, DevProcess, ExitReason, Options, RustAppSettings, Target};
use super::{
get_profile, AppSettings, DevProcess, ExitReason, Options, RustAppSettings, RustupTarget,
};
use crate::CommandExt;
use tauri_utils::display_path;
@ -69,7 +71,7 @@ impl DevProcess for DevChild {
pub fn run_dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
options: Options,
run_args: Vec<String>,
available_targets: &mut Option<Vec<Target>>,
available_targets: &mut Option<Vec<RustupTarget>>,
config_features: Vec<String>,
app_settings: &RustAppSettings,
product_name: Option<String>,
@ -135,7 +137,7 @@ pub fn build(
options: Options,
app_settings: &RustAppSettings,
product_name: Option<String>,
available_targets: &mut Option<Vec<Target>>,
available_targets: &mut Option<Vec<RustupTarget>>,
config_features: Vec<String>,
) -> crate::Result<()> {
let bin_path = app_settings.app_binary_path(&options)?;
@ -194,7 +196,7 @@ pub fn build(
fn build_dev_app<F: FnOnce(Option<i32>, ExitReason) + Send + 'static>(
options: Options,
available_targets: &mut Option<Vec<Target>>,
available_targets: &mut Option<Vec<RustupTarget>>,
config_features: Vec<String>,
on_exit: F,
) -> crate::Result<Arc<SharedChild>> {
@ -288,7 +290,7 @@ fn build_dev_app<F: FnOnce(Option<i32>, ExitReason) + Send + 'static>(
fn build_production_app(
options: Options,
available_targets: &mut Option<Vec<Target>>,
available_targets: &mut Option<Vec<RustupTarget>>,
config_features: Vec<String>,
) -> crate::Result<()> {
let mut build_cmd = build_command(options, available_targets, config_features)?;
@ -311,7 +313,7 @@ fn build_production_app(
fn build_command(
options: Options,
available_targets: &mut Option<Vec<Target>>,
available_targets: &mut Option<Vec<RustupTarget>>,
config_features: Vec<String>,
) -> crate::Result<Command> {
let runner = options.runner.unwrap_or_else(|| "cargo".into());
@ -353,7 +355,7 @@ fn build_command(
Ok(build_cmd)
}
fn fetch_available_targets() -> Option<Vec<Target>> {
fn fetch_available_targets() -> Option<Vec<RustupTarget>> {
if let Ok(output) = Command::new("rustup").args(["target", "list"]).output() {
let stdout = String::from_utf8_lossy(&output.stdout).into_owned();
Some(
@ -363,7 +365,7 @@ fn fetch_available_targets() -> Option<Vec<Target>> {
let mut s = t.split(' ');
let name = s.next().unwrap().to_string();
let installed = s.next().map(|v| v == "(installed)").unwrap_or_default();
Target { name, installed }
RustupTarget { name, installed }
})
.filter(|t| !t.name.is_empty())
.collect(),
@ -373,7 +375,10 @@ fn fetch_available_targets() -> Option<Vec<Target>> {
}
}
fn validate_target(available_targets: &Option<Vec<Target>>, target: &str) -> crate::Result<()> {
fn validate_target(
available_targets: &Option<Vec<RustupTarget>>,
target: &str,
) -> crate::Result<()> {
if let Some(available_targets) = available_targets {
if let Some(target) = available_targets.iter().find(|t| t.name == target) {
if !target.installed {

View File

@ -36,7 +36,7 @@ pub fn command(options: Options) -> Result<()> {
Profile::Debug
};
let tauri_config = get_tauri_config(None)?;
let tauri_config = get_tauri_config(tauri_utils::platform::Target::Android, None)?;
let (config, metadata, cli_options) = {
let tauri_config_guard = tauri_config.lock().unwrap();

View File

@ -84,7 +84,10 @@ pub fn command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
let (merge_config, _merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let tauri_config = get_tauri_config(options.config.as_deref())?;
let tauri_config = get_tauri_config(
tauri_utils::platform::Target::Android,
options.config.as_deref(),
)?;
let (app, config, metadata) = {
let tauri_config_guard = tauri_config.lock().unwrap();
let tauri_config_ = tauri_config_guard.as_ref().unwrap();
@ -163,7 +166,11 @@ fn run_build(
.triple
.into(),
);
let interface = crate::build::setup(&mut build_options, true)?;
let interface = crate::build::setup(
tauri_utils::platform::Target::Android,
&mut build_options,
true,
)?;
let interface_options = InterfaceOptions {
debug: build_options.debug,

View File

@ -110,7 +110,10 @@ fn run_command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
let (merge_config, _merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let tauri_config = get_tauri_config(options.config.as_deref())?;
let tauri_config = get_tauri_config(
tauri_utils::platform::Target::Android,
options.config.as_deref(),
)?;
let (app, config, metadata) = {
let tauri_config_guard = tauri_config.lock().unwrap();
@ -141,7 +144,11 @@ fn run_dev(
metadata: &AndroidMetadata,
noise_level: NoiseLevel,
) -> Result<()> {
setup_dev_config(&mut options.config, options.force_ip_prompt)?;
setup_dev_config(
MobileTarget::Android,
&mut options.config,
options.force_ip_prompt,
)?;
let mut env = env()?;
let device = if options.open {
None
@ -161,7 +168,11 @@ fn run_dev(
.map(|d| d.target().triple.to_string())
.unwrap_or_else(|| Target::all().values().next().unwrap().triple.into());
dev_options.target = Some(target_triple.clone());
let mut interface = crate::dev::setup(&mut dev_options, true)?;
let mut interface = crate::dev::setup(
tauri_utils::platform::Target::Android,
&mut dev_options,
true,
)?;
let interface_options = InterfaceOptions {
debug: !dev_options.release_mode,

View File

@ -8,7 +8,7 @@ use crate::{helpers::config::get as get_tauri_config, Result};
use tauri_mobile::os;
pub fn command() -> Result<()> {
let tauri_config = get_tauri_config(None)?;
let tauri_config = get_tauri_config(tauri_utils::platform::Target::Android, None)?;
let (config, _metadata) = {
let tauri_config_guard = tauri_config.lock().unwrap();

View File

@ -88,7 +88,7 @@ pub fn exec(
skip_targets_install: bool,
) -> Result<App> {
let current_dir = current_dir()?;
let tauri_config = get_tauri_config(None)?;
let tauri_config = get_tauri_config(target.platform_target(), None)?;
let tauri_config_guard = tauri_config.lock().unwrap();
let tauri_config_ = tauri_config_guard.as_ref().unwrap();

View File

@ -78,7 +78,10 @@ pub fn command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
let (merge_config, _merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let tauri_config = get_tauri_config(options.config.as_deref())?;
let tauri_config = get_tauri_config(
tauri_utils::platform::Target::Ios,
options.config.as_deref(),
)?;
let (app, config) = {
let tauri_config_guard = tauri_config.lock().unwrap();
let tauri_config_ = tauri_config_guard.as_ref().unwrap();
@ -127,7 +130,8 @@ fn run_build(
.triple
.into(),
);
let interface = crate::build::setup(&mut build_options, true)?;
let interface =
crate::build::setup(tauri_utils::platform::Target::Ios, &mut build_options, true)?;
let app_settings = interface.app_settings();
let bin_path = app_settings.app_binary_path(&InterfaceOptions {

View File

@ -126,7 +126,10 @@ fn run_command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
let (merge_config, _merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let tauri_config = get_tauri_config(options.config.as_deref())?;
let tauri_config = get_tauri_config(
tauri_utils::platform::Target::Ios,
options.config.as_deref(),
)?;
let (app, config) = {
let tauri_config_guard = tauri_config.lock().unwrap();
let tauri_config_ = tauri_config_guard.as_ref().unwrap();
@ -150,7 +153,11 @@ fn run_dev(
config: &AppleConfig,
noise_level: NoiseLevel,
) -> Result<()> {
setup_dev_config(&mut options.config, options.force_ip_prompt)?;
setup_dev_config(
MobileTarget::Ios,
&mut options.config,
options.force_ip_prompt,
)?;
let env = env()?;
let device = if options.open {
None
@ -171,7 +178,8 @@ fn run_dev(
.map(|d| d.target().triple.to_string())
.unwrap_or_else(|| "aarch64-apple-ios".into()),
);
let mut interface = crate::dev::setup(&mut dev_options, true)?;
let mut interface =
crate::dev::setup(tauri_utils::platform::Target::Ios, &mut dev_options, true)?;
let app_settings = interface.app_settings();
let bin_path = app_settings.app_binary_path(&InterfaceOptions {

View File

@ -8,7 +8,7 @@ use crate::{helpers::config::get as get_tauri_config, Result};
use tauri_mobile::os;
pub fn command() -> Result<()> {
let tauri_config = get_tauri_config(None)?;
let tauri_config = get_tauri_config(tauri_utils::platform::Target::Ios, None)?;
let (config, _metadata) = {
let tauri_config_guard = tauri_config.lock().unwrap();

View File

@ -68,7 +68,7 @@ pub fn command(options: Options) -> Result<()> {
let profile = profile_from_configuration(&options.configuration);
let macos = macos_from_platform(&options.platform);
let tauri_config = get_tauri_config(None)?;
let tauri_config = get_tauri_config(tauri_utils::platform::Target::Ios, None)?;
let (config, metadata, cli_options) = {
let tauri_config_guard = tauri_config.lock().unwrap();

View File

@ -123,6 +123,14 @@ impl Target {
Self::Ios => "xcode-script",
}
}
fn platform_target(&self) -> tauri_utils::platform::Target {
match self {
Self::Android => tauri_utils::platform::Target::Android,
#[cfg(target_os = "macos")]
Self::Ios => tauri_utils::platform::Target::Ios,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -145,10 +153,11 @@ impl Default for CliOptions {
}
fn setup_dev_config(
target: Target,
config_extension: &mut Option<String>,
force_ip_prompt: bool,
) -> crate::Result<()> {
let config = get_config(config_extension.as_deref())?;
let config = get_config(target.platform_target(), config_extension.as_deref())?;
let mut dev_path = config
.lock()