#![doc = include_str!("../README.MD")]
#![warn(missing_docs)]
use clap::Parser;
use std::io::Read;
use std::path::Path;
use std::process::ExitCode;
use std::sync::Arc;
mod activity;
mod execute_story;
mod message;
mod modules;
pub mod prelude;
mod report_generators;
mod reporter;
mod story;
use crate::prelude::*;
#[derive(Parser)]
struct Args {
stories: String,
}
fn result_text(count: u64, text: &'static str) -> String {
if count == 0 {
String::new()
} else {
format!(" {} {} stories", count, text)
}
}
fn main_() -> anyhow::Result<bool> {
let runtime = Arc::new(
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?,
);
let args = Args::parse();
let mut file = std::fs::File::open(&args.stories)?;
let mut data = String::new();
let r = file.read_to_string(&mut data);
match r {
Ok(_) => {}
Err(e) => {
log::error!(
"Failed to read file '{}' with error: '{}'.",
args.stories,
e
);
return Ok(false);
}
}
let stories: Result<story::Stories, _> = serde_yml::from_str(&mut data);
let stories = match stories {
Ok(stories) => stories,
Err(m) => {
log::error!("Failed to parse '{}' with error: '{}'.", args.stories, m);
return Ok(false);
}
};
let report_generator = report_generators::GeneratorDispatcher::new(
&args.stories,
stories
.report_generators
.as_ref()
.map(|x| x.junit.as_ref())
.flatten(),
stories
.report_generators
.as_ref()
.map(|x| x.markdown.as_ref())
.flatten(),
);
let mut result = true;
let mut success = 0;
let mut failed = 0;
let mut skipped = 0;
for story in stories.stories.iter() {
if story.enabled {
let story_res = runtime.block_on(execute_story::execute_story(
story,
&stories,
Path::new(&args.stories)
.parent()
.ok_or(anyhow::Error::msg("Unreachable."))?,
runtime.clone(),
&report_generator,
))?;
result &= story_res;
if story_res {
success += 1;
} else {
failed += 1;
}
} else {
skipped += 1;
}
}
use colored::Colorize;
println!(
"Ran {} stories{}{}{}",
success + failed + skipped,
result_text(success, "successful").green(),
result_text(failed, "failed").red(),
result_text(skipped, "skipped").yellow()
);
Ok(result)
}
pub fn main() -> ExitCode {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.parse_default_env()
.init();
let r = main_();
match r {
Ok(v) => {
if v {
ExitCode::SUCCESS
} else {
ExitCode::FAILURE
}
}
Err(e) => {
log::error!("Error occurred while running stories: {:#?}", e);
ExitCode::FAILURE
}
}
}