Skip to content

Commit

Permalink
Merge pull request #22 from QIUZHILEI/dev
Browse files Browse the repository at this point in the history
Remove the function of executing js command
  • Loading branch information
genedna authored Jul 26, 2023
2 parents d69586f + c6e53b3 commit 914e931
Show file tree
Hide file tree
Showing 27 changed files with 218 additions and 365 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: check
- uses: actions/setup-node@v3
with:
node-version: 16

test:
name: Test Suite
Expand Down
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ keywords = ["DAG", "task", "async", "parallel", "concurrent"]
[dependencies]
yaml-rust = "0.4.5"
bimap = "0.6.1"
deno_core = "0.191.0"
clap = { version = "4.2.2", features = ["derive"] }
anymap2 = "0.13.0"
thiserror = "1.0.30"
Expand Down
41 changes: 11 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,7 @@ Task executed successfully. [name: Task d]
Process finished with exit code 0
```



### Yaml configuration file
### `Yaml` configuration file

A standard yaml configuration file format is given below:

Expand All @@ -147,50 +145,34 @@ dagrs:
a:
name: "Task 1"
after: [ b, c ]
run:
type: sh
script: echo a
cmd: echo a
b:
name: "Task 2"
after: [ c, f, g ]
run:
type: sh
script: echo b
cmd: echo b
c:
name: "Task 3"
after: [ e, g ]
run:
type: sh
script: echo c
cmd: echo c
d:
name: "Task 4"
after: [ c, e ]
run:
type: sh
script: echo d
cmd: echo d
e:
name: "Task 5"
after: [ h ]
run:
type: sh
script: echo e
cmd: echo e
f:
name: "Task 6"
after: [ g ]
run:
type: deno
script: Deno.core.print("f\n")
cmd: python3 ./tests/config/test.py
g:
name: "Task 7"
after: [ h ]
run:
type: deno
script: Deno.core.print("g\n")
cmd: node ./tests/config/test.js
h:
name: "Task 8"
run:
type: sh
script: echo h
cmd: echo h
```
These yaml-defined task items form a complex dependency graph. In the yaml configuration file:
Expand All @@ -199,7 +181,8 @@ These yaml-defined task items form a complex dependency graph. In the yaml confi
- Similar to `a`, `b`, `c`... is the unique identifier of the task
- `name` is a required attribute, which is the name of the task
- `after` is an optional attribute (only the first executed task does not have this attribute), which represents which tasks are executed after the task, that is, specifies dependencies for tasks
- `run` is a required attribute, followed by `type` and `script`, they are all required attributes, where `type` represents the type of task. The framework provides default implementations of the `Action` trait for two types of script tasks, namely sh and javascript. If users want to customize other types of script tasks, or implement their own script execution logic, they can implement the `Action` trait by programming. Although this is cumbersome, this method will be more flexible. In addition, when parsing the configuration file, the user also needs to provide the parser with a specific type that implements the `Action` trait, and the method should be in the form of a key-value pair: <id,action>
- `cmd` is a optional attribute. You need to point out the command to be executed, such as the basic shell command: `echo hello`, execute the python script `python test.py`, etc. The user must ensure that the interpreter that executes the script exists in the environment variable. `CommandAction` is the implementation of the specific execution logic of the script, which is put into a specific `Task` type.
If users want to customize other types of script tasks, or implement their own script execution logic, they can implement the "Action" feature through programming, and when parsing the configuration file, provide the parser with a specific type that implements the `Action` feature, and the method should be in the form of a key-value pair: <id,action>. Although this is more troublesome, this method will be more flexible.

To parse the yaml configured file, you need to compile this project, requiring rust version >= 1.70:

