From 39399f93db73c0fcf71c0cd4d858afaed7360931 Mon Sep 17 00:00:00 2001 From: Joe Bellus Date: Sat, 13 Nov 2021 01:53:44 -0500 Subject: [PATCH] Sync --- Cargo.lock | 2 +- src/definition.rs | 171 +++++++++++++++++++++++++++++++--------------- src/job.rs | 6 ++ src/main.rs | 28 ++++++++ 4 files changed, 151 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 291450a..a668fc0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,7 +60,7 @@ dependencies = [ [[package]] name = "arkham" -version = "0.1.1" +version = "0.1.0" dependencies = [ "console", ] diff --git a/src/definition.rs b/src/definition.rs index 41f3840..a89286a 100644 --- a/src/definition.rs +++ b/src/definition.rs @@ -5,7 +5,7 @@ use std::collections::HashMap; #[derive(Serialize, Deserialize, Default)] #[serde(default)] pub struct Project { - pub components: Vec, + pub components: HashMap, pub groups: Vec, pub env: HashMap, pub tasks: Vec, @@ -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 { - 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 { - 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 { + 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> { + 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 { 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::>() + .into() + }) + }) } pub fn from_str(s: &str) -> Self { @@ -146,15 +171,13 @@ impl Project { #[serde(default)] pub struct Group { name: String, - components: Vec, - env: HashMap, + components: Vec, } #[derive(Serialize, Deserialize)] #[serde(default)] pub struct Component { pub env: HashMap, - pub name: String, pub command: String, pub path: Option, 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 - env: - foo: four + main-cmp: + env: + 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); + } } diff --git a/src/job.rs b/src/job.rs index 5b5545c..a17d36d 100644 --- a/src/job.rs +++ b/src/job.rs @@ -39,6 +39,12 @@ impl DerefMut for Jobs { } } +impl From> for Jobs { + fn from(fr: Vec) -> Self { + Jobs::new(fr) + } +} + #[derive(Clone, Debug, Message)] #[rtype(result = "()")] pub struct Job { diff --git a/src/main.rs b/src/main.rs index b6b2d94..f222c94 100644 --- a/src/main.rs +++ b/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 { + env::current_dir() + .map(|dir| find_file(&dir, config)) + .unwrap_or(None) +} + +fn find_file(starting_directory: &Path, filename: &str) -> Option { + 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; + } + } +}