Skip to content

Commit

Permalink
fix(cli): Make app_dir() consistent by basing it on the explicit invo…
Browse files Browse the repository at this point in the history
…cation directory rather than the current working directory
  • Loading branch information
samkearney committed Aug 8, 2024
1 parent 5f56cb0 commit f1a44d9
Show file tree
Hide file tree
Showing 16 changed files with 131 additions and 35 deletions.
6 changes: 6 additions & 0 deletions .changes/cli-make-app-dir-consistent.md
Original file line number Diff line number Diff line change
@@ -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.
6 changes: 4 additions & 2 deletions tooling/cli/src/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use anyhow::Context;
use clap::Parser;
use colored::Colorize;
use regex::Regex;
Expand All @@ -16,7 +17,7 @@ use crate::{
Result,
};

use std::{collections::HashMap, process::Command};
use std::{collections::HashMap, env::current_dir, process::Command};

#[derive(Default)]
struct PluginMetadata {
Expand Down Expand Up @@ -102,6 +103,7 @@ pub fn command(options: Options) -> Result<()> {
let mut plugins = plugins();
let metadata = plugins.remove(plugin).unwrap_or_default();

let invocation_dir = current_dir().with_context(|| "failed to get current working directory")?;
let tauri_dir = tauri_dir();

let target_str = metadata
Expand All @@ -124,7 +126,7 @@ pub fn command(options: Options) -> Result<()> {
})?;

if !metadata.rust_only {
if let Some(manager) = std::panic::catch_unwind(app_dir)
if let Some(manager) = std::panic::catch_unwind(|| app_dir(&invocation_dir))
.map(Some)
.unwrap_or_default()
.map(PackageManager::from_project)
Expand Down
25 changes: 22 additions & 3 deletions tooling/cli/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ use crate::{
};
use anyhow::Context;
use clap::{ArgAction, Parser};
use std::env::set_current_dir;
use std::{
env::{current_dir, set_current_dir},
path::Path,
};
use tauri_utils::platform::Target;

#[derive(Debug, Clone, Parser)]
Expand Down Expand Up @@ -73,7 +76,15 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
options.target.clone(),
)?;

setup(&interface, &mut options, config.clone(), false)?;
let invocation_dir = current_dir().with_context(|| "failed to get current working directory")?;

setup(
&interface,
&mut options,
config.clone(),
&invocation_dir,
false,
)?;

let config_guard = config.lock().unwrap();
let config_ = config_guard.as_ref().unwrap();
Expand All @@ -98,6 +109,7 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
&interface,
&app_settings,
config_,
&invocation_dir,
out_dir,
)?;
}
Expand All @@ -109,6 +121,7 @@ pub fn setup(
interface: &AppInterface,
options: &mut Options,
config: ConfigHandle,
invocation_dir: &Path,
mobile: bool,
) -> Result<()> {
let tauri_path = tauri_dir();
Expand Down Expand Up @@ -143,7 +156,13 @@ pub fn setup(
}

if let Some(before_build) = config_.build.before_build_command.clone() {
helpers::run_hook("beforeBuildCommand", before_build, interface, options.debug)?;
helpers::run_hook(
"beforeBuildCommand",
before_build,
interface,
invocation_dir,
options.debug,
)?;
}

if let Some(FrontendDist::Directory(web_asset_path)) = &config_.build.frontend_dist {
Expand Down
6 changes: 6 additions & 0 deletions tooling/cli/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: MIT

use std::{
env::current_dir,
path::{Path, PathBuf},
str::FromStr,
sync::OnceLock,
Expand Down Expand Up @@ -109,6 +110,7 @@ pub fn command(options: Options, verbosity: u8) -> crate::Result<()> {
options.target.clone(),
)?;

let invocation_dir = current_dir().with_context(|| "failed to get current working directory")?;
let tauri_path = tauri_dir();
std::env::set_current_dir(tauri_path)
.with_context(|| "failed to change current working directory")?;
Expand All @@ -129,17 +131,20 @@ pub fn command(options: Options, verbosity: u8) -> crate::Result<()> {
&interface,
&app_settings,
config_,
&invocation_dir,
out_dir,
)
}

#[allow(clippy::too_many_arguments)]
pub fn bundle<A: AppSettings>(
options: &Options,
verbosity: u8,
ci: bool,
interface: &AppInterface,
app_settings: &std::sync::Arc<A>,
config: &ConfigMetadata,
invocation_dir: &Path,
out_dir: &Path,
) -> crate::Result<()> {
let package_types: Vec<PackageType> = if let Some(bundles) = &options.bundles {
Expand All @@ -165,6 +170,7 @@ pub fn bundle<A: AppSettings>(
"beforeBundleCommand",
before_bundle,
interface,
invocation_dir,
options.debug,
)?;
}
Expand Down
17 changes: 12 additions & 5 deletions tooling/cli/src/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ use shared_child::SharedChild;
use tauri_utils::platform::Target;

use std::{
env::set_current_dir,
env::{current_dir, set_current_dir},
net::{IpAddr, Ipv4Addr},
path::Path,
process::{exit, Command, Stdio},
sync::{
atomic::{AtomicBool, Ordering},
Expand Down Expand Up @@ -109,16 +110,22 @@ fn command_internal(mut options: Options) -> Result<()> {
options.target.clone(),
)?;

setup(&interface, &mut options, config)?;
let invocation_dir = current_dir().with_context(|| "failed to get current working directory")?;
setup(&interface, &mut options, config, &invocation_dir)?;

let exit_on_panic = options.exit_on_panic;
let no_watch = options.no_watch;
interface.dev(options.into(), move |status, reason| {
interface.dev(options.into(), &invocation_dir, move |status, reason| {
on_app_exit(status, reason, exit_on_panic, no_watch)
})
}

pub fn setup(interface: &AppInterface, options: &mut Options, config: ConfigHandle) -> Result<()> {
pub fn setup(
interface: &AppInterface,
options: &mut Options,
config: ConfigHandle,
invocation_dir: &Path,
) -> Result<()> {
let tauri_path = tauri_dir();
set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;

Expand All @@ -138,7 +145,7 @@ pub fn setup(interface: &AppInterface, options: &mut Options, config: ConfigHand
(Some(script), cwd.map(Into::into), wait)
}
};
let cwd = script_cwd.unwrap_or_else(|| app_dir().clone());
let cwd = script_cwd.unwrap_or_else(|| app_dir(invocation_dir).clone());
if let Some(before_dev) = script {
log::info!(action = "Running"; "BeforeDevCommand (`{}`)", before_dev);
let mut env = command_env(true);
Expand Down
17 changes: 8 additions & 9 deletions tooling/cli/src/helpers/app_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,12 @@ pub fn tauri_dir() -> PathBuf {
)
}

fn get_app_dir() -> Option<PathBuf> {
let cwd = current_dir().expect("failed to read cwd");

if cwd.join("package.json").exists() {
return Some(cwd);
fn get_app_dir(base_dir: &Path) -> Option<PathBuf> {
if base_dir.join("package.json").exists() {
return Some(base_dir.into());
}

lookup(&cwd, |path| {
lookup(base_dir, |path| {
if let Some(file_name) = path.file_name() {
file_name == OsStr::new("package.json")
} else {
Expand All @@ -127,8 +125,9 @@ fn get_app_dir() -> Option<PathBuf> {
.map(|p| p.parent().unwrap().to_path_buf())
}

pub fn app_dir() -> &'static PathBuf {
pub fn app_dir(base_dir: &Path) -> &'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()))
APP_DIR.get_or_init(|| {
get_app_dir(base_dir).unwrap_or_else(|| tauri_dir().parent().unwrap().to_path_buf())
})
}
3 changes: 2 additions & 1 deletion tooling/cli/src/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,15 @@ pub fn run_hook(
name: &str,
hook: HookCommand,
interface: &AppInterface,
invocation_dir: &Path,
debug: bool,
) -> crate::Result<()> {
let (script, script_cwd) = match hook {
HookCommand::Script(s) if s.is_empty() => (None, None),
HookCommand::Script(s) => (Some(s), None),
HookCommand::ScriptWithOptions { script, cwd } => (Some(script), cwd.map(Into::into)),
};
let cwd = script_cwd.unwrap_or_else(|| app_dir().clone());
let cwd = script_cwd.unwrap_or_else(|| app_dir(invocation_dir).clone());
if let Some(script) = script {
log::info!(action = "Running"; "{} `{}`", name, script);

Expand Down
6 changes: 5 additions & 1 deletion tooling/cli/src/info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
// SPDX-License-Identifier: MIT

use crate::Result;
use anyhow::Context;
use clap::Parser;
use colored::{ColoredString, Colorize};
use dialoguer::{theme::ColorfulTheme, Confirm};
use serde::Deserialize;
use std::{
env::current_dir,
fmt::{self, Display, Formatter},
panic,
};
Expand Down Expand Up @@ -263,7 +265,9 @@ pub fn command(options: Options) -> Result<()> {
panic::set_hook(Box::new(|_info| {
// do nothing
}));
let app_dir = panic::catch_unwind(crate::helpers::app_paths::app_dir)

let invocation_dir = current_dir().with_context(|| "failed to get current working directory")?;
let app_dir = panic::catch_unwind(|| crate::helpers::app_paths::app_dir(&invocation_dir))
.map(Some)
.unwrap_or_default();
let tauri_dir = panic::catch_unwind(crate::helpers::app_paths::tauri_dir)
Expand Down
2 changes: 2 additions & 0 deletions tooling/cli/src/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,13 @@ pub trait Interface: Sized {
fn dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
&mut self,
options: Options,
invocation_dir: &Path,
on_exit: F,
) -> crate::Result<()>;
fn mobile_dev<R: Fn(MobileOptions) -> crate::Result<Box<dyn DevProcess + Send>>>(
&mut self,
options: MobileOptions,
invocation_dir: &Path,
runner: R,
) -> crate::Result<()>;
}
9 changes: 6 additions & 3 deletions tooling/cli/src/interface/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ impl Interface for Rust {
fn dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
&mut self,
mut options: Options,
invocation_dir: &Path,
on_exit: F,
) -> crate::Result<()> {
let on_exit = Arc::new(on_exit);
Expand Down Expand Up @@ -210,13 +211,14 @@ impl Interface for Rust {
on_exit(status, reason)
})
});
self.run_dev_watcher(config, run)
self.run_dev_watcher(config, invocation_dir, run)
}
}

fn mobile_dev<R: Fn(MobileOptions) -> crate::Result<Box<dyn DevProcess + Send>>>(
&mut self,
mut options: MobileOptions,
invocation_dir: &Path,
runner: R,
) -> crate::Result<()> {
let mut run_args = Vec::new();
Expand All @@ -234,7 +236,7 @@ impl Interface for Rust {
} else {
let config = options.config.clone().map(|c| c.0);
let run = Arc::new(|_rust: &mut Rust| runner(options.clone()));
self.run_dev_watcher(config, run)
self.run_dev_watcher(config, invocation_dir, run)
}
}

Expand Down Expand Up @@ -505,13 +507,14 @@ impl Rust {
fn run_dev_watcher<F: Fn(&mut Rust) -> crate::Result<Box<dyn DevProcess + Send>>>(
&mut self,
config: Option<serde_json::Value>,
invocation_dir: &Path,
run: Arc<F>,
) -> crate::Result<()> {
let child = run(self)?;

let process = Arc::new(Mutex::new(child));
let (tx, rx) = sync_channel(1);
let app_path = app_dir();
let app_path = app_dir(invocation_dir);

let watch_folders = get_watch_folders()?;

Expand Down
5 changes: 4 additions & 1 deletion tooling/cli/src/migrate/migrations/v1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use std::env::current_dir;

use crate::{
helpers::app_paths::{app_dir, tauri_dir},
Result,
Expand All @@ -14,8 +16,9 @@ mod frontend;
mod manifest;

pub fn run() -> Result<()> {
let current_dir = current_dir().with_context(|| "failed to get current working directory")?;
let tauri_dir = tauri_dir();
let app_dir = app_dir();
let app_dir = app_dir(&current_dir);

let migrated = config::migrate(&tauri_dir).context("Could not migrate config")?;
manifest::migrate(&tauri_dir).context("Could not migrate manifest")?;
Expand Down
5 changes: 3 additions & 2 deletions tooling/cli/src/migrate/migrations/v2_rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ use crate::{
Result,
};

use std::{fs::read_to_string, path::Path};
use std::{env::current_dir, fs::read_to_string, path::Path};

use anyhow::Context;
use toml_edit::{Document, Item, Table, TableLike, Value};

pub fn run() -> Result<()> {
let app_dir = app_dir();
let current_dir = current_dir().with_context(|| "failed to get current working directory")?;
let app_dir = app_dir(&current_dir);
let tauri_dir = tauri_dir();

let manifest_path = tauri_dir.join("Cargo.toml");
Expand Down
11 changes: 9 additions & 2 deletions tooling/cli/src/mobile/android/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use cargo_mobile2::{
target::TargetTrait,
};

use std::env::set_current_dir;
use std::env::{current_dir, set_current_dir};

#[derive(Debug, Clone, Parser)]
#[clap(
Expand Down Expand Up @@ -128,6 +128,7 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
Profile::Release
};

let invocation_dir = current_dir().with_context(|| "failed to get current working directory")?;
let tauri_path = tauri_dir();
set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;

Expand All @@ -141,7 +142,13 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
let mut env = env()?;
configure_cargo(&app, Some((&mut env, &config)))?;

crate::build::setup(&interface, &mut build_options, tauri_config.clone(), true)?;
crate::build::setup(
&interface,
&mut build_options,
tauri_config.clone(),
&invocation_dir,
true,
)?;

// run an initial build to initialize plugins
first_target.build(&config, &metadata, &env, noise_level, true, profile)?;
Expand Down
Loading

0 comments on commit f1a44d9

Please sign in to comment.