Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 41 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,17 +294,54 @@ mod tests {
}

#[test]
fn test_task_script() {
fn test_task_script_random_arg() {
let input = r#"
main () {
task(stub, random_string());
}
"#;

let nodes: Vec<Node> = parse_instructions(input).unwrap();
assert_eq!(nodes.len(), 1);
let prepared_nodes = apply_rules(nodes);

new_script_worker(prepared_nodes[0].clone())
.run_payload()
.unwrap();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

#[test]
fn test_task_script_no_arg() {
let input = r#"
main () {
task(stub);
}
"#;

let ast: Vec<Node> = parse_instructions(input).unwrap();
assert_eq!(ast.len(), 1);
let nodes: Vec<Node> = parse_instructions(input).unwrap();
assert_eq!(nodes.len(), 1);
let prepared_nodes = apply_rules(nodes);

new_script_worker(ast[0].clone()).run_payload().unwrap();
new_script_worker(prepared_nodes[0].clone())
.run_payload()
.unwrap();
}

#[test]
fn test_task_script_fixed_arg() {
let input = r#"
main () {
task(stub, "arg1 arg2");
}
"#;

let nodes: Vec<Node> = parse_instructions(input).unwrap();
assert_eq!(nodes.len(), 1);
let prepared_nodes = apply_rules(nodes);

new_script_worker(prepared_nodes[0].clone())
.run_payload()
.unwrap();
}

#[test]
Expand Down
10 changes: 10 additions & 0 deletions src/script/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ use std::collections::HashMap;

#[derive(Debug, Clone, PartialEq)]
pub enum Arg {
/// Null constant
Null,

/// Simple constant
Const { text: String },

Expand All @@ -14,9 +17,16 @@ pub enum Arg {

#[derive(Debug, Clone, PartialEq)]
pub enum Instruction {
/// Execute a binary with specified name and arguments
Task { name: Arg, args: Vec<Arg> },

/// Open a file at specified path
Open { path: Arg },

/// Print a debugging message (subject to configured log level)
Debug { text: Arg },

/// Send a message to a server at specified address
Ping { server: Arg },
}

Expand Down
2 changes: 1 addition & 1 deletion src/script/grammar.peg
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ arg = {
}

args = {"(" ~ (arg ~ ("," ~ arg)* ~ ","?)? ~ ")"}
value = {(ASCII_ALPHANUMERIC| "." | " " | "/" | ":")*}
value = {(ASCII_ALPHANUMERIC | "." | " " | "/" | ":" | "_")*}

param = {ident ~ "=" ~ value}
params = {"(" ~ (param ~ ("," ~ param)* ~ ","?)? ~ ")"}
Expand Down
36 changes: 31 additions & 5 deletions src/script/rules.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,39 @@
use log::debug;

use crate::script::ast::{Instruction, Node};
use crate::script::ast::{Arg, Instruction, Node};
use std::collections::HashMap;

fn apply_instruction_rules(
/// Apply following transformations to task instruction:
/// * If no arguments provided for the task, add an empty argument
fn apply_task_rules(task: &Instruction, _node: &Node) -> Instruction {
let Instruction::Task { name, args } = task else {
unreachable!()
};

let new_args = if args.is_empty() {
vec![Arg::Null {}]
} else {
args.to_vec()
};

Instruction::Task {
name: name.clone(),
args: new_args,
}
}

fn apply_instructions_rules(
instructions: &[Instruction],
_node: &Node,
node: &Node,
) -> Vec<Instruction> {
instructions.to_vec()
instructions
.iter()
.map(|i| match i {
Instruction::Task { .. } => apply_task_rules(i, node),
_ => i.clone(),
})
.collect::<Vec<_>>()
.to_vec()
}

fn apply_arg_rules(
Expand Down Expand Up @@ -43,7 +69,7 @@ fn apply_work_rules(work: Node) -> Node {
Node::Work {
name: name.clone(),
args: apply_arg_rules(args, &work),
instructions: apply_instruction_rules(instructions, &work),
instructions: apply_instructions_rules(instructions, &work),
dist: dist.clone(),
}
}
Expand Down
Loading
Loading