req/src/bin/checker.rs

113 lines
3.1 KiB
Rust
Raw Normal View History

2024-05-08 14:48:40 +00:00
use std::path::PathBuf;
use clap::Parser;
use indexmap::{
map::{Keys, Values},
IndexMap,
};
use regex::Regex;
use req::*;
use stringlit::s;
#[derive(Parser)]
struct Args {
#[arg(short, long, default_value = "REQ-.*")]
allowed_requirements: String,
requirements: PathBuf,
test_results: PathBuf,
}
fn nl() -> String {
s!("")
}
fn check_requirements(
test_results: &str,
output: &mut Vec<String>,
requirements: &IndexMap<String, Requirement>,
allowed_requirements: &Regex,
) {
for (id, requirement) in requirements {
if allowed_requirements.is_match(&id) {
let status = if test_results.contains(&format!("{id} succeeded")) {
":white_check_mark:"
} else if test_results.contains(&format!("{id} failed")) {
":x:"
} else {
":warning:"
};
output.push(format!("- _{id}_ - {}: {status}", requirement.name));
}
}
}
fn has_valid_requirements(
mut requirements: Keys<String, Requirement>,
allowed_requirements: &Regex,
) -> bool {
requirements.any(|id| allowed_requirements.is_match(&id))
}
fn has_valid_topics(mut topics: Values<String, Topic>, allowed_requirements: &Regex) -> bool {
topics.any(|topic| {
has_valid_requirements(topic.requirements.keys(), allowed_requirements)
|| has_valid_topics(topic.subtopics.values(), allowed_requirements)
})
}
fn check_topics(
test_results: &str,
output: &mut Vec<String>,
topics: &IndexMap<String, Topic>,
allowed_requirements: &Regex,
level: usize,
) {
if !has_valid_topics(topics.values(), allowed_requirements) {
return;
}
for (id, topic) in topics {
if !has_valid_topics(topic.subtopics.values(), allowed_requirements)
&& !has_valid_requirements(topic.requirements.keys(), allowed_requirements)
{
continue;
}
output.push(format!("{} _{id}_ - {}", "#".repeat(level), topic.name));
if !topic.requirements.is_empty() {
check_requirements(
test_results,
output,
&topic.requirements,
allowed_requirements,
);
output.push(nl());
}
if !topic.subtopics.is_empty() {
check_topics(
test_results,
output,
&topic.subtopics,
allowed_requirements,
level + 1,
);
output.push(nl());
}
}
}
fn main() -> anyhow::Result<()> {
let Args {
allowed_requirements,
requirements,
test_results,
} = Args::parse();
let re = Regex::new(&allowed_requirements).unwrap();
let test_results = std::fs::read_to_string(test_results)?;
let project: Project = serde_yaml::from_str(&std::fs::read_to_string(requirements)?)?;
let mut output = vec![format!("# Test Results - {}", project.name)];
check_topics(&test_results, &mut output, &project.topics, &re, 2);
let output = output.join("\n");
println!("{output}");
Ok(())
}