Explorar el Código

fix(cli): kill beforeDevCommand if dev code returns an error (#3907)

Lucas Fernandes Nogueira hace 3 años
padre
commit
485c97438a

+ 6 - 0
.changes/cli-handle-dev-err.md

@@ -0,0 +1,6 @@
+---
+"cli.rs": patch
+"cli.js": patch
+---
+
+Kill the `beforeDevCommand` and app processes if the dev command returns an error.

+ 6 - 6
examples/api/yarn.lock

@@ -23,9 +23,9 @@
     svelte-hmr "^0.14.7"
 
 "@tauri-apps/api@../../tooling/api/dist":
-  version "1.0.0-rc.1"
+  version "1.0.0-rc.2"
   dependencies:
-    type-fest "2.12.0"
+    type-fest "2.12.1"
 
 debug@^4.3.2:
   version "4.3.3"
@@ -262,10 +262,10 @@ svelte@3.35.0:
   resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.35.0.tgz#e0d0ba60c4852181c2b4fd851194be6fda493e65"
   integrity sha512-gknlZkR2sXheu/X+B7dDImwANVvK1R0QGQLd8CNIfxxGPeXBmePnxfzb6fWwTQRsYQG7lYkZXvpXJvxvpsoB7g==
 
-type-fest@2.12.0:
-  version "2.12.0"
-  resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.12.0.tgz#ce342f58cab9114912f54b493d60ab39c3fc82b6"
-  integrity sha512-Qe5GRT+n/4GoqCNGGVp5Snapg1Omq3V7irBJB3EaKsp7HWDo5Gv2d/67gfNyV+d5EXD+x/RF5l1h4yJ7qNkcGA==
+type-fest@2.12.1:
+  version "2.12.1"
+  resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.12.1.tgz#d2be8f50bf5f8f0a5fd916d29bf3e98c17e960be"
+  integrity sha512-AiknQSEqKVGDDjtZqeKrUoTlcj7FKhupmnVUgz6KoOKtvMwRGE6hUNJ/nVear+h7fnUPO1q/htSkYKb1pyntkQ==
 
 vite@^2.6.4:
   version "2.6.14"

+ 80 - 19
tooling/cli/src/dev.rs

@@ -6,8 +6,8 @@ use crate::{
   helpers::{
     app_paths::{app_dir, tauri_dir},
     command_env,
-    config::{get as get_config, reload as reload_config, AppUrl, WindowUrl},
-    manifest::{get_workspace_members, rewrite_manifest, Manifest},
+    config::{get as get_config, reload as reload_config, AppUrl, ConfigHandle, WindowUrl},
+    manifest::{rewrite_manifest, Manifest},
     Logger,
   },
   CommandExt, Result,
@@ -22,10 +22,12 @@ use shared_child::SharedChild;
 use std::{
   env::set_current_dir,
   ffi::OsStr,
+  fs::FileType,
+  path::{Path, PathBuf},
   process::{exit, Command},
   sync::{
     atomic::{AtomicBool, Ordering},
-    mpsc::{channel, Receiver},
+    mpsc::{channel, Receiver, Sender},
     Arc, Mutex,
   },
   time::Duration,
@@ -63,6 +65,14 @@ pub struct Options {
 }
 
 pub fn command(options: Options) -> Result<()> {
+  let r = command_internal(options);
+  if r.is_err() {
+    kill_before_dev_process();
+  }
+  r
+}
+
+fn command_internal(options: Options) -> Result<()> {
   let logger = Logger::new("tauri:dev");
 
   let tauri_path = tauri_dir();
@@ -151,7 +161,7 @@ pub fn command(options: Options) -> Result<()> {
     .or(runner_from_config)
     .unwrap_or_else(|| "cargo".to_string());
 
-  let mut manifest = {
+  let manifest = {
     let (tx, rx) = channel();
     let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap();
     watcher.watch(tauri_path.join("Cargo.toml"), RecursiveMode::Recursive)?;
@@ -239,26 +249,78 @@ pub fn command(options: Options) -> Result<()> {
     }
   }
 
-  let mut process = start_app(
+  let process = start_app(
     &options,
     &runner,
     &manifest,
     &cargo_features,
     child_wait_rx.clone(),
   )?;
+  let shared_process = Arc::new(Mutex::new(process));
+  if let Err(e) = watch(
+    shared_process.clone(),
+    child_wait_tx,
+    child_wait_rx,
+    tauri_path,
+    merge_config,
+    config,
+    options,
+    runner,
+    manifest,
+    cargo_features,
+  ) {
+    shared_process
+      .lock()
+      .unwrap()
+      .kill()
+      .with_context(|| "failed to kill app process")?;
+    Err(e)
+  } else {
+    Ok(())
+  }
+}
+
+fn lookup<F: FnMut(&OsStr, FileType, PathBuf)>(dir: &Path, mut f: F) {
+  let mut builder = ignore::WalkBuilder::new(dir);
+  builder.require_git(false).ignore(false).max_depth(Some(1));
 
+  for entry in builder.build().flatten() {
+    f(
+      entry.file_name(),
+      entry.file_type().unwrap(),
+      dir.join(entry.path()),
+    );
+  }
+}
+
+#[allow(clippy::too_many_arguments)]
+fn watch(
+  process: Arc<Mutex<Arc<SharedChild>>>,
+  child_wait_tx: Sender<()>,
+  child_wait_rx: Arc<Mutex<Receiver<()>>>,
+  tauri_path: PathBuf,
+  merge_config: Option<String>,
+  config: ConfigHandle,
+  options: Options,
+  runner: String,
+  mut manifest: Manifest,
+  cargo_features: Vec<String>,
+) -> Result<()> {
   let (tx, rx) = channel();
 
   let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap();
-  watcher.watch(tauri_path.join("src"), RecursiveMode::Recursive)?;
-  watcher.watch(tauri_path.join("Cargo.toml"), RecursiveMode::Recursive)?;
-  watcher.watch(tauri_path.join("tauri.conf.json"), RecursiveMode::Recursive)?;
-
-  for member in get_workspace_members()? {
-    let workspace_path = tauri_path.join(member);
-    watcher.watch(workspace_path.join("src"), RecursiveMode::Recursive)?;
-    watcher.watch(workspace_path.join("Cargo.toml"), RecursiveMode::Recursive)?;
-  }
+  lookup(&tauri_path, |file_name, file_type, path| {
+    if file_name != "target" && file_name != "Cargo.lock" {
+      let _ = watcher.watch(
+        path,
+        if file_type.is_dir() {
+          RecursiveMode::Recursive
+        } else {
+          RecursiveMode::NonRecursive
+        },
+      );
+    }
+  });
 
   loop {
     if let Ok(event) = rx.recv() {
@@ -279,16 +341,15 @@ pub fn command(options: Options) -> Result<()> {
           // which will trigger the watcher again
           // So the app should only be started when a file other than tauri.conf.json is changed
           let _ = child_wait_tx.send(());
-          process
-            .kill()
-            .with_context(|| "failed to kill app process")?;
+          let mut p = process.lock().unwrap();
+          p.kill().with_context(|| "failed to kill app process")?;
           // wait for the process to exit
           loop {
-            if let Ok(Some(_)) = process.try_wait() {
+            if let Ok(Some(_)) = p.try_wait() {
               break;
             }
           }
-          process = start_app(
+          *p = start_app(
             &options,
             &runner,
             &manifest,

+ 0 - 26
tooling/cli/src/helpers/manifest.rs

@@ -234,29 +234,3 @@ pub fn rewrite_manifest(config: ConfigHandle) -> crate::Result<Manifest> {
     Err(e) => Err(e),
   }
 }
-
-pub fn get_workspace_members() -> crate::Result<Vec<String>> {
-  let mut manifest = read_manifest(&tauri_dir().join("Cargo.toml"))?;
-  let workspace = manifest
-    .as_table_mut()
-    .entry("workspace")
-    .or_insert(Item::None)
-    .as_table_mut();
-
-  match workspace {
-    Some(workspace) => {
-      let members = workspace
-        .entry("members")
-        .or_insert(Item::None)
-        .as_array()
-        .expect("workspace members aren't an array");
-      Ok(
-        members
-          .iter()
-          .map(|v| v.as_str().unwrap().to_string())
-          .collect(),
-      )
-    }
-    None => Ok(vec![]),
-  }
-}