diff options
Diffstat (limited to 'crates/rebel/src/main.rs')
-rw-r--r-- | crates/rebel/src/main.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/crates/rebel/src/main.rs b/crates/rebel/src/main.rs new file mode 100644 index 0000000..625b43d --- /dev/null +++ b/crates/rebel/src/main.rs @@ -0,0 +1,87 @@ +mod driver; +mod recipe; +mod template; + +use std::{collections::HashSet, fs::File, path::Path}; + +use clap::Parser; + +use rebel_common::error::*; +use rebel_parse as parse; +use rebel_resolve::{self as resolve, context, pin}; +use rebel_runner::{self as runner, Runner}; + +#[derive(Parser)] +#[clap(version, about)] +struct Opts { + /// Allow N jobs at once. + /// Defaults to the number of available CPUs + #[clap(short, long)] + jobs: Option<usize>, + /// Keep going after some tasks have failed + #[clap(short, long)] + keep_going: bool, + /// The tasks to run + #[clap(name = "task", required = true)] + tasks: Vec<String>, +} + +fn read_pins<P: AsRef<Path>>(path: P) -> Result<pin::Pins> { + let f = File::open(path)?; + let pins: pin::Pins = serde_yaml::from_reader(f) + .map_err(Error::new) + .context("YAML error")?; + Ok(pins) +} + +fn main() { + let opts: Opts = Opts::parse(); + + let runner = unsafe { Runner::new(&runner::Options { jobs: opts.jobs }) }.unwrap(); + + let ctx = context::Context::new( + recipe::read_recipes("examples/recipes").unwrap(), + read_pins("examples/pins.yml").unwrap(), + ) + .unwrap(); + + let mut rsv = resolve::Resolver::new(&ctx); + let mut force_run = HashSet::new(); + + for task in opts.tasks { + let Ok((parsed, flags)) = parse::task_ref::task_ref_with_flags(&task) else { + eprintln!("Invalid task syntax"); + std::process::exit(1); + }; + let task_ref = match ctx.lookup(parsed.id, parsed.args.host, parsed.args.target) { + Ok(task_ref) => task_ref, + Err(err) => { + eprintln!("{}", err); + std::process::exit(1); + } + }; + let errors = rsv.add_goal(&task_ref); + if !errors.is_empty() { + for error in errors { + eprintln!("{}", error); + } + std::process::exit(1); + } + if flags.force_run { + force_run.insert(task_ref); + } + } + let taskset = rsv.into_taskset(); + let mut driver = driver::Driver::new(&ctx, taskset, force_run).unwrap(); + match driver.run(&runner, opts.keep_going) { + Ok(success) => { + if !success { + std::process::exit(1); + } + } + Err(error) => { + eprintln!("{}", error); + std::process::exit(1); + } + } +} |