#![deny(clippy::all, clippy::pedantic, unsafe_code)]
pub(crate) mod config;
pub(crate) mod convert;
pub(crate) mod env;
pub(crate) mod facts;
pub(crate) mod installer;
pub(crate) mod jobs;
pub(crate) mod preflight;
pub(crate) mod runner;
pub(crate) mod runnerstate;
pub(crate) mod status;
pub(crate) mod template;
use std::io;
use camino::Utf8PathBuf;
use clap::Parser;
use thiserror::Error as ThisError;
use crate::facts::Facts;
#[derive(Debug, Parser)]
#[command(version)]
struct Args {
#[arg(short, long)]
config: Option<Utf8PathBuf>,
}
#[derive(Debug, ThisError)]
enum Error {
#[error(transparent)]
Config {
#[from]
source: config::Error,
},
#[error(transparent)]
Facts {
#[from]
source: facts::Error,
},
#[error(transparent)]
Io {
#[from]
source: io::Error,
},
#[error(transparent)]
Job {
#[from]
source: jobs::Error,
},
#[error(transparent)]
Preflight {
#[from]
source: preflight::Error,
},
}
type Result<T> = std::result::Result<T, Error>;
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<()> {
let args = Args::parse();
let mut facts = Facts::gather()?;
let config_path = if let Some(c) = args.config {
eprintln!("finding: {}", &c);
if c.is_absolute() {
c
} else {
crate::env::current_dir().join(c).canonicalize_utf8()?
}
} else {
config::find_config_file(&facts)?
};
eprintln!("reading: {}", &config_path);
facts.main_file = config_path.clone();
let rm = config::read_main_toml(config_path)?;
rm.validate()?;
runner::run(rm.jobs, &facts).await;
Ok(())
}