Skip to content

Commit

Permalink
fix(core): Correctly detect Android Tauri configuration file, closes #…
Browse files Browse the repository at this point in the history
…7785 (#7802)

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
  • Loading branch information
i-c-b and lucasfernog authored Sep 12, 2023
1 parent 3c66a53 commit 100d9ed
Show file tree
Hide file tree
Showing 27 changed files with 269 additions and 165 deletions.
6 changes: 6 additions & 0 deletions .changes/cli-config-target-mobile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-cli": patch:bug
"@tauri-apps/cli": patch:bug
---

Properly read platform-specific configuration files for mobile targets.
6 changes: 6 additions & 0 deletions .changes/codegen-target-from-utils.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-codegen": patch:enhance
"tauri-macros": patch:enhance
---

Use `Target` enum from `tauri_utils::platform`.
5 changes: 5 additions & 0 deletions .changes/mobile-config-naming-conventions.md
Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions core/tauri-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down
54 changes: 6 additions & 48 deletions core/tauri-codegen/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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 {
Expand All @@ -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)
Expand Down
5 changes: 4 additions & 1 deletion core/tauri-codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand Down
10 changes: 8 additions & 2 deletions core/tauri-macros/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 {
Expand All @@ -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!(
Expand Down
124 changes: 58 additions & 66 deletions core/tauri-utils/src/config/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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",
},
}
}
}
Expand Down Expand Up @@ -154,28 +137,28 @@ 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| {
file_name == OsStr::new(ConfigFormat::Json.into_file_name())
|| 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()
}
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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()
})
Expand All @@ -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()
});
Expand Down
Loading

0 comments on commit 100d9ed

Please sign in to comment.