Skip to content

Commit

Permalink
feat(lib): Expose run_checks_with and print_returning_exit_code f…
Browse files Browse the repository at this point in the history
…unctions

`run_checks_with`: Run checks on a given list of items
`print_returning_exit_code`: Print the result of each check run via
`run_checks_with` and return whether the checks succeed.
  • Loading branch information
shivaraj-bh committed Jul 10, 2024
1 parent 9741f8c commit 82f5cce
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 71 deletions.
81 changes: 80 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ pub mod check;
pub mod report;
pub mod traits;

use colored::Colorize;
use std::vec::IntoIter;

use check::direnv::Direnv;
use nix_rs::command::NixCmd;
use nix_rs::flake::url::FlakeUrl;
Expand Down Expand Up @@ -70,13 +73,47 @@ impl NixHealth {
&self,
nix_info: &nix_rs::info::NixInfo,
flake_url: Option<FlakeUrl>,
) -> Vec<traits::Check> {
NixHealth::run_checks_with(self.into_iter(), nix_info, flake_url)
}

pub fn run_checks_with(
items: IntoIter<&dyn traits::Checkable>,
nix_info: &nix_rs::info::NixInfo,
flake_url: Option<FlakeUrl>,
) -> Vec<traits::Check> {
tracing::info!("🩺 Running health checks");
self.into_iter()
items
.flat_map(|c| c.check(nix_info, flake_url.clone()))
.collect()
}

pub fn print_report_returning_exit_code(checks: &[traits::Check], quiet: bool) -> i32 {
let mut res = AllChecksResult::new();
for check in checks {
match &check.result {
traits::CheckResult::Green => {
if !quiet {
println!("{}", format!("✅ {}", check.title).green().bold());
println!(" {}", check.info.blue());
}
}
traits::CheckResult::Red { msg, suggestion } => {
res.register_failure(check.required);
if check.required {
println!("{}", format!("❌ {}", check.title).red().bold());
} else {
println!("{}", format!("🟧 {}", check.title).yellow().bold());
}
println!(" {}", check.info.blue());
println!(" {}", msg.yellow());
println!(" {}", suggestion);
}
}
}
res.report()
}

pub fn schema() -> Result<String, serde_json::Error> {
serde_json::to_string_pretty(&NixHealth::default())
}
Expand Down Expand Up @@ -114,3 +151,45 @@ mod tests {
assert_eq!(v.nix_version, MinNixVersion::default());
}
}

/// A convenient type to aggregate check failures, and summary report at end.
enum AllChecksResult {
Pass,
PassSomeFail,
Fail,
}

impl AllChecksResult {
fn new() -> Self {
AllChecksResult::Pass
}

fn register_failure(&mut self, required: bool) {
if required {
*self = AllChecksResult::Fail;
} else if matches!(self, AllChecksResult::Pass) {
*self = AllChecksResult::PassSomeFail;
}
}

fn report(self) -> i32 {
match self {
AllChecksResult::Pass => {
println!("{}", "✅ All checks passed".green().bold());
0
}
AllChecksResult::PassSomeFail => {
println!(
"{}, {}",
"✅ Required checks passed".green().bold(),
"but some non-required checks failed".yellow().bold()
);
0
}
AllChecksResult::Fail => {
println!("{}", "❌ Some required checks failed".red().bold());
1
}
}
}
}
75 changes: 5 additions & 70 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
use anyhow::Context;
use clap::{command, Parser};
use colored::Colorize;
use nix_health::{
traits::{Check, CheckResult},
NixHealth,
};
use nix_health::{traits::Check, NixHealth};
use nix_rs::{command::NixCmd, env::NixEnv, flake::url::FlakeUrl, info::NixInfo};

#[derive(Parser)]
Expand Down Expand Up @@ -36,29 +32,10 @@ async fn main() -> anyhow::Result<()> {
.flake_url
.map(|url| url.with_fully_qualified_root_attr("nix-health"));
let checks = run_checks(flake_url).await?;
let mut res = AllChecksResult::new();
for check in &checks {
match &check.result {
CheckResult::Green => {
if !args.quiet {
println!("{}", format!("✅ {}", check.title).green().bold());
println!(" {}", check.info.blue());
}
}
CheckResult::Red { msg, suggestion } => {
res.register_failure(check.required);
if check.required {
println!("{}", format!("❌ {}", check.title).red().bold());
} else {
println!("{}", format!("🟧 {}", check.title).yellow().bold());
}
println!(" {}", check.info.blue());
println!(" {}", msg.yellow());
println!(" {}", suggestion);
}
}
}
std::process::exit(res.report())

let exit_code = NixHealth::print_report_returning_exit_code(&checks, args.quiet);

std::process::exit(exit_code)
}

/// Run health checks, taking current directory flake into account if there is
Expand Down Expand Up @@ -87,45 +64,3 @@ async fn run_checks(flake_url: Option<FlakeUrl>) -> anyhow::Result<Vec<Check>> {
let checks = health.run_checks(&nix_info, flake_url.clone());
Ok(checks)
}

/// A convenient type to aggregate check failures, and summary report at end.
enum AllChecksResult {
Pass,
PassSomeFail,
Fail,
}

impl AllChecksResult {
fn new() -> Self {
AllChecksResult::Pass
}

fn register_failure(&mut self, required: bool) {
if required {
*self = AllChecksResult::Fail;
} else if matches!(self, AllChecksResult::Pass) {
*self = AllChecksResult::PassSomeFail;
}
}

fn report(self) -> i32 {
match self {
AllChecksResult::Pass => {
println!("{}", "✅ All checks passed".green().bold());
0
}
AllChecksResult::PassSomeFail => {
println!(
"{}, {}",
"✅ Required checks passed".green().bold(),
"but some non-required checks failed".yellow().bold()
);
0
}
AllChecksResult::Fail => {
println!("{}", "❌ Some required checks failed".red().bold());
1
}
}
}
}

0 comments on commit 82f5cce

Please sign in to comment.