Skip to content

Commit e4c9268

Browse files
feat(cli): make tauri/cli fully support projects with non-standard structure (#11258)
* feat(cli): add support for providing custom app/src paths to tauri's CLI via optional env vars * fix tests * rename env vars (app vs src is confusing) * add change file --------- Co-authored-by: Lucas Nogueira <[email protected]>
1 parent 2e88633 commit e4c9268

File tree

2 files changed

+44
-25
lines changed

2 files changed

+44
-25
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@tauri-apps/cli": patch:enhance
3+
"tauri-cli": patch:enhance
4+
---
5+
6+
Support custom project directory structure where the Tauri app folder is not a subfolder of the frontend project.
7+
The frontend and Tauri app project paths can be set with the `TAURI_FRONTEND_PATH` and the `TAURI_APP_PATH` environment variables respectively.

crates/tauri-cli/src/helpers/app_paths.rs

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ use tauri_utils::{
1818
};
1919

2020
const TAURI_GITIGNORE: &[u8] = include_bytes!("../../tauri.gitignore");
21+
// path to the Tauri app (Rust crate) directory, usually <cwd>/src-tauri
22+
const ENV_TAURI_APP_PATH: &str = "TAURI_APP_PATH";
23+
// path to the frontend app directory
24+
const ENV_TAURI_FRONTEND_PATH: &str = "TAURI_FRONTEND_PATH";
25+
2126
static APP_DIR: OnceLock<PathBuf> = OnceLock::new();
2227
static TAURI_DIR: OnceLock<PathBuf> = OnceLock::new();
2328

@@ -68,29 +73,33 @@ fn lookup<F: Fn(&PathBuf) -> bool>(dir: &Path, checker: F) -> Option<PathBuf> {
6873
None
6974
}
7075

71-
pub fn resolve_tauri_dir() -> Option<PathBuf> {
72-
let Ok(cwd) = current_dir() else {
73-
return None;
74-
};
76+
fn env_tauri_app_path() -> Option<PathBuf> {
77+
std::env::var(ENV_TAURI_APP_PATH)
78+
.map(PathBuf::from)
79+
.ok()?
80+
.canonicalize()
81+
.ok()
82+
}
7583

76-
if cwd.join(ConfigFormat::Json.into_file_name()).exists()
77-
|| cwd.join(ConfigFormat::Json5.into_file_name()).exists()
78-
|| cwd.join(ConfigFormat::Toml.into_file_name()).exists()
79-
{
80-
return Some(cwd);
81-
}
84+
fn env_tauri_frontend_path() -> Option<PathBuf> {
85+
std::env::var(ENV_TAURI_FRONTEND_PATH)
86+
.map(PathBuf::from)
87+
.ok()?
88+
.canonicalize()
89+
.ok()
90+
}
91+
92+
pub fn resolve_tauri_dir() -> Option<PathBuf> {
93+
let src_dir = env_tauri_frontend_path().or_else(|| current_dir().ok())?;
8294

83-
let src_tauri = cwd.join("src-tauri");
84-
if src_tauri.join(ConfigFormat::Json.into_file_name()).exists()
85-
|| src_tauri
86-
.join(ConfigFormat::Json5.into_file_name())
87-
.exists()
88-
|| src_tauri.join(ConfigFormat::Toml.into_file_name()).exists()
95+
if src_dir.join(ConfigFormat::Json.into_file_name()).exists()
96+
|| src_dir.join(ConfigFormat::Json5.into_file_name()).exists()
97+
|| src_dir.join(ConfigFormat::Toml.into_file_name()).exists()
8998
{
90-
return Some(src_tauri);
99+
return Some(src_dir);
91100
}
92101

93-
lookup(&cwd, |path| {
102+
lookup(&src_dir, |path| {
94103
folder_has_configuration_file(Target::Linux, path) || is_configuration_file(Target::Linux, path)
95104
})
96105
.map(|p| {
@@ -103,13 +112,15 @@ pub fn resolve_tauri_dir() -> Option<PathBuf> {
103112
}
104113

105114
pub fn resolve() {
106-
TAURI_DIR.set(resolve_tauri_dir().unwrap_or_else(||
107-
panic!("Couldn't recognize the current folder as a Tauri project. It must contain a `{}`, `{}` or `{}` file in any subfolder.",
115+
TAURI_DIR.set(resolve_tauri_dir().unwrap_or_else(|| {
116+
let env_var_name = env_tauri_frontend_path().is_some().then(|| format!("`{ENV_TAURI_FRONTEND_PATH}`"));
117+
panic!("Couldn't recognize the {} folder as a Tauri project. It must contain a `{}`, `{}` or `{}` file in any subfolder.",
118+
env_var_name.as_deref().unwrap_or("current"),
108119
ConfigFormat::Json.into_file_name(),
109120
ConfigFormat::Json5.into_file_name(),
110121
ConfigFormat::Toml.into_file_name()
111122
)
112-
)).expect("tauri dir already resolved");
123+
})).expect("tauri dir already resolved");
113124
APP_DIR
114125
.set(resolve_app_dir().unwrap_or_else(|| tauri_dir().parent().unwrap().to_path_buf()))
115126
.expect("app dir already resolved");
@@ -122,12 +133,13 @@ pub fn tauri_dir() -> &'static PathBuf {
122133
}
123134

124135
pub fn resolve_app_dir() -> Option<PathBuf> {
125-
let cwd = current_dir().expect("failed to read cwd");
126-
if cwd.join("package.json").exists() {
127-
return Some(cwd);
136+
let app_dir = env_tauri_app_path().unwrap_or_else(|| current_dir().expect("failed to read cwd"));
137+
138+
if app_dir.join("package.json").exists() {
139+
return Some(app_dir);
128140
}
129141

130-
lookup(&cwd, |path| {
142+
lookup(&app_dir, |path| {
131143
if let Some(file_name) = path.file_name() {
132144
file_name == OsStr::new("package.json")
133145
} else {

0 commit comments

Comments
 (0)