mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-08-17 03:40:23 +03:00
fix(cli): dev watcher infinite loop on mobile (#9017)
This commit is contained in:
parent
e4463f0814
commit
d7d03c7197
6
.changes/mobile-watcher.md
Normal file
6
.changes/mobile-watcher.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@tauri-apps/cli": patch:bug
|
||||||
|
"tauri-cli": patch:bug
|
||||||
|
---
|
||||||
|
|
||||||
|
Fixes dev watcher on mobile dev.
|
@ -21,7 +21,6 @@ pub trait DevProcess {
|
|||||||
fn try_wait(&self) -> std::io::Result<Option<ExitStatus>>;
|
fn try_wait(&self) -> std::io::Result<Option<ExitStatus>>;
|
||||||
fn wait(&self) -> std::io::Result<ExitStatus>;
|
fn wait(&self) -> std::io::Result<ExitStatus>;
|
||||||
fn manually_killed_process(&self) -> bool;
|
fn manually_killed_process(&self) -> bool;
|
||||||
fn is_building_app(&self) -> bool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AppSettings {
|
pub trait AppSettings {
|
||||||
|
@ -121,7 +121,7 @@ impl Interface for Rust {
|
|||||||
watcher
|
watcher
|
||||||
.watcher()
|
.watcher()
|
||||||
.watch(&tauri_dir().join("Cargo.toml"), RecursiveMode::Recursive)?;
|
.watch(&tauri_dir().join("Cargo.toml"), RecursiveMode::Recursive)?;
|
||||||
let manifest = rewrite_manifest(config)?;
|
let (manifest, _modified) = rewrite_manifest(config)?;
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let timeout = Duration::from_secs(2);
|
let timeout = Duration::from_secs(2);
|
||||||
loop {
|
loop {
|
||||||
@ -535,38 +535,34 @@ impl Rust {
|
|||||||
|
|
||||||
if !ignore_matcher.is_ignore(&event_path, event_path.is_dir()) {
|
if !ignore_matcher.is_ignore(&event_path, event_path.is_dir()) {
|
||||||
if is_configuration_file(self.app_settings.target, &event_path) {
|
if is_configuration_file(self.app_settings.target, &event_path) {
|
||||||
match reload_config(config.as_ref()) {
|
if let Ok(config) = reload_config(config.as_ref()) {
|
||||||
Ok(config) => {
|
let (manifest, modified) =
|
||||||
info!("Tauri configuration changed. Rewriting manifest...");
|
rewrite_manifest(config.lock().unwrap().as_ref().unwrap())?;
|
||||||
*self.app_settings.manifest.lock().unwrap() =
|
if modified {
|
||||||
rewrite_manifest(config.lock().unwrap().as_ref().unwrap())?
|
*self.app_settings.manifest.lock().unwrap() = manifest;
|
||||||
}
|
// no need to run the watcher logic, the manifest was modified
|
||||||
Err(err) => {
|
// and it will trigger the watcher again
|
||||||
let p = process.lock().unwrap();
|
continue;
|
||||||
if p.is_building_app() {
|
|
||||||
p.kill().with_context(|| "failed to kill app process")?;
|
|
||||||
}
|
|
||||||
error!("{}", err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,10 +62,6 @@ impl DevProcess for DevChild {
|
|||||||
fn manually_killed_process(&self) -> bool {
|
fn manually_killed_process(&self) -> bool {
|
||||||
self.manually_killed_app.load(Ordering::Relaxed)
|
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>(
|
pub fn run_dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
|
||||||
|
@ -84,7 +84,7 @@ fn get_enabled_features(list: &HashMap<String, Vec<String>>, feature: &str) -> V
|
|||||||
f
|
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_str = String::new();
|
||||||
|
|
||||||
let mut manifest_file = File::open(manifest_path)
|
let mut manifest_file = File::open(manifest_path)
|
||||||
@ -95,7 +95,7 @@ pub fn read_manifest(manifest_path: &Path) -> crate::Result<Document> {
|
|||||||
.parse::<Document>()
|
.parse::<Document>()
|
||||||
.with_context(|| "failed to parse Cargo.toml")?;
|
.with_context(|| "failed to parse Cargo.toml")?;
|
||||||
|
|
||||||
Ok(manifest)
|
Ok((manifest, manifest_str))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toml_array(features: &HashSet<String>) -> Array {
|
pub fn toml_array(features: &HashSet<String>) -> Array {
|
||||||
@ -265,9 +265,9 @@ fn inject_features(
|
|||||||
Ok(persist)
|
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 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();
|
let mut dependencies = Vec::new();
|
||||||
|
|
||||||
@ -303,31 +303,36 @@ pub fn rewrite_manifest(config: &Config) -> crate::Result<Manifest> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.features;
|
.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 =
|
let mut manifest_file =
|
||||||
File::create(&manifest_path).with_context(|| "failed to open Cargo.toml for rewrite")?;
|
File::create(&manifest_path).with_context(|| "failed to open Cargo.toml for rewrite")?;
|
||||||
manifest_file.write_all(
|
manifest_file.write_all(new_manifest_str.as_bytes())?;
|
||||||
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.flush()?;
|
manifest_file.flush()?;
|
||||||
Ok(Manifest {
|
Ok((
|
||||||
inner: manifest,
|
Manifest {
|
||||||
tauri_features,
|
inner: manifest,
|
||||||
})
|
tauri_features,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(Manifest {
|
Ok((
|
||||||
inner: manifest,
|
Manifest {
|
||||||
tauri_features,
|
inner: manifest,
|
||||||
})
|
tauri_features,
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ const CRATE_TYPES: [&str; 3] = ["lib", "staticlib", "cdylib"];
|
|||||||
|
|
||||||
pub fn migrate(tauri_dir: &Path) -> Result<()> {
|
pub fn migrate(tauri_dir: &Path) -> Result<()> {
|
||||||
let manifest_path = tauri_dir.join("Cargo.toml");
|
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)?;
|
migrate_manifest(&mut manifest)?;
|
||||||
|
|
||||||
let mut manifest_file =
|
let mut manifest_file =
|
||||||
|
@ -69,9 +69,14 @@ impl DevChild {
|
|||||||
|
|
||||||
impl DevProcess for DevChild {
|
impl DevProcess for DevChild {
|
||||||
fn kill(&self) -> std::io::Result<()> {
|
fn kill(&self) -> std::io::Result<()> {
|
||||||
self.child.kill()?;
|
|
||||||
self.manually_killed_process.store(true, Ordering::Relaxed);
|
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>> {
|
fn try_wait(&self) -> std::io::Result<Option<ExitStatus>> {
|
||||||
@ -85,10 +90,6 @@ impl DevProcess for DevChild {
|
|||||||
fn manually_killed_process(&self) -> bool {
|
fn manually_killed_process(&self) -> bool {
|
||||||
self.manually_killed_process.load(Ordering::Relaxed)
|
self.manually_killed_process.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_building_app(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||||
|
Loading…
Reference in New Issue
Block a user