From 1fa817f12f07a5a219965f6f087ca3e70fd9c56d Mon Sep 17 00:00:00 2001 From: Duane Johnson Date: Fri, 20 Jan 2023 15:15:28 -0700 Subject: [PATCH] Handle shebang more thoroughly in scripts plugin (#160) * feat(scripts): allow whitespace after shebang `#!` characters * feat(scripts): allow shebang line to have its own args * fix(scripts): improve unwraps and extra allocations; use SHELL env variable --- plugins/src/scripts/mod.rs | 44 +++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/plugins/src/scripts/mod.rs b/plugins/src/scripts/mod.rs index 8c93dd7..80e430b 100644 --- a/plugins/src/scripts/mod.rs +++ b/plugins/src/scripts/mod.rs @@ -6,6 +6,7 @@ use pop_launcher::*; use flume::Sender; use futures::StreamExt; +use regex::Regex; use std::collections::VecDeque; use std::path::{Path, PathBuf}; use std::process::Stdio; @@ -54,11 +55,42 @@ impl App { async fn activate(&mut self, id: u32) { if let Some(script) = self.scripts.get(id as usize) { - let interpreter = script.interpreter.as_deref().unwrap_or("sh"); + let mut shell: String = Default::default(); + let mut args: Vec<&OsStr> = Vec::new(); + + let program = script + .interpreter + .as_deref() + .and_then(|interpreter| { + // split the shebang into parts, e.g. ["/bin/bash"], or a more complex ["/usr/bin/env", "bash"] + let mut parts = interpreter.split_ascii_whitespace(); + + // first part must be the command to run, e.g. "/usr/bin/env" + let command = parts.next()?; + + for arg in parts { + args.push(arg.as_ref()); + } + + Some(command) + }) + .or_else(|| { + if let Ok(string) = std::env::var("SHELL") { + shell = string; + return Some(&shell); + } + + None + }) + .unwrap_or("sh"); + + // add the script file itself as a final arg for the interpreter + args.push(script.path.as_ref()); + send(&mut self.out, PluginResponse::Close).await; - let _ = Command::new(interpreter) - .arg(script.path.as_os_str()) + let _ = Command::new(program) + .args(args) .stdin(Stdio::null()) .stdout(Stdio::null()) .stderr(Stdio::null()) @@ -156,6 +188,8 @@ async fn load_from(path: &Path, paths: &mut VecDeque, tx: Sender