From 837dcb2a57396f5ec7ed89c2d57f971a03f6f46d Mon Sep 17 00:00:00 2001 From: Cristian Oliveira Date: Sun, 21 May 2023 01:39:35 +0200 Subject: [PATCH] feat: allow complex commands --- examples/complex-commands.yml | 4 +++ src/cmd.rs | 63 ++++++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 examples/complex-commands.yml diff --git a/examples/complex-commands.yml b/examples/complex-commands.yml new file mode 100644 index 0000000..265b3c8 --- /dev/null +++ b/examples/complex-commands.yml @@ -0,0 +1,4 @@ +- name: run my test + run: "echo 'foo bar baz' | sed 's/foo/bar/g'" + change: "**" + run_on_init: true diff --git a/src/cmd.rs b/src/cmd.rs index d2dc152..adf8f71 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -1,33 +1,61 @@ use std::process::{ Command, Stdio }; fn command_parser(command: String) -> Vec { - let mut commands = vec![]; - let mut tokens: Vec<&str> = command.split(' ').collect(); + let formatted = command.replace("'", " ' ").replace("\"", " \" "); + let mut tokens: Vec<&str> = formatted.split(' ').collect(); let init = tokens.remove(0); - commands.push(Command::new(init)); + let mut current_cmd = Command::new(init); while tokens.len() > 0 { let token = tokens.remove(0); match token.clone() { "|" | "||" | "&" | "&&" => { - let mut child = commands.remove(commands.len() - 1); - child.stdout(Stdio::piped()); + current_cmd.stdout(Stdio::piped()); let cmdname = tokens.remove(0); let mut cmd = Command::new(cmdname); - let result = child.spawn().unwrap().stdout.unwrap(); + let result = current_cmd.spawn().unwrap().stdout.unwrap(); cmd.stdin(Stdio::from(result)); - commands.push(cmd); + current_cmd = cmd; } - _ => { - let mut cmd = commands.remove(commands.len() - 1); - cmd.arg(token.replace("'", "").replace("\"", "")); - commands.push(cmd); + + "\"" => { + let mut string_arg = String::new(); + while tokens.len() > 0 { + let token = tokens.remove(0); + if token == "\"" { + string_arg.pop(); + current_cmd.arg(string_arg); + break; + } + string_arg.push_str(token); + string_arg.push_str(" "); + } + } + + "'" => { + let mut string_arg = String::new(); + while tokens.len() > 0 { + let token = tokens.remove(0); + if token == "'" { + string_arg.pop(); + current_cmd.arg(string_arg); + break; + } + string_arg.push_str(token); + string_arg.push_str(" "); + } } + + arg if arg.len() > 0 => { + current_cmd.arg(arg); + } + + _ => {} } } - commands + vec![current_cmd] } pub fn execute(command_line: String) -> Result<(), String> { @@ -104,3 +132,14 @@ fn it_allows_piping_outputs() { assert_eq!("bar\n", String::from_utf8_lossy(result)); } +#[test] +fn it_accept_strings_as_arguments() { + let result = command_parser(String::from("echo 'foo bar baz'")); + + let mut cmd2 = Command::new("echo"); + cmd2.arg("foo bar baz"); + + let commands = vec![cmd2]; + + assert_eq!(format!("{:?}", commands), format!("{:?}", result)) +}