Sync
This commit is contained in:
parent
b624dc3b34
commit
39399f93db
|
@ -60,7 +60,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "arkham"
|
||||
version = "0.1.1"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"console",
|
||||
]
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::collections::HashMap;
|
|||
#[derive(Serialize, Deserialize, Default)]
|
||||
#[serde(default)]
|
||||
pub struct Project {
|
||||
pub components: Vec<Component>,
|
||||
pub components: HashMap<String, Component>,
|
||||
pub groups: Vec<Group>,
|
||||
pub env: HashMap<String, String>,
|
||||
pub tasks: Vec<TaskDefinition>,
|
||||
|
@ -30,13 +30,13 @@ impl Project {
|
|||
Jobs::new(jobs)
|
||||
})
|
||||
.or_else(|| {
|
||||
self.components.iter().find_map(|component| {
|
||||
self.components.iter().find_map(|(c_name, component)| {
|
||||
component
|
||||
.tasks
|
||||
.iter()
|
||||
.find(|t| format!("{}:{}", component.name, t.name) == name)
|
||||
.find(|t| format!("{}:{}", c_name, t.name) == name)
|
||||
.map(|task| {
|
||||
let job = self.build_component_task_job(component, task);
|
||||
let job = self.build_component_task_job(c_name, component, task);
|
||||
let mut jobs = task
|
||||
.before
|
||||
.iter()
|
||||
|
@ -53,13 +53,13 @@ impl Project {
|
|||
}
|
||||
|
||||
fn get_relative_task(&self, task_name: &str, component_name: &str) -> Option<Jobs> {
|
||||
if let Some(component) = self.components.iter().find(|c| c.name == component_name) {
|
||||
if let Some(component) = self.components.get(component_name) {
|
||||
component
|
||||
.tasks
|
||||
.iter()
|
||||
.find(|t| t.name == task_name)
|
||||
.map(|task| {
|
||||
let job = self.build_component_task_job(component, task);
|
||||
let job = self.build_component_task_job(component_name, component, task);
|
||||
let mut jobs = task
|
||||
.before
|
||||
.iter()
|
||||
|
@ -76,9 +76,9 @@ impl Project {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_component(&self, name: &str) -> Option<Jobs> {
|
||||
self.components.iter().find(|c| c.name == name).map(|c| {
|
||||
let component_job = self.build_component_job(c);
|
||||
fn get_component(&self, component_name: &str) -> Option<Jobs> {
|
||||
self.components.get(component_name).map(|c| {
|
||||
let component_job = self.build_component_job(component_name, c);
|
||||
let mut absolute_tasks = c
|
||||
.before
|
||||
.iter()
|
||||
|
@ -90,7 +90,7 @@ impl Project {
|
|||
let mut relative_tasks = c
|
||||
.before
|
||||
.iter()
|
||||
.map(|name| self.get_relative_task(name, &c.name))
|
||||
.map(|task_name| self.get_relative_task(task_name, &component_name))
|
||||
.flatten()
|
||||
.map(|jobs| jobs.to_vec())
|
||||
.flatten()
|
||||
|
@ -102,11 +102,22 @@ impl Project {
|
|||
})
|
||||
}
|
||||
|
||||
fn build_component_job(&self, c: &Component) -> Job {
|
||||
fn get_group(&self, name: &str) -> Option<Vec<Jobs>> {
|
||||
self.groups.iter().find(|g| g.name == name).map(|group| {
|
||||
group
|
||||
.components
|
||||
.iter()
|
||||
.map(|name| self.get_by_name(&name))
|
||||
.flatten()
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
fn build_component_job(&self, name: &str, c: &Component) -> Job {
|
||||
let mut env = self.env.clone();
|
||||
env.extend(c.env.clone());
|
||||
Job {
|
||||
name: c.name.clone(),
|
||||
name: name.to_string(),
|
||||
env,
|
||||
..Job::default()
|
||||
}
|
||||
|
@ -121,12 +132,17 @@ impl Project {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_component_task_job(&self, component: &Component, task: &TaskDefinition) -> Job {
|
||||
fn build_component_task_job(
|
||||
&self,
|
||||
cmp_name: &str,
|
||||
component: &Component,
|
||||
task: &TaskDefinition,
|
||||
) -> Job {
|
||||
let mut env = self.env.clone();
|
||||
env.extend(component.env.clone());
|
||||
env.extend(task.env.clone());
|
||||
Job {
|
||||
name: format!("{}:{}", component.name.clone(), task.name.clone()),
|
||||
name: format!("{}:{}", cmp_name.to_string(), task.name.clone()),
|
||||
env,
|
||||
..Job::default()
|
||||
}
|
||||
|
@ -135,6 +151,15 @@ impl Project {
|
|||
pub fn get_by_name(&self, name: &str) -> Option<Jobs> {
|
||||
self.get_component(name)
|
||||
.or_else(|| self.get_absolute_task(name))
|
||||
.or_else(|| {
|
||||
self.get_group(name).map(|v| {
|
||||
v.iter()
|
||||
.map(|jobs| jobs.to_vec())
|
||||
.flatten()
|
||||
.collect::<Vec<_>>()
|
||||
.into()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_str(s: &str) -> Self {
|
||||
|
@ -146,15 +171,13 @@ impl Project {
|
|||
#[serde(default)]
|
||||
pub struct Group {
|
||||
name: String,
|
||||
components: Vec<Component>,
|
||||
env: HashMap<String, String>,
|
||||
components: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct Component {
|
||||
pub env: HashMap<String, String>,
|
||||
pub name: String,
|
||||
pub command: String,
|
||||
pub path: Option<String>,
|
||||
pub retry: bool,
|
||||
|
@ -168,7 +191,6 @@ impl Default for Component {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
env: HashMap::new(),
|
||||
name: "UNNAMED".to_string(),
|
||||
command: String::new(),
|
||||
path: None,
|
||||
retry: false,
|
||||
|
@ -202,7 +224,7 @@ mod tests {
|
|||
let project = Project::from_str(
|
||||
r#"
|
||||
components:
|
||||
- name: test-component
|
||||
test-component: {}
|
||||
"#,
|
||||
);
|
||||
|
||||
|
@ -228,9 +250,9 @@ mod tests {
|
|||
let project = Project::from_str(
|
||||
r#"
|
||||
components:
|
||||
- name: c1
|
||||
tasks:
|
||||
- name: task1
|
||||
c1:
|
||||
tasks:
|
||||
- name: task1
|
||||
"#,
|
||||
);
|
||||
|
||||
|
@ -243,11 +265,11 @@ mod tests {
|
|||
let project = Project::from_str(
|
||||
r#"
|
||||
components:
|
||||
- name: main-cmp
|
||||
before:
|
||||
- main-cmp:sub-task
|
||||
tasks:
|
||||
- name: sub-task
|
||||
main-cmp:
|
||||
before:
|
||||
- main-cmp:sub-task
|
||||
tasks:
|
||||
- name: sub-task
|
||||
"#,
|
||||
);
|
||||
|
||||
|
@ -257,15 +279,15 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn component_dependent_relative_component_task() {
|
||||
fn component_dependent_relative() {
|
||||
let project = Project::from_str(
|
||||
r#"
|
||||
components:
|
||||
- name: main-cmp
|
||||
before:
|
||||
- sub-task
|
||||
tasks:
|
||||
- name: sub-task
|
||||
main-cmp:
|
||||
before:
|
||||
- sub-task
|
||||
tasks:
|
||||
- name: sub-task
|
||||
"#,
|
||||
);
|
||||
|
||||
|
@ -279,19 +301,19 @@ mod tests {
|
|||
let project = Project::from_str(
|
||||
r#"
|
||||
components:
|
||||
- name: ui
|
||||
before:
|
||||
- build-ui
|
||||
tasks:
|
||||
- name: build-ui
|
||||
- name: server
|
||||
before:
|
||||
- setup
|
||||
tasks:
|
||||
- name: setup
|
||||
- name: build
|
||||
ui:
|
||||
before:
|
||||
- server:setup
|
||||
- build-ui
|
||||
tasks:
|
||||
- name: build-ui
|
||||
server:
|
||||
before:
|
||||
- setup
|
||||
tasks:
|
||||
- name: setup
|
||||
- name: build
|
||||
before:
|
||||
- server:setup
|
||||
tasks:
|
||||
- name: build
|
||||
before:
|
||||
|
@ -316,9 +338,9 @@ mod tests {
|
|||
foo: one
|
||||
sub: two
|
||||
components:
|
||||
- name: main-cmp
|
||||
env:
|
||||
sub: three
|
||||
main-cmp:
|
||||
env:
|
||||
sub: three
|
||||
"#,
|
||||
);
|
||||
|
||||
|
@ -337,13 +359,13 @@ mod tests {
|
|||
foo: one
|
||||
sub: two
|
||||
components:
|
||||
- name: main-cmp
|
||||
env:
|
||||
sub: three
|
||||
tasks:
|
||||
- name: t
|
||||
main-cmp:
|
||||
env:
|
||||
foo: four
|
||||
sub: three
|
||||
tasks:
|
||||
- name: t
|
||||
env:
|
||||
foo: four
|
||||
"#,
|
||||
);
|
||||
|
||||
|
@ -353,4 +375,43 @@ mod tests {
|
|||
assert_eq!(job.env.get("sub"), Some(&String::from("three")));
|
||||
assert_eq!(job.env.get("root"), Some(&String::from("ten")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group() {
|
||||
let project = Project::from_str(
|
||||
r#"
|
||||
groups:
|
||||
- name: all
|
||||
components:
|
||||
- ui
|
||||
- server
|
||||
components:
|
||||
ui:
|
||||
before:
|
||||
- build-ui
|
||||
tasks:
|
||||
- name: build-ui
|
||||
server:
|
||||
before:
|
||||
- setup
|
||||
tasks:
|
||||
- name: setup
|
||||
- name: build
|
||||
before:
|
||||
- server:setup
|
||||
tasks:
|
||||
- name: build
|
||||
before:
|
||||
- ui:build-ui
|
||||
- server:build
|
||||
"#,
|
||||
);
|
||||
let jobs = project.get_by_name("all").unwrap();
|
||||
println!("{:?}", jobs);
|
||||
assert_eq!(jobs.get(0).unwrap().name, "ui:build-ui");
|
||||
assert_eq!(jobs.get(1).unwrap().name, "ui");
|
||||
assert_eq!(jobs.get(2).unwrap().name, "server:setup");
|
||||
assert_eq!(jobs.get(3).unwrap().name, "server");
|
||||
assert_eq!(jobs.len(), 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,12 @@ impl DerefMut for Jobs {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Job>> for Jobs {
|
||||
fn from(fr: Vec<Job>) -> Self {
|
||||
Jobs::new(fr)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Message)]
|
||||
#[rtype(result = "()")]
|
||||
pub struct Job {
|
||||
|
|
28
src/main.rs
28
src/main.rs
|
@ -1,6 +1,9 @@
|
|||
use crate::definition::Project;
|
||||
use actix::prelude::*;
|
||||
use arkham::{App, Command};
|
||||
use runner::Manager;
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
mod definition;
|
||||
mod job;
|
||||
|
@ -23,7 +26,32 @@ async fn main() {
|
|||
let manager = Manager::new().start();
|
||||
manager.do_send(jobs);
|
||||
|
||||
find_config("conductor.yml");
|
||||
|
||||
actix_rt::signal::ctrl_c()
|
||||
.await
|
||||
.expect("failed to listen for event");
|
||||
}
|
||||
|
||||
fn find_config(config: &str) -> Option<PathBuf> {
|
||||
env::current_dir()
|
||||
.map(|dir| find_file(&dir, config))
|
||||
.unwrap_or(None)
|
||||
}
|
||||
|
||||
fn find_file(starting_directory: &Path, filename: &str) -> Option<PathBuf> {
|
||||
let mut path: PathBuf = starting_directory.into();
|
||||
let file = Path::new(&filename);
|
||||
|
||||
loop {
|
||||
path.push(file);
|
||||
|
||||
if path.is_file() {
|
||||
break Some(path);
|
||||
}
|
||||
|
||||
if !(path.pop() && path.pop()) {
|
||||
break None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue