Просмотр исходного кода

fix(cli): make app_dir() logic consistent (#10418)

* fix(cli): Make app_dir() consistent by basing it on the explicit invocation directory rather than the current working directory

* resolve app paths before everything else

* fix xcode script

* fix test

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
Sam Kearney 1 год назад
Родитель
Сommit
2d47352a07

+ 6 - 0
.changes/cli-make-app-dir-consistent.md

@@ -0,0 +1,6 @@
+---
+"tauri-cli": patch:bug
+"@tauri-apps/cli": patch:bug
+---
+
+CLI commands will now consistently search for the `app_dir` (the directory containing `package.json`) from the current working directory of the command invocation.

+ 31 - 10
examples/api/src-tauri/Cargo.lock

@@ -801,6 +801,15 @@ dependencies = [
  "miniz_oxide",
 ]
 
+[[package]]
+name = "fluent-uri"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
 [[package]]
 name = "fnv"
 version = "1.0.7"
@@ -1562,15 +1571,27 @@ dependencies = [
 
 [[package]]
 name = "json-patch"
-version = "1.4.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b"
+checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc"
 dependencies = [
+ "jsonptr",
  "serde",
  "serde_json",
  "thiserror",
 ]
 
+[[package]]
+name = "jsonptr"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c6e529149475ca0b2820835d3dce8fcc41c6b943ca608d32f35b449255e4627"
+dependencies = [
+ "fluent-uri",
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "keyboard-types"
 version = "0.7.0"
@@ -3033,7 +3054,7 @@ checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
 
 [[package]]
 name = "tauri"
-version = "2.0.0-rc.0"
+version = "2.0.0-rc.2"
 dependencies = [
  "anyhow",
  "bytes",
@@ -3083,7 +3104,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-build"
-version = "2.0.0-rc.0"
+version = "2.0.0-rc.2"
 dependencies = [
  "anyhow",
  "cargo_toml",
@@ -3105,7 +3126,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-codegen"
-version = "2.0.0-rc.0"
+version = "2.0.0-rc.2"
 dependencies = [
  "base64 0.22.1",
  "brotli",
@@ -3130,7 +3151,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-macros"
-version = "2.0.0-rc.0"
+version = "2.0.0-rc.2"
 dependencies = [
  "heck 0.5.0",
  "proc-macro2",
@@ -3142,7 +3163,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-plugin"
-version = "2.0.0-rc.0"
+version = "2.0.0-rc.2"
 dependencies = [
  "anyhow",
  "glob",
@@ -3168,7 +3189,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-runtime"
-version = "2.0.0-rc.0"
+version = "2.0.0-rc.2"
 dependencies = [
  "dpi",
  "gtk",
@@ -3185,7 +3206,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-runtime-wry"
-version = "2.0.0-rc.0"
+version = "2.0.0-rc.2"
 dependencies = [
  "cocoa",
  "gtk",
@@ -3207,7 +3228,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-utils"
-version = "2.0.0-rc.0"
+version = "2.0.0-rc.2"
 dependencies = [
  "aes-gcm",
  "brotli",

+ 2 - 0
tooling/cli/src/acl/capability/new.rs

@@ -36,6 +36,8 @@ pub struct Options {
 }
 
 pub fn command(options: Options) -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let identifier = match options.identifier {
     Some(i) => i,
     None => prompts::input("What's the capability identifier?", None, false, false)?.unwrap(),

+ 2 - 2
tooling/cli/src/acl/permission/add.rs

@@ -7,7 +7,7 @@ use std::path::Path;
 use clap::Parser;
 
 use crate::{
-  helpers::{app_paths::tauri_dir_opt, prompts},
+  helpers::{app_paths::resolve_tauri_dir, prompts},
   Result,
 };
 
@@ -87,7 +87,7 @@ pub struct Options {
 }
 
 pub fn command(options: Options) -> Result<()> {
-  let dir = match tauri_dir_opt() {
+  let dir = match resolve_tauri_dir() {
     Some(t) => t,
     None => std::env::current_dir()?,
   };

+ 2 - 0
tooling/cli/src/acl/permission/ls.rs

@@ -21,6 +21,8 @@ pub struct Options {
 }
 
 pub fn command(options: Options) -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let tauri_dir = tauri_dir();
   let acl_manifests_path = tauri_dir
     .join("gen")

+ 2 - 2
tooling/cli/src/acl/permission/new.rs

@@ -8,7 +8,7 @@ use clap::Parser;
 
 use crate::{
   acl::FileFormat,
-  helpers::{app_paths::tauri_dir_opt, prompts},
+  helpers::{app_paths::resolve_tauri_dir, prompts},
   Result,
 };
 
@@ -69,7 +69,7 @@ pub fn command(options: Options) -> Result<()> {
   let path = match options.out {
     Some(o) => o.canonicalize()?,
     None => {
-      let dir = match tauri_dir_opt() {
+      let dir = match resolve_tauri_dir() {
         Some(t) => t,
         None => std::env::current_dir()?,
       };

+ 2 - 2
tooling/cli/src/acl/permission/rm.rs

@@ -7,7 +7,7 @@ use std::path::Path;
 use clap::Parser;
 use tauri_utils::acl::{manifest::PermissionFile, PERMISSION_SCHEMA_FILE_NAME};
 
-use crate::{acl::FileFormat, helpers::app_paths::tauri_dir_opt, Result};
+use crate::{acl::FileFormat, helpers::app_paths::resolve_tauri_dir, Result};
 
 fn rm_permission_files(identifier: &str, dir: &Path) -> Result<()> {
   for entry in std::fs::read_dir(dir)?.flatten() {
@@ -126,7 +126,7 @@ pub fn command(options: Options) -> Result<()> {
     rm_permission_files(&options.identifier, &permissions_dir)?;
   }
 
-  if let Some(tauri_dir) = tauri_dir_opt() {
+  if let Some(tauri_dir) = resolve_tauri_dir() {
     let capabilities_dir = tauri_dir.join("capabilities");
     if capabilities_dir.exists() {
       rm_permission_from_capabilities(&options.identifier, &capabilities_dir)?;

+ 8 - 7
tooling/cli/src/add.rs

@@ -9,7 +9,7 @@ use regex::Regex;
 use crate::{
   acl,
   helpers::{
-    app_paths::{app_dir, tauri_dir},
+    app_paths::{resolve_app_dir, tauri_dir},
     cargo,
     npm::PackageManager,
   },
@@ -92,6 +92,8 @@ pub struct Options {
 }
 
 pub fn command(options: Options) -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let (plugin, version) = options
     .plugin
     .split_once('@')
@@ -105,6 +107,7 @@ pub fn command(options: Options) -> Result<()> {
   let mut plugins = plugins();
   let metadata = plugins.remove(plugin).unwrap_or_default();
 
+  let app_dir = resolve_app_dir();
   let tauri_dir = tauri_dir();
 
   let target_str = metadata
@@ -122,14 +125,12 @@ pub fn command(options: Options) -> Result<()> {
     branch: options.branch.as_deref(),
     rev: options.rev.as_deref(),
     tag: options.tag.as_deref(),
-    cwd: Some(&tauri_dir),
+    cwd: Some(tauri_dir),
     target: target_str,
   })?;
 
   if !metadata.rust_only {
-    if let Some(manager) = std::panic::catch_unwind(app_dir)
-      .map(Some)
-      .unwrap_or_default()
+    if let Some(manager) = app_dir
       .map(PackageManager::from_project)
       .and_then(|managers| managers.into_iter().next())
     {
@@ -149,7 +150,7 @@ pub fn command(options: Options) -> Result<()> {
         (None, None, None, None) => npm_name,
         _ => anyhow::bail!("Only one of --tag, --rev and --branch can be specified"),
       };
-      manager.install(&[npm_spec], &tauri_dir)?;
+      manager.install(&[npm_spec], tauri_dir)?;
     }
 
     let _ = acl::permission::add::command(acl::permission::add::Options {
@@ -193,7 +194,7 @@ pub fn command(options: Options) -> Result<()> {
         log::info!("Running `cargo fmt`...");
         let _ = Command::new("cargo")
           .arg("fmt")
-          .current_dir(&tauri_dir)
+          .current_dir(tauri_dir)
           .status();
       }
 

+ 2 - 0
tooling/cli/src/build.rs

@@ -58,6 +58,8 @@ pub struct Options {
 }
 
 pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let ci = options.ci;
 
   let target = options

+ 3 - 0
tooling/cli/src/bundle.rs

@@ -94,6 +94,8 @@ impl From<crate::build::Options> for Options {
 }
 
 pub fn command(options: Options, verbosity: u8) -> crate::Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let ci = options.ci;
 
   let target = options
@@ -133,6 +135,7 @@ pub fn command(options: Options, verbosity: u8) -> crate::Result<()> {
   )
 }
 
+#[allow(clippy::too_many_arguments)]
 pub fn bundle<A: AppSettings>(
   options: &Options,
   verbosity: u8,

+ 2 - 0
tooling/cli/src/dev.rs

@@ -88,6 +88,8 @@ pub struct Options {
 }
 
 pub fn command(options: Options) -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let r = command_internal(options);
   if r.is_err() {
     kill_before_dev_process();

+ 18 - 8
tooling/cli/src/helpers/app_paths.rs

@@ -18,6 +18,8 @@ use tauri_utils::{
 };
 
 const TAURI_GITIGNORE: &[u8] = include_bytes!("../../tauri.gitignore");
+static APP_DIR: OnceLock<PathBuf> = OnceLock::new();
+static TAURI_DIR: OnceLock<PathBuf> = OnceLock::new();
 
 pub fn walk_builder(path: &Path) -> WalkBuilder {
   let mut default_gitignore = std::env::temp_dir();
@@ -66,7 +68,7 @@ fn lookup<F: Fn(&PathBuf) -> bool>(dir: &Path, checker: F) -> Option<PathBuf> {
   None
 }
 
-pub fn tauri_dir_opt() -> Option<PathBuf> {
+pub fn resolve_tauri_dir() -> Option<PathBuf> {
   let Ok(cwd) = current_dir() else {
     return None;
   };
@@ -100,19 +102,27 @@ pub fn tauri_dir_opt() -> Option<PathBuf> {
   })
 }
 
-pub fn tauri_dir() -> PathBuf {
-  tauri_dir_opt().unwrap_or_else(||
+pub fn resolve() {
+  TAURI_DIR.set(resolve_tauri_dir().unwrap_or_else(||
     panic!("Couldn't recognize the current folder as a Tauri project. It must contain a `{}`, `{}` or `{}` file in any subfolder.",
       ConfigFormat::Json.into_file_name(),
       ConfigFormat::Json5.into_file_name(),
       ConfigFormat::Toml.into_file_name()
     )
-  )
+  )).expect("tauri dir already resolved");
+  APP_DIR
+    .set(resolve_app_dir().unwrap_or_else(|| tauri_dir().parent().unwrap().to_path_buf()))
+    .expect("app dir already resolved");
 }
 
-fn get_app_dir() -> Option<PathBuf> {
-  let cwd = current_dir().expect("failed to read cwd");
+pub fn tauri_dir() -> &'static PathBuf {
+  TAURI_DIR
+    .get()
+    .expect("app paths not initialized, this is a Tauri CLI bug")
+}
 
+pub fn resolve_app_dir() -> Option<PathBuf> {
+  let cwd = current_dir().expect("failed to read cwd");
   if cwd.join("package.json").exists() {
     return Some(cwd);
   }
@@ -128,7 +138,7 @@ fn get_app_dir() -> Option<PathBuf> {
 }
 
 pub fn app_dir() -> &'static PathBuf {
-  static APP_DIR: OnceLock<PathBuf> = OnceLock::new();
   APP_DIR
-    .get_or_init(|| get_app_dir().unwrap_or_else(|| tauri_dir().parent().unwrap().to_path_buf()))
+    .get()
+    .expect("app paths not initialized, this is a Tauri CLI bug")
 }

+ 1 - 1
tooling/cli/src/helpers/config.rs

@@ -132,7 +132,7 @@ fn get_internal(
   let mut extensions = HashMap::new();
 
   if let Some((platform_config, config_path)) =
-    tauri_utils::config::parse::read_platform(target, tauri_dir)?
+    tauri_utils::config::parse::read_platform(target, tauri_dir.to_path_buf())?
   {
     merge(&mut config, &platform_config);
     extensions.insert(

+ 4 - 1
tooling/cli/src/icon.rs

@@ -100,7 +100,10 @@ impl Source {
 
 pub fn command(options: Options) -> Result<()> {
   let input = options.input;
-  let out_dir = options.output.unwrap_or_else(|| tauri_dir().join("icons"));
+  let out_dir = options.output.unwrap_or_else(|| {
+    crate::helpers::app_paths::resolve();
+    tauri_dir().join("icons")
+  });
   let png_icon_sizes = options.png.unwrap_or_default();
   let ios_color = css_color::Srgb::from_str(&options.ios_color)
     .map(|color| {

+ 15 - 18
tooling/cli/src/info/mod.rs

@@ -7,10 +7,7 @@ use clap::Parser;
 use colored::{ColoredString, Colorize};
 use dialoguer::{theme::ColorfulTheme, Confirm};
 use serde::Deserialize;
-use std::{
-  fmt::{self, Display, Formatter},
-  panic,
-};
+use std::fmt::{self, Display, Formatter};
 
 mod app;
 mod env_nodejs;
@@ -259,17 +256,15 @@ pub struct Options {
 
 pub fn command(options: Options) -> Result<()> {
   let Options { interactive } = options;
-  let hook = panic::take_hook();
-  panic::set_hook(Box::new(|_info| {
-    // do nothing
-  }));
-  let app_dir = panic::catch_unwind(crate::helpers::app_paths::app_dir)
-    .map(Some)
-    .unwrap_or_default();
-  let tauri_dir = panic::catch_unwind(crate::helpers::app_paths::tauri_dir)
-    .map(Some)
-    .unwrap_or_default();
-  panic::set_hook(hook);
+
+  let app_dir = crate::helpers::app_paths::resolve_app_dir();
+  let tauri_dir = crate::helpers::app_paths::resolve_tauri_dir();
+
+  if tauri_dir.is_some() {
+    // safe to initialize
+    crate::helpers::app_paths::resolve();
+  }
+
   let metadata = version_metadata()?;
 
   let mut environment = Section {
@@ -289,17 +284,19 @@ pub fn command(options: Options) -> Result<()> {
   };
   packages
     .items
-    .extend(packages_rust::items(app_dir, tauri_dir.as_deref()));
+    .extend(packages_rust::items(app_dir.as_ref(), tauri_dir.as_deref()));
   packages
     .items
-    .extend(packages_nodejs::items(app_dir, &metadata));
+    .extend(packages_nodejs::items(app_dir.as_ref(), &metadata));
 
   let mut app = Section {
     label: "App",
     interactive,
     items: Vec::new(),
   };
-  app.items.extend(app::items(app_dir, tauri_dir.as_deref()));
+  app
+    .items
+    .extend(app::items(app_dir.as_ref(), tauri_dir.as_deref()));
 
   environment.display();
   packages.display();

+ 4 - 3
tooling/cli/src/interface/rust.rs

@@ -905,7 +905,7 @@ impl AppSettings for RustAppSettings {
       }
     }
 
-    let mut bins_path = tauri_dir();
+    let mut bins_path = tauri_dir().to_path_buf();
     bins_path.push("src/bin");
     if let Ok(fs_bins) = std::fs::read_dir(bins_path) {
       for entry in fs_bins {
@@ -977,7 +977,7 @@ impl AppSettings for RustAppSettings {
 impl RustAppSettings {
   pub fn new(config: &Config, manifest: Manifest, target: Option<String>) -> crate::Result<Self> {
     let cargo_settings =
-      CargoSettings::load(&tauri_dir()).with_context(|| "failed to load cargo settings")?;
+      CargoSettings::load(tauri_dir()).with_context(|| "failed to load cargo settings")?;
     let cargo_package_settings = match &cargo_settings.package {
       Some(package_info) => package_info.clone(),
       None => {
@@ -1051,7 +1051,7 @@ impl RustAppSettings {
       default_run: cargo_package_settings.default_run.clone(),
     };
 
-    let cargo_config = CargoConfig::load(&tauri_dir())?;
+    let cargo_config = CargoConfig::load(tauri_dir())?;
 
     let target_triple = target.unwrap_or_else(|| {
       cargo_config
@@ -1582,6 +1582,7 @@ mod tests {
 
   #[test]
   fn parse_target_dir_from_opts() {
+    crate::helpers::app_paths::resolve();
     let current_dir = std::env::current_dir().unwrap();
 
     let options = Options {

+ 3 - 3
tooling/cli/src/migrate/migrations/v1/mod.rs

@@ -17,9 +17,9 @@ pub fn run() -> Result<()> {
   let tauri_dir = tauri_dir();
   let app_dir = app_dir();
 
-  let migrated = config::migrate(&tauri_dir).context("Could not migrate config")?;
-  manifest::migrate(&tauri_dir).context("Could not migrate manifest")?;
-  frontend::migrate(app_dir, &tauri_dir)?;
+  let migrated = config::migrate(tauri_dir).context("Could not migrate config")?;
+  manifest::migrate(tauri_dir).context("Could not migrate manifest")?;
+  frontend::migrate(app_dir, tauri_dir)?;
 
   // Add plugins
   for plugin in migrated.plugins {

+ 1 - 1
tooling/cli/src/migrate/migrations/v2_rc.rs

@@ -24,7 +24,7 @@ pub fn run() -> Result<()> {
   let (mut manifest, _) = read_manifest(&manifest_path)?;
   migrate_manifest(&mut manifest)?;
 
-  migrate_permissions(&tauri_dir)?;
+  migrate_permissions(tauri_dir)?;
 
   migrate_npm_dependencies(app_dir)?;
 

+ 3 - 1
tooling/cli/src/migrate/mod.rs

@@ -18,6 +18,8 @@ use anyhow::Context;
 mod migrations;
 
 pub fn command() -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let tauri_dir = tauri_dir();
 
   let manifest_contents =
@@ -36,7 +38,7 @@ pub fn command() -> Result<()> {
     None
   };
 
-  let tauri_version = crate_version(&tauri_dir, Some(&manifest), lock.as_ref(), "tauri").version;
+  let tauri_version = crate_version(tauri_dir, Some(&manifest), lock.as_ref(), "tauri").version;
   let tauri_version = semver::Version::from_str(&tauri_version)?;
 
   if tauri_version.major == 1 {

+ 2 - 0
tooling/cli/src/mobile/android/android_studio_script.rs

@@ -37,6 +37,8 @@ pub struct Options {
 }
 
 pub fn command(options: Options) -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let profile = if options.release {
     Profile::Release
   } else {

+ 2 - 0
tooling/cli/src/mobile/android/build.rs

@@ -86,6 +86,8 @@ impl From<Options> for BuildOptions {
 }
 
 pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   delete_codegen_vars();
 
   let mut build_options: BuildOptions = options.clone().into();

+ 2 - 0
tooling/cli/src/mobile/android/dev.rs

@@ -91,6 +91,8 @@ impl From<Options> for DevOptions {
 }
 
 pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let result = run_command(options, noise_level);
   if result.is_err() {
     crate::dev::kill_before_dev_process();

+ 9 - 6
tooling/cli/src/mobile/android/mod.rs

@@ -75,12 +75,15 @@ enum Commands {
 pub fn command(cli: Cli, verbosity: u8) -> Result<()> {
   let noise_level = NoiseLevel::from_occurrences(verbosity as u64);
   match cli.command {
-    Commands::Init(options) => init_command(
-      MobileTarget::Android,
-      options.ci,
-      false,
-      options.skip_targets_install,
-    )?,
+    Commands::Init(options) => {
+      crate::helpers::app_paths::resolve();
+      init_command(
+        MobileTarget::Android,
+        options.ci,
+        false,
+        options.skip_targets_install,
+      )?
+    }
     Commands::Dev(options) => dev::command(options, noise_level)?,
     Commands::Build(options) => build::command(options, noise_level)?,
     Commands::AndroidStudioScript(options) => android_studio_script::command(options)?,

+ 4 - 1
tooling/cli/src/mobile/ios/build.rs

@@ -117,6 +117,8 @@ impl From<Options> for BuildOptions {
 }
 
 pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let mut build_options: BuildOptions = options.clone().into();
   build_options.target = Some(
     Target::all()
@@ -154,7 +156,7 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
   };
 
   let tauri_path = tauri_dir();
-  set_current_dir(&tauri_path).with_context(|| "failed to change current working directory")?;
+  set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;
 
   ensure_init(
     &tauri_config,
@@ -248,6 +250,7 @@ fn create_export_options(
   (!plist.is_empty()).then(|| plist.into())
 }
 
+#[allow(clippy::too_many_arguments)]
 fn run_build(
   interface: AppInterface,
   options: Options,

+ 3 - 1
tooling/cli/src/mobile/ios/dev.rs

@@ -117,6 +117,8 @@ impl From<Options> for DevOptions {
 }
 
 pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
+  crate::helpers::app_paths::resolve();
+
   let result = run_command(options, noise_level);
   if result.is_err() {
     crate::dev::kill_before_dev_process();
@@ -166,7 +168,7 @@ fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
   };
 
   let tauri_path = tauri_dir();
-  set_current_dir(&tauri_path).with_context(|| "failed to change current working directory")?;
+  set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;
 
   ensure_init(
     &tauri_config,

+ 9 - 6
tooling/cli/src/mobile/ios/mod.rs

@@ -86,12 +86,15 @@ enum Commands {
 pub fn command(cli: Cli, verbosity: u8) -> Result<()> {
   let noise_level = NoiseLevel::from_occurrences(verbosity as u64);
   match cli.command {
-    Commands::Init(options) => init_command(
-      MobileTarget::Ios,
-      options.ci,
-      options.reinstall_deps,
-      options.skip_targets_install,
-    )?,
+    Commands::Init(options) => {
+      crate::helpers::app_paths::resolve();
+      init_command(
+        MobileTarget::Ios,
+        options.ci,
+        options.reinstall_deps,
+        options.skip_targets_install,
+      )?
+    }
     Commands::Dev(options) => dev::command(options, noise_level)?,
     Commands::Build(options) => build::command(options, noise_level)?,
     Commands::XcodeScript(options) => xcode_script::command(options)?,

+ 2 - 0
tooling/cli/src/mobile/ios/xcode_script.rs

@@ -66,6 +66,8 @@ pub fn command(options: Options) -> Result<()> {
     set_current_dir(current_dir()?.parent().unwrap().parent().unwrap()).unwrap();
   }
 
+  crate::helpers::app_paths::resolve();
+
   let profile = profile_from_configuration(&options.configuration);
   let macos = macos_from_platform(&options.platform);
 

+ 1 - 1
tooling/cli/src/mobile/mod.rs

@@ -268,7 +268,7 @@ pub fn get_app(config: &TauriConfig, interface: &AppInterface) -> App {
   };
 
   let app_settings = interface.app_settings();
-  App::from_raw(tauri_dir(), raw)
+  App::from_raw(tauri_dir().to_path_buf(), raw)
     .unwrap()
     .with_target_dir_resolver(move |target, profile| {
       let bin_path = app_settings