Skip to content

Commit

Permalink
chore: move run_command to shell struct
Browse files Browse the repository at this point in the history
  • Loading branch information
eugeis committed Sep 25, 2024
1 parent fdb313d commit 4fc92da
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 33 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shellchat"
version = "1.0.32"
version = "1.0.38"
edition = "2021"
authors = ["Eugen Eisler <[email protected]>"]
description = "Transforms natural language into shell commands for execution or explanation."
Expand Down
17 changes: 8 additions & 9 deletions src/lib/chatter.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::command::run_command;
use crate::command::SHELL;
use crate::common::Question;
use crate::common::HEADER_API_KEY;
Expand Down Expand Up @@ -74,29 +73,29 @@ impl Chatter {
spinner.stop();

match result {
Ok(eval_str) => loop {
Ok(command) => loop {
let answer = Select::new(
eval_str.trim(),
command.trim(),
vec!["✅ Execute", "📖 Explain", "📋 Copy", "❌ Cancel"],
)
.prompt()?;
.prompt()?;

match answer {
"✅ Execute" => {
debug!("{} {:?}", SHELL.cmd, &[&SHELL.arg, &eval_str]);
let code = run_command(&SHELL.cmd, &[&SHELL.arg, &eval_str], None)?;
debug!("{} {:?}", SHELL.cmd, &[&SHELL.arg, &command]);
let code = SHELL.run_command(&command)?;
if code != 0 {
process::exit(code);
}
}
"📖 Explain" => {
let explain_result = self.chat(&eval_str, true).await?;
let explain_result = self.chat(&command, true).await?;
termimad::print_text(&explain_result);
continue;
}
"📋 Copy" => {
let mut clipboard = clipboard::ClipboardContext::new()?;
clipboard.set_contents(eval_str.to_string())?;
clipboard.set_contents(command.to_string())?;
}
"❌ Cancel" => break,
_ => {}
Expand Down Expand Up @@ -139,4 +138,4 @@ mod tests {
let result = chatter.execute("echo Hello").await;
assert!(result.is_err()); // Assuming there's no actual server running during tests
}
}
}
53 changes: 31 additions & 22 deletions src/lib/command.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use anyhow::Result;
use std::collections::HashMap;
use std::io::IsTerminal;
use std::{env, ffi::OsStr, process::Command};
use std::{env, process::Command};

lazy_static::lazy_static! {
pub static ref OS: String = detect_os();
Expand All @@ -27,16 +26,36 @@ pub struct Shell {
pub name: String,
pub cmd: String,
pub arg: String,
pub history_cmd: Option<String>,
}

impl Shell {
pub fn new(name: &str, cmd: &str, arg: &str) -> Self {
pub fn new(name: &str, cmd: &str, arg: &str, history_cmd: Option<&str>) -> Self {
Self {
name: name.to_string(),
cmd: cmd.to_string(),
arg: arg.to_string(),
history_cmd: history_cmd.map(|cmd| cmd.to_string()),
}
}

pub fn run_command(&self, eval_str: &str) -> Result<i32> {
let status = Command::new(&self.cmd)
.arg(&self.arg)
.arg(eval_str)
.status()?;

if status.success() {
if let Some(history_cmd) = &self.history_cmd {
let _ = Command::new(&self.cmd)
.arg(&self.arg)
.arg(format!("{} \"{}\"", history_cmd, eval_str))
.status();
}
}

Ok(status.code().unwrap_or_default())
}
}

pub fn detect_shell() -> Shell {
Expand All @@ -46,17 +65,17 @@ pub fn detect_shell() -> Shell {
let v = v.to_lowercase();
if v.split(';').count() >= 3 {
if v.contains("powershell\\7\\") {
Some(Shell::new("pwsh", "pwsh.exe", "-c"))
Some(Shell::new("pwsh", "pwsh.exe", "-c", None))
} else {
Some(Shell::new("powershell", "powershell.exe", "-Command"))
Some(Shell::new("powershell", "powershell.exe", "-Command", None))
}
} else {
None
}
}) {
ret
} else {
Shell::new("cmd", "cmd.exe", "/C")
Shell::new("cmd", "cmd.exe", "/C", None)
}
} else {
let shell = env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());
Expand All @@ -65,24 +84,14 @@ pub fn detect_shell() -> Shell {
None => &shell,
};
match shell {
"bash" | "zsh" | "fish" | "pwsh" => Shell::new(shell, shell, "-c"),
_ => Shell::new("sh", "sh", "-c"),
"bash" => Shell::new(shell, shell, "-c", Some("history -s")),
"zsh" => Shell::new(shell, shell, "-c", Some("print -s")),
"fish" | "pwsh" => Shell::new(shell, shell, "-c", None),
_ => Shell::new("sh", "sh", "-c", None),
}
}
}

pub fn run_command<T: AsRef<OsStr>>(
cmd: &str,
args: &[T],
envs: Option<HashMap<String, String>>,
) -> Result<i32> {
let status = Command::new(cmd)
.args(args.iter())
.envs(envs.unwrap_or_default())
.status()?;
Ok(status.code().unwrap_or_default())
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -103,8 +112,8 @@ mod tests {

#[test]
fn test_run_command() {
let result = run_command("echo", &["Hello, world!"], None);
let result = SHELL.run_command("echo Hello, world!");
assert!(result.is_ok());
assert_eq!(result.unwrap(), 0);
}
}
}

0 comments on commit 4fc92da

Please sign in to comment.