fix(cli): dev watcher infinite loop on mobile (#9017)

This commit is contained in:
Lucas Fernandes Nogueira 2024-02-28 17:22:45 -03:00 committed by GitHub
parent e4463f0814
commit d7d03c7197
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 70 additions and 67 deletions

View File

@ -0,0 +1,6 @@
---
"@tauri-apps/cli": patch:bug
"tauri-cli": patch:bug
---
Fixes dev watcher on mobile dev.

View File

@ -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 {

View File

@ -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 {
@ -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;
}
}
*p = run(self)?;
}
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)?;
}
}
}

View File

@ -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>(

View File

@ -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)
@ -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 {
@ -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();
@ -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,
))
}
}

View File

@ -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 =

View File

@ -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>> {
@ -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)]