Skip to content

Commit

Permalink
fix(cli): dev watcher infinite loop on mobile (#9017)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog authored Feb 28, 2024
1 parent e4463f0 commit d7d03c7
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 66 deletions.
6 changes: 6 additions & 0 deletions .changes/mobile-watcher.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@tauri-apps/cli": patch:bug
"tauri-cli": patch:bug
---

Fixes dev watcher on mobile dev.
1 change: 0 additions & 1 deletion tooling/cli/src/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ pub trait DevProcess {
fn try_wait(&self) -> std::io::Result<Option<ExitStatus>>;
fn wait(&self) -> std::io::Result<ExitStatus>;
fn manually_killed_process(&self) -> bool;
fn is_building_app(&self) -> bool;
}

pub trait AppSettings {
Expand Down
54 changes: 25 additions & 29 deletions tooling/cli/src/interface/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl Interface for Rust {
watcher
.watcher()
.watch(&tauri_dir().join("Cargo.toml"), RecursiveMode::Recursive)?;
let manifest = rewrite_manifest(config)?;
let (manifest, _modified) = rewrite_manifest(config)?;
let now = Instant::now();
let timeout = Duration::from_secs(2);
loop {
Expand Down Expand Up @@ -535,38 +535,34 @@ impl Rust {

if !ignore_matcher.is_ignore(&event_path, event_path.is_dir()) {
if is_configuration_file(self.app_settings.target, &event_path) {
match reload_config(config.as_ref()) {
Ok(config) => {
info!("Tauri configuration changed. Rewriting manifest...");
*self.app_settings.manifest.lock().unwrap() =
rewrite_manifest(config.lock().unwrap().as_ref().unwrap())?
}
Err(err) => {
let p = process.lock().unwrap();
if p.is_building_app() {
p.kill().with_context(|| "failed to kill app process")?;
}
error!("{}", err);
if let Ok(config) = reload_config(config.as_ref()) {
let (manifest, modified) =
rewrite_manifest(config.lock().unwrap().as_ref().unwrap())?;
if modified {
*self.app_settings.manifest.lock().unwrap() = manifest;
// no need to run the watcher logic, the manifest was modified
// and it will trigger the watcher again
continue;
}
}
} else {
info!(
"File {} changed. Rebuilding application...",
display_path(event_path.strip_prefix(app_path).unwrap_or(&event_path))
);
// When tauri.conf.json is changed, rewrite_manifest will be called
// which will trigger the watcher again
// So the app should only be started when a file other than tauri.conf.json is changed
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(_)) = p.try_wait() {
break;
}
}

log::info!(
"File {} changed. Rebuilding application...",
display_path(event_path.strip_prefix(app_path).unwrap_or(&event_path))
);

let mut p = process.lock().unwrap();
p.kill().with_context(|| "failed to kill app process")?;

// wait for the process to exit
// note that on mobile, kill() already waits for the process to exit (duct implementation)
loop {
if !matches!(p.try_wait(), Ok(None)) {
break;
}
*p = run(self)?;
}
*p = run(self)?;
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions tooling/cli/src/interface/rust/desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ impl DevProcess for DevChild {
fn manually_killed_process(&self) -> bool {
self.manually_killed_app.load(Ordering::Relaxed)
}

fn is_building_app(&self) -> bool {
self.app_child.lock().unwrap().is_none()
}
}

pub fn run_dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
Expand Down
55 changes: 30 additions & 25 deletions tooling/cli/src/interface/rust/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ fn get_enabled_features(list: &HashMap<String, Vec<String>>, feature: &str) -> V
f
}

pub fn read_manifest(manifest_path: &Path) -> crate::Result<Document> {
pub fn read_manifest(manifest_path: &Path) -> crate::Result<(Document, String)> {
let mut manifest_str = String::new();

let mut manifest_file = File::open(manifest_path)
Expand All @@ -95,7 +95,7 @@ pub fn read_manifest(manifest_path: &Path) -> crate::Result<Document> {
.parse::<Document>()
.with_context(|| "failed to parse Cargo.toml")?;

Ok(manifest)
Ok((manifest, manifest_str))
}

pub fn toml_array(features: &HashSet<String>) -> Array {
Expand Down Expand Up @@ -265,9 +265,9 @@ fn inject_features(
Ok(persist)
}

pub fn rewrite_manifest(config: &Config) -> crate::Result<Manifest> {
pub fn rewrite_manifest(config: &Config) -> crate::Result<(Manifest, bool)> {
let manifest_path = tauri_dir().join("Cargo.toml");
let mut manifest = read_manifest(&manifest_path)?;
let (mut manifest, original_manifest_str) = read_manifest(&manifest_path)?;

let mut dependencies = Vec::new();

Expand Down Expand Up @@ -303,31 +303,36 @@ pub fn rewrite_manifest(config: &Config) -> crate::Result<Manifest> {
.unwrap()
.features;

if persist {
let new_manifest_str = manifest
.to_string()
// apply some formatting fixes
.replace(r#"" ,features =["#, r#"", features = ["#)
.replace(r#"" , features"#, r#"", features"#)
.replace("]}", "] }")
.replace("={", "= {")
.replace("=[", "= [")
.replace(r#"",""#, r#"", ""#);

if persist && original_manifest_str != new_manifest_str {
let mut manifest_file =
File::create(&manifest_path).with_context(|| "failed to open Cargo.toml for rewrite")?;
manifest_file.write_all(
manifest
.to_string()
// apply some formatting fixes
.replace(r#"" ,features =["#, r#"", features = ["#)
.replace(r#"" , features"#, r#"", features"#)
.replace("]}", "] }")
.replace("={", "= {")
.replace("=[", "= [")
.replace(r#"",""#, r#"", ""#)
.as_bytes(),
)?;
manifest_file.write_all(new_manifest_str.as_bytes())?;
manifest_file.flush()?;
Ok(Manifest {
inner: manifest,
tauri_features,
})
Ok((
Manifest {
inner: manifest,
tauri_features,
},
true,
))
} else {
Ok(Manifest {
inner: manifest,
tauri_features,
})
Ok((
Manifest {
inner: manifest,
tauri_features,
},
false,
))
}
}

Expand Down
2 changes: 1 addition & 1 deletion tooling/cli/src/migrate/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const CRATE_TYPES: [&str; 3] = ["lib", "staticlib", "cdylib"];

pub fn migrate(tauri_dir: &Path) -> Result<()> {
let manifest_path = tauri_dir.join("Cargo.toml");
let mut manifest = read_manifest(&manifest_path)?;
let (mut manifest, _) = read_manifest(&manifest_path)?;
migrate_manifest(&mut manifest)?;

let mut manifest_file =
Expand Down
13 changes: 7 additions & 6 deletions tooling/cli/src/mobile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,14 @@ impl DevChild {

impl DevProcess for DevChild {
fn kill(&self) -> std::io::Result<()> {
self.child.kill()?;
self.manually_killed_process.store(true, Ordering::Relaxed);
Ok(())
match self.child.kill() {
Ok(_) => Ok(()),
Err(e) => {
self.manually_killed_process.store(false, Ordering::Relaxed);
Err(e)
}
}
}

fn try_wait(&self) -> std::io::Result<Option<ExitStatus>> {
Expand All @@ -85,10 +90,6 @@ impl DevProcess for DevChild {
fn manually_killed_process(&self) -> bool {
self.manually_killed_process.load(Ordering::Relaxed)
}

fn is_building_app(&self) -> bool {
false
}
}

#[derive(PartialEq, Eq, Copy, Clone)]
Expand Down

0 comments on commit d7d03c7

Please sign in to comment.