summaryrefslogtreecommitdiffstats
path: root/crates/rebel/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/rebel/src/main.rs')
-rw-r--r--crates/rebel/src/main.rs87
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);
+ }
+ }
+}