mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-11-28 20:48:52 +03:00
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
parent
3c66a53a9e
commit
100d9ede35
6
.changes/cli-config-target-mobile.md
Normal file
6
.changes/cli-config-target-mobile.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-cli": patch:bug
|
||||
"@tauri-apps/cli": patch:bug
|
||||
---
|
||||
|
||||
Properly read platform-specific configuration files for mobile targets.
|
6
.changes/codegen-target-from-utils.md
Normal file
6
.changes/codegen-target-from-utils.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-codegen": patch:enhance
|
||||
"tauri-macros": patch:enhance
|
||||
---
|
||||
|
||||
Use `Target` enum from `tauri_utils::platform`.
|
5
.changes/mobile-config-naming-conventions.md
Normal file
5
.changes/mobile-config-naming-conventions.md
Normal 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.
|
@ -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") {
|
||||
|
@ -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)
|
||||
|
@ -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)?;
|
||||
|
@ -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!(
|
||||
|
@ -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()
|
||||
});
|
||||
|
@ -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
|
||||
|
@ -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")?;
|
||||
|
@ -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")?;
|
||||
|
@ -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.",
|
||||
|
@ -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"))
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user