//! A Radicle CI adapter for native CI.
//!
//! Perform the CI run locally, without any isolation. This is not
//! safe and secure, but it's simple, and easy to get working. Do not
//! use this unless you trust the repository.
//!
//! The repository must contain a file `.radicle/native.yaml` that
//! specifies how CI is run for the repository. For example:
//!
//! ```yaml
//! shell: |
//! cargo test --locked --workspace
//! ```
#![allow(clippy::result_large_err)]
use std::{env::args, error::Error, process::exit};
use radicle_native_ci::engine::{Engine, EngineError};
// Exit codes for the program.
const EXIT_OK: i32 = 0;
const EXIT_FAILURE: i32 = 1;
const EXIT_ERROR: i32 = 2;
/// The main program.
fn main() {
let code = match fallible_main() {
Ok(success) => {
if success {
EXIT_OK
} else {
EXIT_FAILURE
}
}
Err(e) => {
eprintln!("ERROR: {e}");
let mut e = e.source();
while let Some(source) = e {
eprintln!("caused by: {source}");
e = source.source();
}
EXIT_ERROR
}
};
exit(code);
}
fn fallible_main() -> Result<bool, EngineError> {
let args: Vec<String> = args().skip(1).collect();
if args.is_empty() {
let mut engine = Engine::new()?;
engine.run()
} else {
for arg in args.iter() {
match arg.as_str() {
"--version" => println!("{} {}", env!("CARGO_PKG_NAME"), env!("VERSION")),
"--show-config" => {
let engine = Engine::new()?;
println!("{}", engine.config().as_json());
}
_ => {
eprintln!("unknown argument {arg}");
return Ok(false);
}
}
}
Ok(true)
}
}