From 67d7877f27f265c133a70d48a46c83ffff31d571 Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Thu, 4 Jan 2024 00:37:05 +0100 Subject: [PATCH] fix(cli): Watch workspace members if tauri dir is workspace root (#8520) * fix(cli): Watch workspace members if tauri dir is ws root See title. This PR also includes a fix/workaround for paths with funny characters that may not make the glob expansion panic. Fixes #8509 * extract into function * cleanup --- .changes/cli-watch-ws-members.md | 6 +++ tooling/cli/src/interface/rust.rs | 78 ++++++++++++++++--------------- 2 files changed, 46 insertions(+), 38 deletions(-) create mode 100644 .changes/cli-watch-ws-members.md diff --git a/.changes/cli-watch-ws-members.md b/.changes/cli-watch-ws-members.md new file mode 100644 index 00000000000..a32d7f9f2c9 --- /dev/null +++ b/.changes/cli-watch-ws-members.md @@ -0,0 +1,6 @@ +--- +"tauri-cli": patch:bug +"@tauri-apps/cli": patch:bug +--- + +The cli now also watches cargo workspace members if the tauri folder is the workspace root. diff --git a/tooling/cli/src/interface/rust.rs b/tooling/cli/src/interface/rust.rs index f015b9e9599..02fb0c058a3 100644 --- a/tooling/cli/src/interface/rust.rs +++ b/tooling/cli/src/interface/rust.rs @@ -347,6 +347,40 @@ fn expand_member_path(path: &Path) -> crate::Result> { Ok(res) } +fn get_watch_folders() -> crate::Result> { + let tauri_path = tauri_dir(); + let workspace_path = get_workspace_dir()?; + + // We always want to watch the main tauri folder. + let mut watch_folders = vec![tauri_path.to_path_buf()]; + + // We also try to watch workspace members, no matter if the tauri cargo project is the workspace root or a workspace member + let cargo_settings = CargoSettings::load(&workspace_path)?; + if let Some(members) = cargo_settings.workspace.and_then(|w| w.members) { + for p in members { + let p = workspace_path.join(p); + match expand_member_path(&p) { + // Sometimes expand_member_path returns an empty vec, for example if the path contains `[]` as in `C:/[abc]/project/`. + // Cargo won't complain unless theres a workspace.members config with glob patterns so we should support it too. + Ok(expanded_paths) => { + if expanded_paths.is_empty() { + watch_folders.push(p); + } else { + watch_folders.extend(expanded_paths); + } + } + Err(err) => { + // If this fails cargo itself should fail too. But we still try to keep going with the unexpanded path. + error!("Error watching {}: {}", p.display(), err.to_string()); + watch_folders.push(p); + } + }; + } + } + + Ok(watch_folders) +} + impl Rust { fn run_dev( &mut self, @@ -412,43 +446,11 @@ impl Rust { let process = Arc::new(Mutex::new(child)); let (tx, rx) = sync_channel(1); let app_path = app_dir(); - let tauri_path = tauri_dir(); - let workspace_path = get_workspace_dir()?; - - let watch_folders = if tauri_path == workspace_path { - vec![tauri_path] - } else { - let cargo_settings = CargoSettings::load(&workspace_path)?; - cargo_settings - .workspace - .as_ref() - .map(|w| { - w.members - .clone() - .unwrap_or_default() - .into_iter() - .map(|p| workspace_path.join(p)) - .collect() - }) - .unwrap_or_else(|| vec![tauri_path]) - }; - let watch_folders = watch_folders - .into_iter() - .flat_map(|p| { - match expand_member_path(&p) { - Ok(p) => p, - Err(err) => { - // If this fails cargo itself should fail too. But we still try to keep going with the unexpanded path. - error!("Error watching {}: {}", p.display(), err.to_string()); - vec![p] - } - } - }) - .collect::>(); - let watch_folders = watch_folders.iter().map(Path::new).collect::>(); + let watch_folders = get_watch_folders()?; - let common_ancestor = common_path::common_path_all(watch_folders.clone()).unwrap(); + let common_ancestor = common_path::common_path_all(watch_folders.iter().map(Path::new)) + .expect("watch_folders should not be empty"); let ignore_matcher = build_ignore_matcher(&common_ancestor); let mut watcher = new_debouncer(Duration::from_secs(1), move |r| { @@ -458,9 +460,9 @@ impl Rust { }) .unwrap(); for path in watch_folders { - if !ignore_matcher.is_ignore(path, true) { - info!("Watching {} for changes...", display_path(path)); - lookup(path, |file_type, p| { + if !ignore_matcher.is_ignore(&path, true) { + info!("Watching {} for changes...", display_path(&path)); + lookup(&path, |file_type, p| { if p != path { debug!("Watching {} for changes...", display_path(&p)); let _ = watcher.watcher().watch(