conductor/src/main.rs

75 lines
1.7 KiB
Rust

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<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;
}
}
}