mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-03 10:11:15 +02:00
feat(cli): expose a function to kill dev child
This commit is contained in:
5
.changes/cli-js-kill-dev-fn.md
Normal file
5
.changes/cli-js-kill-dev-fn.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"cli.js": "minor"
|
||||
---
|
||||
|
||||
Add `killDevApp` API to kill the dev app process manually.
|
||||
5
.changes/cli-rs-kill-dev-fn.md
Normal file
5
.changes/cli-rs-kill-dev-fn.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"cli.rs": "minor"
|
||||
---
|
||||
|
||||
Add `tauri_cli::kill_dev_app` API to kill the dev app process manually.
|
||||
1
tooling/cli/node/index.d.ts
vendored
1
tooling/cli/node/index.d.ts
vendored
@@ -4,4 +4,5 @@
|
||||
/* auto-generated by NAPI-RS */
|
||||
|
||||
export function run(args: Array<string>, binName: string | undefined | null, callback: (...args: any[]) => any): void
|
||||
export function killDevApp(callback: (...args: any[]) => any): void
|
||||
export function logError(error: string): void
|
||||
|
||||
@@ -252,7 +252,8 @@ if (!nativeBinding) {
|
||||
throw new Error(`Failed to load native binding`)
|
||||
}
|
||||
|
||||
const { run, logError } = nativeBinding
|
||||
const { run, killDevApp, logError } = nativeBinding
|
||||
|
||||
module.exports.run = run
|
||||
module.exports.killDevApp = killDevApp
|
||||
module.exports.logError = logError
|
||||
|
||||
1
tooling/cli/node/main.d.ts
vendored
1
tooling/cli/node/main.d.ts
vendored
@@ -6,3 +6,4 @@
|
||||
/* eslint-disable */
|
||||
|
||||
export function run(args: Array<string>, binName: string | undefined | null): Promise<void>
|
||||
export function killDevApp(): Promise<void>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
const { run, logError } = require('./index')
|
||||
const { run, killDevApp, logError } = require('./index')
|
||||
|
||||
module.exports.run = (args, binName) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -16,4 +16,16 @@ module.exports.run = (args, binName) => {
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.killDevApp = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
killDevApp(res => {
|
||||
if (res instanceof Error) {
|
||||
reject(res)
|
||||
} else {
|
||||
resolve(res)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.logError = logError
|
||||
|
||||
@@ -25,6 +25,23 @@ pub fn run(args: Vec<String>, bin_name: Option<String>, callback: JsFunction) ->
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn kill_dev_app(callback: JsFunction) -> Result<()> {
|
||||
let function: ThreadsafeFunction<bool, ErrorStrategy::CalleeHandled> = callback
|
||||
.create_threadsafe_function(0, |ctx| ctx.env.get_boolean(ctx.value).map(|v| vec![v]))?;
|
||||
|
||||
// we need to run in a separate thread so Node.js (e.g. vue-cli-plugin-tauri) consumers
|
||||
// can do work while `tauri dev` is running.
|
||||
std::thread::spawn(move || match tauri_cli::kill_dev_app() {
|
||||
Ok(_) => function.call(Ok(true), ThreadsafeFunctionCallMode::Blocking),
|
||||
Err(e) => function.call(
|
||||
Err(Error::new(Status::GenericFailure, format!("{:#}", e))),
|
||||
ThreadsafeFunctionCallMode::Blocking,
|
||||
),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn log_error(error: String) {
|
||||
log::error!("{}", error);
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
command_env,
|
||||
config::{get as get_config, reload as reload_config, AppUrl, BeforeDevCommand, WindowUrl},
|
||||
},
|
||||
interface::{AppInterface, ExitReason, Interface},
|
||||
interface::{rust::DevChild, AppInterface, ExitReason, Interface},
|
||||
CommandExt, Result,
|
||||
};
|
||||
use clap::{ArgAction, Parser};
|
||||
@@ -27,6 +27,7 @@ use std::{
|
||||
},
|
||||
};
|
||||
|
||||
pub(crate) static DEV_CHILD: OnceCell<Arc<Mutex<DevChild>>> = OnceCell::new();
|
||||
static BEFORE_DEV: OnceCell<Mutex<Arc<SharedChild>>> = OnceCell::new();
|
||||
static KILL_BEFORE_DEV_FLAG: OnceCell<AtomicBool> = OnceCell::new();
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ pub struct DevChild {
|
||||
}
|
||||
|
||||
impl DevChild {
|
||||
fn kill(&self) -> std::io::Result<()> {
|
||||
pub fn kill(&self) -> std::io::Result<()> {
|
||||
if let Some(child) = &*self.app_child.lock().unwrap() {
|
||||
child.kill()?;
|
||||
} else {
|
||||
@@ -194,11 +194,13 @@ impl Interface for Rust {
|
||||
|
||||
if options.no_watch {
|
||||
let (tx, rx) = sync_channel(1);
|
||||
self.run_dev(options, move |status, reason| {
|
||||
let child = self.run_dev(options, move |status, reason| {
|
||||
tx.send(()).unwrap();
|
||||
on_exit_(status, reason)
|
||||
})?;
|
||||
|
||||
let _ = crate::dev::DEV_CHILD.set(Arc::new(Mutex::new(child)));
|
||||
|
||||
rx.recv().unwrap();
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -206,6 +208,10 @@ impl Interface for Rust {
|
||||
on_exit_(status, reason)
|
||||
})?;
|
||||
|
||||
let child = Arc::new(Mutex::new(child));
|
||||
let child_ = Arc::clone(&child);
|
||||
let _ = crate::dev::DEV_CHILD.set(child_);
|
||||
|
||||
self.run_dev_watcher(child, options, on_exit)
|
||||
}
|
||||
}
|
||||
@@ -392,11 +398,10 @@ impl Rust {
|
||||
|
||||
fn run_dev_watcher<F: Fn(ExitStatus, ExitReason) + Send + Sync + 'static>(
|
||||
&mut self,
|
||||
child: DevChild,
|
||||
process: Arc<Mutex<DevChild>>,
|
||||
options: Options,
|
||||
on_exit: Arc<F>,
|
||||
) -> crate::Result<()> {
|
||||
let process = Arc::new(Mutex::new(child));
|
||||
let (tx, rx) = sync_channel(1);
|
||||
let app_path = app_dir();
|
||||
let tauri_path = tauri_dir();
|
||||
|
||||
@@ -176,6 +176,14 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn kill_dev_app() -> Result<()> {
|
||||
dev::DEV_CHILD
|
||||
.get()
|
||||
.map(|child| child.lock().unwrap().kill())
|
||||
.unwrap_or(Ok(()))
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// This maps the occurrence of `--verbose` flags to the correct log level
|
||||
fn verbosity_level(num: u8) -> Level {
|
||||
match num {
|
||||
|
||||
Reference in New Issue
Block a user