multilint 0.1.2

A driver of multiple linters
Documentation
use crate::{config, linter::Linter};
use anyhow::Result;
use colored::*;
use std::{
    io::{stdout, Write},
    path::Path,
};

pub fn run_linters(config_path: impl AsRef<Path>) -> Result<bool> {
    let config = config::from_path(&config_path)?;
    let global = config.global.unwrap_or_default();
    let root = config_path.as_ref().parent().unwrap();
    let mut ok = true;
    for (name, linter_config) in &config.linter {
        print!("{} {} ... ", "Running".bold().green(), &name);
        let linter = Linter::from_config(linter_config.clone(), &global);
        if !linter.is_executable() {
            println!("{}", "no command".yellow());
            continue;
        }
        match linter.run(&root)? {
            Some(output) => {
                if output.status.success() {
                    println!("{}", "ok".green());
                } else {
                    println!("{}", "failed".red());
                }
                if !output.stdout.is_empty() {
                    stdout().write_all(&output.stdout)?;
                }
                if !output.stderr.is_empty() {
                    stdout().write_all(&output.stderr)?;
                }
                ok &= output.status.success();
            }
            None => println!("{}", "skipped".yellow()),
        }
    }
    Ok(ok)
}

#[cfg(test)]
mod tests {
    use super::run_linters;
    use std::{fs::File, io::Write};
    use tempfile::tempdir;
    use test_log::test;

    #[test]
    fn run() {
        let root = tempdir().unwrap();
        let config = root.path().join("config.toml");

        {
            let mut config = File::create(&config).unwrap();
            writeln!(config, "[linter.test]").unwrap();
            writeln!(config, "command = 'true'").unwrap();
            writeln!(config, "includes = ['*']").unwrap();
        }
        assert!(run_linters(&config).unwrap());

        {
            let mut config = File::create(&config).unwrap();
            writeln!(config, "[linter.test]").unwrap();
            writeln!(config, "command = 'false'").unwrap();
            writeln!(config, "includes = ['*']").unwrap();
        }
        assert!(!run_linters(&config).unwrap());
    }
}