diff --git a/src/shell_interface.rs b/src/shell_interface.rs index 0e6ff26..a9fb1a1 100644 --- a/src/shell_interface.rs +++ b/src/shell_interface.rs @@ -1,5 +1,5 @@ -use crate::log; use crate::logger::{LogLevel, Logger}; +use crate::{log, osf}; use std::error::Error; use std::ffi::OsString; use std::fmt::{Debug, Display, Formatter}; @@ -29,12 +29,12 @@ pub enum ShellCommand { Editor(Vec), Execute { working_directory: PathBuf, - command: OsString, + command: Vec, }, } impl ShellCommand { - pub fn at(self, environment: &mut E) -> EnvCommand { + pub fn in_env(self, environment: &mut E) -> EnvCommand { EnvCommand { command: self, environment, @@ -69,6 +69,17 @@ pub struct ScpParam { pub path: PathBuf, } +impl From<&ScpParam> for OsString { + fn from(value: &ScpParam) -> Self { + let mut builder = osf!(); + if let Some(server) = &value.server { + builder += format!("{server}:"); + } + builder += &value.path; + builder.build() + } +} + impl Display for ShellCommand { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!( @@ -94,8 +105,59 @@ pub(crate) fn command_to_string(command: &Command) -> String { .join(" ") } -fn build_command_from_shell_command(_shell_command: &ShellCommand) -> Command { - todo!() +macro_rules! cmd { + ($programm: expr $(, $arg:expr )*)=> {{ + #[allow(unused_mut)] + let mut cmd = Command::new($programm); + $( cmd.arg($arg); )* + cmd + }}; +} + +fn build_command_from_shell_command(shell_command: &ShellCommand) -> Command { + match shell_command { + ShellCommand::Ssh { + address, + server_command, + } => cmd!( + "ssh", + address, + match server_command { + ServerCommand::Realpath { path } => osf!("realpath -e ") + path, + ServerCommand::Ls { dir } => osf!("ls ") + dir, + ServerCommand::Rm { file } => osf!("rm ") + file, + ServerCommand::Mv { + source, + destination, + } => osf!("mv ") + source + " " + destination, + ServerCommand::Execute { + working_directory, + command, + } => osf!("cd ") + working_directory + "; " + command, + } + ), + ShellCommand::Scp { + source, + destination, + } => cmd!("scp", OsString::from(source), OsString::from(destination)), + ShellCommand::SshAgent => cmd!("ssh-agent", "-s"), + ShellCommand::ShhAdd => cmd!("ssh-add"), + ShellCommand::Editor(args) => { + let mut args = args.clone(); + let mut cmd = cmd!(args.remove(0)); + cmd.args(args); + cmd + } + ShellCommand::Execute { + working_directory, + command, + } => { + let mut args = command.clone(); + let mut cmd = cmd!(args.remove(0)); + cmd.args(args).current_dir(working_directory); + cmd + } + } } pub trait ShellInterface { @@ -380,3 +442,93 @@ where } impl Error for ExecutionError where T: AsRef + Debug {} + +#[cfg(test)] +mod test_commands { + use crate::shell_interface::{ScpParam, ServerCommand, ShellCommand}; + use std::path::PathBuf; + + #[test] + fn test_to_string() { + assert_eq!( + ShellCommand::Ssh { + address: "crea".to_string(), + server_command: ServerCommand::Realpath { + path: PathBuf::from("plugins/*.jar") + } + } + .to_string(), + r#"ssh crea "realpath -e plugins/*.jar""# + ); + assert_eq!( + ShellCommand::Ssh { + address: "crea".to_string(), + server_command: ServerCommand::Ls { + dir: PathBuf::from("creative/plugins") + } + } + .to_string(), + r#"ssh crea "ls creative/plugins""# + ); + assert_eq!( + ShellCommand::Ssh { + address: "crea".to_string(), + server_command: ServerCommand::Rm { + file: PathBuf::from("foo.txt") + }, + } + .to_string(), + r#"ssh crea "rm foo.txt""# + ); + assert_eq!( + ShellCommand::Ssh { + address: "crea".to_string(), + server_command: ServerCommand::Mv { + source: PathBuf::from("foo"), + destination: PathBuf::from("bar") + } + } + .to_string(), + r#"ssh crea "mv foo bar""# + ); + assert_eq!( + ShellCommand::Ssh { + address: "crea".to_string(), + server_command: ServerCommand::Execute { + working_directory: PathBuf::from(".."), + command: "sudo rm -rf *".into(), + } + } + .to_string(), + r#"ssh crea "cd ..; sudo rm -rf *""# + ); + assert_eq!( + ShellCommand::Scp { + source: ScpParam { + server: None, + path: PathBuf::from("target/mssh") + }, + destination: ScpParam { + server: Some("crea".into()), + path: PathBuf::from("/usr/bin") + }, + } + .to_string(), + r#"scp target/mssh crea:/usr/bin"# + ); + assert_eq!(ShellCommand::SshAgent.to_string(), r#"ssh-agent -s"#); + assert_eq!(ShellCommand::ShhAdd.to_string(), r#"ssh-add"#); + assert_eq!( + ShellCommand::Editor(vec!["kate".into(), "-b".into(), "test.txt".into()]).to_string(), + r#"kate -b test.txt"# + ); + assert_eq!( + ShellCommand::Execute { + working_directory: PathBuf::from("/home/me/server"), + command: vec!["java".into(), "-jar".into(), "paper.jar".into()] + } + .to_string(), + r#"java -jar paper.jar"# + ); + } +}