rumk 0.0.1

A fast linter for Makefiles
Documentation
use crate::diagnostic::Diagnostic;
use crate::parser::Makefile;
use anyhow::{bail, Result};

pub mod best_practices;
pub mod style;
pub mod syntax;

pub trait Rule: Send + Sync {
    fn id(&self) -> &'static str;
    fn name(&self) -> &'static str;
    fn description(&self) -> &'static str;
    fn category(&self) -> RuleCategory;
    fn check(&self, makefile: &Makefile, content: &str) -> Vec<Diagnostic>;
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RuleCategory {
    Syntax,
    Style,
    BestPractices,
}

pub fn get_rule_explanation(rule_id: &str) -> Result<String> {
    let all_rules = get_all_rules();

    for rule in all_rules {
        if rule.id() == rule_id {
            return Ok(format!(
                "Rule: {}\nCategory: {:?}\nDescription: {}\n\n{}",
                rule.id(),
                rule.category(),
                rule.name(),
                rule.description()
            ));
        }
    }

    bail!("Unknown rule: {}", rule_id)
}

pub fn get_all_rules() -> Vec<Box<dyn Rule>> {
    vec![
        Box::new(syntax::TabInRecipe),
        Box::new(syntax::InvalidVariableSyntax),
        Box::new(style::LineLength::new(120)),
        Box::new(style::VariableNaming::new(style::NamingStyle::Upper)),
        Box::new(style::TargetNaming::new(style::NamingStyle::Lower)),
        Box::new(best_practices::MissingPhony),
        Box::new(best_practices::HardcodedPath),
    ]
}

pub fn get_default_rules() -> Vec<Box<dyn Rule>> {
    vec![
        Box::new(syntax::TabInRecipe),
        Box::new(syntax::InvalidVariableSyntax),
        Box::new(style::LineLength::new(120)),
        Box::new(best_practices::MissingPhony),
    ]
}