Explorar o código

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
Fabian-Lars hai 1 ano
pai
achega
67d7877f27
Modificáronse 2 ficheiros con 46 adicións e 38 borrados
  1. 6 0
      .changes/cli-watch-ws-members.md
  2. 40 38
      tooling/cli/src/interface/rust.rs

+ 6 - 0
.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.

+ 40 - 38
tooling/cli/src/interface/rust.rs

@@ -347,6 +347,40 @@ fn expand_member_path(path: &Path) -> crate::Result<Vec<PathBuf>> {
   Ok(res)
 }
 
+fn get_watch_folders() -> crate::Result<Vec<PathBuf>> {
+  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<F: Fn(ExitStatus, ExitReason) + Send + Sync + 'static>(
     &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::<Vec<_>>();
-    let watch_folders = watch_folders.iter().map(Path::new).collect::<Vec<_>>();
+    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(