diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 5e490216..617841b2 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -23,4 +23,3 @@ jobs: run: cargo build --verbose - name: Run tests run: cargo test --verbose - diff --git a/app/src/manager/folder.rs b/app/src/manager/folder.rs index e9a3683e..6b0143f1 100644 --- a/app/src/manager/folder.rs +++ b/app/src/manager/folder.rs @@ -76,7 +76,7 @@ impl<'a> Folder<'a> { // TODO: to be configured by THEME? let style = Style::new().fg(Color::Rgb(255, 255, 50)).add_modifier(Modifier::ITALIC); Some(vec![ - Span::raw(short.prefix.join(&head).display().to_string()), + Span::raw(short.prefix.join(head).display().to_string()), Span::styled(body, style), Span::raw(tail), ]) diff --git a/core/src/external/shell.rs b/core/src/external/shell.rs index 2ca8f185..4285c7a7 100644 --- a/core/src/external/shell.rs +++ b/core/src/external/shell.rs @@ -15,37 +15,44 @@ impl ShellOpt { self.piped = true; self } + + #[inline] + fn stdio(&self) -> Stdio { + if self.orphan { + Stdio::null() + } else if self.piped { + Stdio::piped() + } else { + Stdio::inherit() + } + } } pub fn shell(opt: ShellOpt) -> Result { - #[cfg(not(target_os = "windows"))] - { - Ok( - Command::new("sh") - .arg("-c") - .arg(opt.cmd) - .arg("") // $0 is the command name - .args(opt.args) - .stdin(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .stdout(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .stderr(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .kill_on_drop(!opt.orphan) - .spawn()?, - ) - } + #[cfg(unix)] + return Ok( + Command::new("sh") + .arg("-c") + .stdin(opt.stdio()) + .stdout(opt.stdio()) + .stderr(opt.stdio()) + .arg(opt.cmd) + .arg("") // $0 is the command name + .args(opt.args) + .kill_on_drop(!opt.orphan) + .spawn()?, + ); - #[cfg(target_os = "windows")] - { - Ok( - Command::new("cmd") - .arg("/C") - .arg(opt.cmd) - .args(opt.args) - .stdin(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .stdout(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .stderr(if opt.piped { Stdio::piped() } else { Stdio::inherit() }) - .kill_on_drop(true) - .spawn()?, - ) - } + #[cfg(windows)] + return Ok( + Command::new("cmd") + .stdin(opt.stdio()) + .stdout(opt.stdio()) + .stderr(opt.stdio()) + .arg("/C") + .arg(opt.cmd) + .args(opt.args) + .kill_on_drop(true) + .spawn()?, + ); } diff --git a/core/src/manager/finder.rs b/core/src/manager/finder.rs index f2f9e3a7..6009e9a4 100644 --- a/core/src/manager/finder.rs +++ b/core/src/manager/finder.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, collections::BTreeMap, ffi::OsStr}; +use std::{collections::BTreeMap, ffi::OsStr, borrow::Cow}; use anyhow::Result; use regex::bytes::Regex; diff --git a/core/src/tasks/workers/process.rs b/core/src/tasks/workers/process.rs index 6bed7b44..b45c86f7 100644 --- a/core/src/tasks/workers/process.rs +++ b/core/src/tasks/workers/process.rs @@ -2,7 +2,6 @@ use std::{ffi::OsString, mem}; use anyhow::Result; use tokio::{io::{AsyncBufReadExt, BufReader}, select, sync::{mpsc, oneshot}}; -use tracing::trace; use crate::{emit, external::{self, ShellOpt}, tasks::TaskOp, BLOCKER}; @@ -41,26 +40,37 @@ impl Process { fn done(&self, id: usize) -> Result<()> { Ok(self.sch.send(TaskOp::Done(id))?) } pub(crate) async fn open(&self, mut task: ProcessOpOpen) -> Result<()> { + let opt = ShellOpt::from(&mut task); if task.block { let _guard = BLOCKER.acquire().await.unwrap(); emit!(Stop(true)).await; - match external::shell(ShellOpt::from(&mut task)) { + match external::shell(opt) { Ok(mut child) => { child.wait().await.ok(); + self.done(task.id)?; } Err(e) => { - trace!("Failed to spawn process: {e}"); + self.sch.send(TaskOp::New(task.id, 0))?; + self.log(task.id, format!("Failed to spawn process: {e}"))?; } } - emit!(Stop(false)).await; + return Ok(emit!(Stop(false)).await); + } - self.sch.send(TaskOp::Adv(task.id, 1, 0))?; - return self.done(task.id); + if task.orphan { + match external::shell(opt) { + Ok(_) => self.done(task.id)?, + Err(e) => { + self.sch.send(TaskOp::New(task.id, 0))?; + self.log(task.id, format!("Failed to spawn process: {e}"))?; + } + } + return Ok(()); } self.sch.send(TaskOp::New(task.id, 0))?; - let mut child = external::shell(ShellOpt::from(&mut task).with_piped())?; + let mut child = external::shell(opt.with_piped())?; let mut stdout = BufReader::new(child.stdout.take().unwrap()).lines(); let mut stderr = BufReader::new(child.stderr.take().unwrap()).lines();