Expand Down Expand Up @@ -230,9 +213,7 @@ $./target/release/dagrs --yaml=./tests/config/correct.yaml --log-path=./dagrs.lo
Executing Task[name: Task 8]
Executing Task[name: Task 5]
Executing Task[name: Task 7]
g
Executing Task[name: Task 6]
f
Executing Task[name: Task 3]
Executing Task[name: Task 2]
Executing Task[name: Task 4]
Expand Down
42 changes: 16 additions & 26 deletions examples/custom_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
//! The content of the configuration file is as follows:
//!
//! ```
//! a,Task a,b c,sh,echo a
//! b,Task b,c f g,sh,echo b
//! c,Task c,e g,sh,echo c
//! d,Task d,c e,sh,echo d
//! e,Task e,h,sh,echo e
//! f,Task f,g,deno,Deno.core.print("f\n")
//! g,Task g,h,deno,Deno.core.print("g\n")
//! h,Task h,,sh,echo h
//! a,Task a,b c,echo a
//! b,Task b,c f g,echo b
//! c,Task c,e g,echo c
//! d,Task d,c e,echo d
//! e,Task e,h,echo e
//! f,Task f,g,python3 tests/config/test.py
//! g,Task g,h,node tests/config/test.js
//! h,Task h,,echo h
//! ```
extern crate dagrs;
Expand All @@ -18,7 +18,7 @@ use std::{fs, sync::Arc};
use std::collections::HashMap;
use std::fmt::{Display, Formatter};

use dagrs::{Action, Dag, log,LogLevel, JavaScript, Parser, ParserError, ShScript, Task};
use dagrs::{Action, Dag, log,LogLevel, Parser, ParserError, CommandAction, Task};

