Skip to content

Commit

Permalink
fix(cli): kill beforeDevCommand if dev code returns an error (#3907)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Apr 19, 2022
1 parent f2a30d8 commit 485c974
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 51 deletions.
6 changes: 6 additions & 0 deletions .changes/cli-handle-dev-err.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"cli.rs": patch
"cli.js": patch
---

Kill the `beforeDevCommand` and app processes if the dev command returns an error.
12 changes: 6 additions & 6 deletions examples/api/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
99 changes: 80 additions & 19 deletions tooling/cli/src/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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)?;
Expand Down Expand Up @@ -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() {
Expand All @@ -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,
Expand Down
26 changes: 0 additions & 26 deletions tooling/cli/src/helpers/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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![]),
}
}

0 comments on commit 485c974

Please sign in to comment.