mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-04-29 12:06:01 +02:00
fix(core/shell): speedup Command.execute & fix extra new lines (#1299)
* fix(core/shell): speedup `Command.execute` & fix extra new lines The speed gains comes from running the Command in Rust fully and returning the result in one go instead of using events. The extra new lines was a regression from https://github.com/tauri-apps/tauri/pull/6519 ref: https://github.com/tauri-apps/tauri/issues/7684#issuecomment-2100897383 * fmt * dedup code
This commit is contained in:
@@ -94,18 +94,15 @@ fn default_env() -> Option<HashMap<String, String>> {
|
||||
Some(HashMap::default())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[tauri::command]
|
||||
pub fn execute<R: Runtime>(
|
||||
#[inline(always)]
|
||||
fn prepare_cmd<R: Runtime>(
|
||||
window: Window<R>,
|
||||
shell: State<'_, Shell<R>>,
|
||||
program: String,
|
||||
args: ExecuteArgs,
|
||||
on_event: Channel,
|
||||
options: CommandOptions,
|
||||
command_scope: CommandScope<crate::scope::ScopeAllowedCommand>,
|
||||
global_scope: GlobalScope<crate::scope::ScopeAllowedCommand>,
|
||||
) -> crate::Result<ChildId> {
|
||||
) -> crate::Result<(crate::process::Command, EncodingWrapper)> {
|
||||
let scope = crate::scope::ShellScope {
|
||||
scopes: command_scope
|
||||
.allows()
|
||||
@@ -151,6 +148,7 @@ pub fn execute<R: Runtime>(
|
||||
} else {
|
||||
command = command.env_clear();
|
||||
}
|
||||
|
||||
let encoding = match options.encoding {
|
||||
Option::None => EncodingWrapper::Text(None),
|
||||
Some(encoding) => match encoding.as_str() {
|
||||
@@ -168,6 +166,82 @@ pub fn execute<R: Runtime>(
|
||||
},
|
||||
};
|
||||
|
||||
Ok((command, encoding))
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
enum Output {
|
||||
String(String),
|
||||
Raw(Vec<u8>),
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ChildProcessReturn {
|
||||
code: Option<i32>,
|
||||
signal: Option<i32>,
|
||||
#[serde(flatten)]
|
||||
stdout: Output,
|
||||
#[serde(flatten)]
|
||||
stderr: Output,
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[tauri::command]
|
||||
pub fn execute<R: Runtime>(
|
||||
window: Window<R>,
|
||||
program: String,
|
||||
args: ExecuteArgs,
|
||||
options: CommandOptions,
|
||||
command_scope: CommandScope<crate::scope::ScopeAllowedCommand>,
|
||||
global_scope: GlobalScope<crate::scope::ScopeAllowedCommand>,
|
||||
) -> crate::Result<ChildProcessReturn> {
|
||||
let (command, encoding) =
|
||||
prepare_cmd(window, program, args, options, command_scope, global_scope)?;
|
||||
|
||||
let mut command: std::process::Command = command.into();
|
||||
let output = command.output()?;
|
||||
|
||||
let (stdout, stderr) = match encoding {
|
||||
EncodingWrapper::Text(Some(encoding)) => (
|
||||
Output::String(encoding.decode_with_bom_removal(&output.stdout).0.into()),
|
||||
Output::String(encoding.decode_with_bom_removal(&output.stderr).0.into()),
|
||||
),
|
||||
EncodingWrapper::Text(None) => (
|
||||
Output::String(String::from_utf8(output.stdout)?),
|
||||
Output::String(String::from_utf8(output.stderr)?),
|
||||
),
|
||||
EncodingWrapper::Raw => (Output::Raw(output.stdout), Output::Raw(output.stderr)),
|
||||
};
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::process::ExitStatusExt;
|
||||
|
||||
Ok(ChildProcessReturn {
|
||||
code: output.status.code(),
|
||||
#[cfg(windows)]
|
||||
signal: None,
|
||||
#[cfg(unix)]
|
||||
signal: output.status.signal(),
|
||||
stdout,
|
||||
stderr,
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[tauri::command]
|
||||
pub fn spawn<R: Runtime>(
|
||||
window: Window<R>,
|
||||
shell: State<'_, Shell<R>>,
|
||||
program: String,
|
||||
args: ExecuteArgs,
|
||||
on_event: Channel,
|
||||
options: CommandOptions,
|
||||
command_scope: CommandScope<crate::scope::ScopeAllowedCommand>,
|
||||
global_scope: GlobalScope<crate::scope::ScopeAllowedCommand>,
|
||||
) -> crate::Result<ChildId> {
|
||||
let (command, encoding) =
|
||||
prepare_cmd(window, program, args, options, command_scope, global_scope)?;
|
||||
|
||||
let (mut rx, child) = command.spawn()?;
|
||||
|
||||
let pid = child.pid();
|
||||
|
||||
@@ -27,6 +27,9 @@ pub enum Error {
|
||||
/// JSON error.
|
||||
#[error(transparent)]
|
||||
Json(#[from] serde_json::Error),
|
||||
/// Utf8 error.
|
||||
#[error(transparent)]
|
||||
Utf8(#[from] std::string::FromUtf8Error),
|
||||
}
|
||||
|
||||
impl Serialize for Error {
|
||||
|
||||
@@ -81,6 +81,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
|
||||
.js_init_script(include_str!("init-iife.js").to_string())
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
commands::execute,
|
||||
commands::spawn,
|
||||
commands::stdin_write,
|
||||
commands::kill,
|
||||
commands::open
|
||||
|
||||
Reference in New Issue
Block a user