struct MyTask {
tid: (String, usize),
Expand Down Expand Up @@ -99,23 +99,13 @@ impl ConfigParser {

let id = *attr.get(0).unwrap();
let name = attr.get(1).unwrap().to_string();
let script = *attr.get(4).unwrap();
let t_type = *attr.get(3).unwrap();
if t_type.eq("sh") {
MyTask::new(
id,
pres,
name,
ShScript::new(script),
)
} else {
MyTask::new(
id,
pres,
name,
JavaScript::new(script),
)
}
let cmd = *attr.get(3).unwrap();
MyTask::new(
id,
pres,
name,
CommandAction::new(cmd),
)
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use dagrs::{
};
fn main() {
// initialization log.
log::init_logger(LogLevel::Error, None);
log::init_logger(LogLevel::Info, None);
// Create an Engine.
let mut engine = Engine::default();

Expand Down
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
extern crate anymap2;
extern crate bimap;
extern crate clap;
extern crate deno_core;
extern crate yaml_rust;

pub use engine::{Dag, DagError, Engine};
pub use parser::*;
pub use task::{Action, DefaultTask, alloc_id, Input, JavaScript, Output, RunningError, ShScript, Task, YamlTask};
pub use task::{Action, DefaultTask, alloc_id, Input, Output, RunningError, CommandAction, Task, YamlTask};
pub use utils::{EnvVar, gen_macro,LogLevel,Logger,log};

mod engine;
Expand Down
9 changes: 0 additions & 9 deletions src/parser/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,6 @@ pub enum YamlTaskError {
/// The specified task predecessor was not found.
#[error("Task cannot find the specified predecessor. [{0}]")]
NotFoundPrecursor(String),
/// `run` is not defined.
#[error("The 'run' attribute is not defined. [{0}]")]
NoRunAttr(String),
/// `type` is not defined.
#[error("The 'type' attribute is not defined. [{0}]")]
NoTypeAttr(String),
/// Unsupported script type.
#[error("Unsupported script type [{0}]")]
UnsupportedType(String),
/// `script` is not defined.
#[error("The 'script' attribute is not defined. [{0}]")]
NoScriptAttr(String),
Expand Down
80 changes: 32 additions & 48 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,56 +14,40 @@
//! # The basic format of the yaml configuration file is as follows:
//! ```yaml
//! dagrs:
//! a:
//! name: "Task 1"
//! after: [b, c]
//! run:
//! type: sh
//! script: echo a
//! b:
//! name: "Task 2"
//! after: [c, f, g]
//! run:
//! type: sh
//! script: echo b
//! c:
//! name: "Task 3"
//! after: [e, g]
//! run:
//! type: sh
//! script: echo c
//! d:
//! name: "Task 4"
//! after: [c, e]
//! run:
//! type: sh
//! script: echo d
//! e:
//! name: "Task 5"
//! after: [h]
//! run:
//! type: sh
//! script: echo e
//! f:
//! name: "Task 6"
//! after: [g]
//! run:
//! type: deno
//! script: Deno.core.print("f\n")
//! g:
//! name: "Task 7"
//! after: [h]
//! run:
//! type: deno
//! script: Deno.core.print("g\n")
//! h:
//! name: "Task 8"
//! run:
//! type: sh
//! script: echo h
//! a:
//! name: "Task 1"
//! after: [ b, c ]
//! cmd: echo a
//! b:
//! name: "Task 2"
//! after: [ c, f, g ]
//! cmd: echo b
//! c:
//! name: "Task 3"
//! after: [ e, g ]
//! cmd: echo c
//! d:
//! name: "Task 4"
//! after: [ c, e ]
//! cmd: echo d
//! e:
//! name: "Task 5"
//! after: [ h ]
//! cmd: echo e
//! f:
//! name: "Task 6"
//! after: [ g ]
//! cmd: python3 ./tests/config/test.py
//! g:
//! name: "Task 7"
//! after: [ h ]
//! cmd: node ./tests/config/test.js
//! h:
//! name: "Task 8"
//! cmd: echo h
//! ```
//!
//! Currently, the framework supports sh and javascript script task types by default. If users
//! Users can execute arbitrary commands of the operating system. If users
//! want to run other types of script tasks, they need to implement the [`Action`] trait by themselves,
//! and before parsing the configuration file, they need to provide a specific type that implements
//! the [`Action`] trait in the form of key-value pairs: <id, action>.
Expand Down
48 changes: 12 additions & 36 deletions src/parser/yaml_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{collections::HashMap, fs::File, io::Read, sync::Arc};
use yaml_rust::{Yaml, YamlLoader};

use crate::{
task::{JavaScript, ShScript, Task, YamlTask},
task::{CommandAction, Task, YamlTask},
Action,
};

Expand Down Expand Up @@ -54,43 +54,19 @@ impl YamlParser {
.map(|task_id| precursors.push(task_id.as_str().unwrap().to_owned()))
.count();
}
// Get run script
let run = &item["run"];
if run.is_badvalue() {
return Err(YamlTaskError::NoRunAttr(name));
}
let script_type = run["type"]
.as_str()
.ok_or(YamlTaskError::NoTypeAttr(name.clone()))?;


if let Some(action) = specific_action {
Ok(YamlTask::new(id, precursors, name, action))
} else {
match script_type {
"sh" => {
let sh_script = run["script"]
.as_str()
.ok_or(YamlTaskError::NoScriptAttr(name.clone()))?;
Ok(YamlTask::new(
id,
precursors,
name,
Arc::new(ShScript::new(sh_script)) as Arc<dyn Action+Send+Sync+'static>,
))
}
"deno" => {
let js_script = run["script"]
.as_str()
.ok_or(YamlTaskError::NoScriptAttr(name.clone()))?;
Ok(YamlTask::new(
id,
precursors,
name,
Arc::new(JavaScript::new(js_script)) as Arc<dyn Action+Send+Sync+'static>,
))
}
_ => Err(YamlTaskError::UnsupportedType(name)),
}
let cmd = item["cmd"]
.as_str()
.ok_or(YamlTaskError::NoScriptAttr(name.clone()))?;
Ok(YamlTask::new(
id,
precursors,
name,
Arc::new(CommandAction::new(cmd)) as Arc<dyn Action + Send + Sync + 'static>,
))
}
}
}
Expand All @@ -99,7 +75,7 @@ impl Parser for YamlParser {
fn parse_tasks(
&self,
file: &str,
mut specific_actions: HashMap<String,Arc<dyn Action+Send+Sync+'static>>,
mut specific_actions: HashMap<String, Arc<dyn Action + Send + Sync + 'static>>,
) -> Result<Vec<Box<dyn Task>>, ParserError> {
let content = self.load_file(file)?;
// Parse Yaml
Expand Down
Loading

0 comments on commit 914e931

Please sign in to comment.