use crate::definition::Project; use runner::Manager; use std::env; use std::path::{Path, PathBuf}; mod definition; mod job; mod runner; mod term; #[actix_rt::main] async fn main() { if let Err(e) = run().await { term::main_error(e); } } pub async fn run() -> anyhow::Result<()> { let cfg_path = find_config("conductor.yml") .ok_or_else(|| anyhow::anyhow!("No config file found. Create a conductor.yml.\nSee http://conductor.5sigma.io/articles/config"))?; std::env::set_current_dir(cfg_path.parent().unwrap())?; let config_str = std::fs::read_to_string(cfg_path)?; let project = Project::load_str(&config_str)?; let args = std::env::args(); if args.len() == 1 { term::help_text(&project); return Ok(()); } let plan = args.into_iter().skip(1).fold(vec![], |mut plan, arg| { if let Some(mut j) = project.get_runplan(&arg) { plan.append(&mut j) } plan }); if plan.is_empty() { return Err(anyhow::anyhow!("No tasks to run")); } plan.into_iter().for_each(Manager::jobs); actix_rt::signal::ctrl_c() .await .expect("failed to listen for event"); Ok(()) } 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; } } }