mirror of
https://github.com/sagiegurari/duckscript
synced 2024-09-29 20:54:34 +00:00
commit
d1c47dc556
|
@ -1,5 +1,10 @@
|
|||
## CHANGELOG
|
||||
|
||||
### v0.9.3
|
||||
|
||||
* Fix: if/else condition with a command that accepts empty values #390
|
||||
* Enhancement: dump commands will print to output if no output variable is defined
|
||||
|
||||
### v0.9.2 (2023-11-18)
|
||||
|
||||
* Enhancement: \[Breaking Change\] add support for renaming directories via mv command #374
|
||||
|
|
|
@ -39,13 +39,17 @@ impl Command for CommandImpl {
|
|||
_arguments: Vec<String>,
|
||||
_state: &mut HashMap<String, StateValue>,
|
||||
_variables: &mut HashMap<String, String>,
|
||||
_output_variable: Option<String>,
|
||||
output_variable: Option<String>,
|
||||
instructions: &Vec<Instruction>,
|
||||
_commands: &mut Commands,
|
||||
_line: usize,
|
||||
) -> CommandResult {
|
||||
let string_value = format!("{:#?}", instructions).to_string();
|
||||
|
||||
if output_variable.is_none() {
|
||||
println!("{}", string_value);
|
||||
}
|
||||
|
||||
CommandResult::Continue(Some(string_value))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,13 +39,17 @@ impl Command for CommandImpl {
|
|||
_arguments: Vec<String>,
|
||||
state: &mut HashMap<String, StateValue>,
|
||||
_variables: &mut HashMap<String, String>,
|
||||
_output_variable: Option<String>,
|
||||
output_variable: Option<String>,
|
||||
_instructions: &Vec<Instruction>,
|
||||
_commands: &mut Commands,
|
||||
_line: usize,
|
||||
) -> CommandResult {
|
||||
let string_value = format!("{:#?}", state).to_string();
|
||||
|
||||
if output_variable.is_none() {
|
||||
println!("{}", string_value);
|
||||
}
|
||||
|
||||
CommandResult::Continue(Some(string_value))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,13 +39,17 @@ impl Command for CommandImpl {
|
|||
_arguments: Vec<String>,
|
||||
_state: &mut HashMap<String, StateValue>,
|
||||
variables: &mut HashMap<String, String>,
|
||||
_output_variable: Option<String>,
|
||||
output_variable: Option<String>,
|
||||
_instructions: &Vec<Instruction>,
|
||||
_commands: &mut Commands,
|
||||
_line: usize,
|
||||
) -> CommandResult {
|
||||
let string_value = format!("{:#?}", variables).to_string();
|
||||
|
||||
if output_variable.is_none() {
|
||||
println!("{}", string_value);
|
||||
}
|
||||
|
||||
CommandResult::Continue(Some(string_value))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ pub(crate) fn load(commands: &mut Commands) -> Result<(), ScriptError> {
|
|||
commands.set(noop::create(PACKAGE))?;
|
||||
commands.set(not::create(PACKAGE))?;
|
||||
commands.set(print::create(PACKAGE))?;
|
||||
commands.set(println::create(PACKAGE)?)?;
|
||||
commands.set(println::create(PACKAGE))?;
|
||||
commands.set(read::create(PACKAGE))?;
|
||||
commands.set(release::create(PACKAGE))?;
|
||||
|
||||
|
|
|
@ -134,6 +134,64 @@ fn add_color(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn run_print(arguments: Vec<String>) -> CommandResult {
|
||||
// collect options
|
||||
let mut styles = vec![];
|
||||
let mut text_color = None;
|
||||
let mut background_color = None;
|
||||
let mut index = 0;
|
||||
let mut looking_for = LookingFor::Flag;
|
||||
for argument in &arguments {
|
||||
index = index + 1;
|
||||
|
||||
match looking_for {
|
||||
LookingFor::Flag => match argument.as_str() {
|
||||
"--style" | "-s" => looking_for = LookingFor::Style,
|
||||
"--color" | "-c" => looking_for = LookingFor::TextColor,
|
||||
"--background-color" | "-bgc" => looking_for = LookingFor::BackgroundColor,
|
||||
_ => break,
|
||||
},
|
||||
LookingFor::Style => {
|
||||
styles.push(argument.to_string());
|
||||
looking_for = LookingFor::Flag;
|
||||
}
|
||||
LookingFor::TextColor => {
|
||||
text_color = Some(argument.to_string());
|
||||
looking_for = LookingFor::Flag;
|
||||
}
|
||||
LookingFor::BackgroundColor => {
|
||||
background_color = Some(argument.to_string());
|
||||
looking_for = LookingFor::Flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
if index > 0 {
|
||||
index = index - 1;
|
||||
}
|
||||
|
||||
// generate whole string
|
||||
let mut string = String::new();
|
||||
let mut count = 0;
|
||||
for argument in &arguments[index..] {
|
||||
count = count + 1;
|
||||
string.push_str(argument);
|
||||
string.push(' ');
|
||||
}
|
||||
if count > 0 {
|
||||
string.remove(string.len() - 1);
|
||||
}
|
||||
|
||||
// add colors
|
||||
let mut styled_string = string.normal();
|
||||
styled_string = add_color(styled_string, text_color, false);
|
||||
styled_string = add_color(styled_string, background_color, true);
|
||||
styled_string = add_styles(styled_string, styles);
|
||||
|
||||
print!("{}", styled_string);
|
||||
|
||||
CommandResult::Continue(Some(count.to_string()))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct CommandImpl {
|
||||
package: String,
|
||||
|
@ -157,61 +215,7 @@ impl Command for CommandImpl {
|
|||
}
|
||||
|
||||
fn run(&self, arguments: Vec<String>) -> CommandResult {
|
||||
// collect options
|
||||
let mut styles = vec![];
|
||||
let mut text_color = None;
|
||||
let mut background_color = None;
|
||||
let mut index = 0;
|
||||
let mut looking_for = LookingFor::Flag;
|
||||
for argument in &arguments {
|
||||
index = index + 1;
|
||||
|
||||
match looking_for {
|
||||
LookingFor::Flag => match argument.as_str() {
|
||||
"--style" | "-s" => looking_for = LookingFor::Style,
|
||||
"--color" | "-c" => looking_for = LookingFor::TextColor,
|
||||
"--background-color" | "-bgc" => looking_for = LookingFor::BackgroundColor,
|
||||
_ => break,
|
||||
},
|
||||
LookingFor::Style => {
|
||||
styles.push(argument.to_string());
|
||||
looking_for = LookingFor::Flag;
|
||||
}
|
||||
LookingFor::TextColor => {
|
||||
text_color = Some(argument.to_string());
|
||||
looking_for = LookingFor::Flag;
|
||||
}
|
||||
LookingFor::BackgroundColor => {
|
||||
background_color = Some(argument.to_string());
|
||||
looking_for = LookingFor::Flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
if index > 0 {
|
||||
index = index - 1;
|
||||
}
|
||||
|
||||
// generate whole string
|
||||
let mut string = String::new();
|
||||
let mut count = 0;
|
||||
for argument in &arguments[index..] {
|
||||
count = count + 1;
|
||||
string.push_str(argument);
|
||||
string.push(' ');
|
||||
}
|
||||
if count > 0 {
|
||||
string.remove(string.len() - 1);
|
||||
}
|
||||
|
||||
// add colors
|
||||
let mut styled_string = string.normal();
|
||||
styled_string = add_color(styled_string, text_color, false);
|
||||
styled_string = add_color(styled_string, background_color, true);
|
||||
styled_string = add_styles(styled_string, styles);
|
||||
|
||||
print!("{}", styled_string);
|
||||
|
||||
CommandResult::Continue(Some(count.to_string()))
|
||||
run_print(arguments)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,47 @@
|
|||
use crate::types::command::create_alias_command;
|
||||
use crate::sdk::std::print::run_print;
|
||||
use crate::utils::pckg;
|
||||
use duckscript::types::command::Command;
|
||||
use duckscript::types::error::ScriptError;
|
||||
use duckscript::types::command::{Command, CommandResult};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "./mod_test.rs"]
|
||||
mod mod_test;
|
||||
|
||||
pub(crate) fn create(package: &str) -> Result<Box<dyn Command>, ScriptError> {
|
||||
let name = pckg::concat(package, "Println");
|
||||
let command = create_alias_command(
|
||||
name,
|
||||
vec!["println".to_string()],
|
||||
include_str!("help.md").to_string(),
|
||||
"println".to_string(),
|
||||
include_str!("script.ds").to_string(),
|
||||
0,
|
||||
)?;
|
||||
|
||||
Ok(Box::new(command))
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct CommandImpl {
|
||||
package: String,
|
||||
}
|
||||
|
||||
impl Command for CommandImpl {
|
||||
fn name(&self) -> String {
|
||||
pckg::concat(&self.package, "Println")
|
||||
}
|
||||
|
||||
fn aliases(&self) -> Vec<String> {
|
||||
vec!["println".to_string()]
|
||||
}
|
||||
|
||||
fn help(&self) -> String {
|
||||
include_str!("help.md").to_string()
|
||||
}
|
||||
|
||||
fn clone_and_box(&self) -> Box<dyn Command> {
|
||||
Box::new((*self).clone())
|
||||
}
|
||||
|
||||
fn run(&self, arguments: Vec<String>) -> CommandResult {
|
||||
let result = run_print(arguments);
|
||||
|
||||
match result {
|
||||
CommandResult::Continue(_) => println!(""),
|
||||
_ => (),
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create(package: &str) -> Box<dyn Command> {
|
||||
Box::new(CommandImpl {
|
||||
package: package.to_string(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,26 @@
|
|||
use super::*;
|
||||
use crate::test;
|
||||
use crate::test::CommandValidation;
|
||||
|
||||
#[test]
|
||||
fn common_functions() {
|
||||
test::test_common_command_functions(create("").unwrap());
|
||||
test::test_common_command_functions(create(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_no_args() {
|
||||
test::run_script_and_validate(
|
||||
vec![create("")],
|
||||
"out = println",
|
||||
CommandValidation::Match("out".to_string(), "0".to_string()),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_multiple_args() {
|
||||
test::run_script_and_validate(
|
||||
vec![create("")],
|
||||
"out = println 1 2 \"3 4\"",
|
||||
CommandValidation::Match("out".to_string(), "3".to_string()),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
scope::println::count = set 0
|
||||
|
||||
if not array_is_empty ${scope::println::arguments}
|
||||
scope::println::commandline = array_join ${scope::println::arguments} "\" \""
|
||||
scope::println::commandline = set "\"${scope::println::commandline}"
|
||||
scope::println::commandline = substring ${scope::println::commandline} -2
|
||||
scope::println::count = print %{scope::println::commandline}
|
||||
end
|
||||
|
||||
echo
|
||||
|
||||
set ${scope::println::count}
|
|
@ -12,12 +12,20 @@ mod eval_test;
|
|||
fn parse(arguments: &Vec<String>) -> Result<Instruction, String> {
|
||||
let mut line_buffer = String::new();
|
||||
for argument in arguments {
|
||||
if argument.contains(" ") {
|
||||
line_buffer.push('"');
|
||||
}
|
||||
line_buffer.push_str(argument);
|
||||
if argument.contains(" ") {
|
||||
line_buffer.push('"');
|
||||
if argument.is_empty() {
|
||||
line_buffer.push_str("\"\"");
|
||||
} else if argument.starts_with("\"") && argument.ends_with("\"") {
|
||||
line_buffer.push('\\');
|
||||
line_buffer.push_str(argument);
|
||||
line_buffer.push('\\');
|
||||
} else {
|
||||
if argument.contains(" ") {
|
||||
line_buffer.push('"');
|
||||
}
|
||||
line_buffer.push_str(argument);
|
||||
if argument.contains(" ") {
|
||||
line_buffer.push('"');
|
||||
}
|
||||
}
|
||||
line_buffer.push(' ');
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::*;
|
||||
use crate::sdk::std::string::equals::create as EqCreate;
|
||||
use crate::test::SetCommand;
|
||||
|
||||
#[test]
|
||||
|
@ -143,3 +144,66 @@ fn eval_with_error_parse_error() {
|
|||
_ => panic!("invalid result type."),
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_with_eq_empty_args() {
|
||||
let mut commands = Commands::new();
|
||||
match commands.set(EqCreate("")) {
|
||||
Err(error) => panic!("{}", error),
|
||||
_ => (),
|
||||
};
|
||||
|
||||
let result = eval_with_error(
|
||||
&vec!["eq".to_string(), "".to_string(), "".to_string()],
|
||||
&mut HashMap::new(),
|
||||
&mut HashMap::new(),
|
||||
&mut commands,
|
||||
);
|
||||
|
||||
match result {
|
||||
CommandResult::Continue(value) => assert_eq!(value.unwrap(), "true"),
|
||||
_ => panic!("invalid result type."),
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_with_eq_true_args() {
|
||||
let mut commands = Commands::new();
|
||||
match commands.set(EqCreate("")) {
|
||||
Err(error) => panic!("{}", error),
|
||||
_ => (),
|
||||
};
|
||||
|
||||
let result = eval_with_error(
|
||||
&vec!["eq".to_string(), "true".to_string(), "true".to_string()],
|
||||
&mut HashMap::new(),
|
||||
&mut HashMap::new(),
|
||||
&mut commands,
|
||||
);
|
||||
|
||||
match result {
|
||||
CommandResult::Continue(value) => assert_eq!(value.unwrap(), "true"),
|
||||
_ => panic!("invalid result type."),
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_with_eq_true_and_false_args() {
|
||||
let mut commands = Commands::new();
|
||||
match commands.set(EqCreate("")) {
|
||||
Err(error) => panic!("{}", error),
|
||||
_ => (),
|
||||
};
|
||||
|
||||
let result = eval_with_error(
|
||||
&vec!["eq".to_string(), "true".to_string(), "false".to_string()],
|
||||
&mut HashMap::new(),
|
||||
&mut HashMap::new(),
|
||||
&mut commands,
|
||||
);
|
||||
|
||||
match result {
|
||||
CommandResult::Continue(value) => assert_eq!(value.unwrap(), "false"),
|
||||
_ => panic!("invalid result type."),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -163,6 +163,38 @@ fn test_if_call_to_functions
|
|||
assert ${valid}
|
||||
end
|
||||
|
||||
fn test_eq_empty_strings
|
||||
valid = set false
|
||||
|
||||
if eq "" ""
|
||||
valid = set true
|
||||
end
|
||||
|
||||
assert ${valid}
|
||||
end
|
||||
|
||||
fn test_eq_different_strings
|
||||
valid = set true
|
||||
|
||||
if eq "1 2" "1 3"
|
||||
valid = set false
|
||||
end
|
||||
|
||||
assert ${valid}
|
||||
end
|
||||
|
||||
fn test_not_is_array_empty
|
||||
valid = set false
|
||||
|
||||
array = array 1 2 3
|
||||
if not array_is_empty ${array}
|
||||
valid = set true
|
||||
end
|
||||
release ${array}
|
||||
|
||||
assert ${valid}
|
||||
end
|
||||
|
||||
fn _test_return_true
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ fn test_no_style
|
|||
end
|
||||
|
||||
fn test_with_style
|
||||
count = print -s bold -s underline -s italic -s dimmed -s blink --style strikethrough --color bright_green --background-color red bright_green red
|
||||
count = println -s bold -s underline -s italic -s dimmed -s blink --style strikethrough --color bright_green --background-color red bright_green red
|
||||
assert_eq ${count} 2
|
||||
|
||||
colors = array black red green yellow blue magenta cyan white
|
||||
|
|
Loading…
Reference in a new issue