code-buster 0.11.0

Repository-aware static analysis for AI-assisted development
Documentation
use std::collections::BTreeSet;

use crate::cli::PreviewOptions;
use crate::config::Config;
use crate::finding_controls;
use crate::rule_catalog;

pub struct ExecutionPlan<'a> {
    languages: BTreeSet<&'a str>,
    only_families: Option<&'static [&'static str]>,
    selected_rule_active: bool,
}

impl<'a> ExecutionPlan<'a> {
    pub fn new(
        options: &PreviewOptions,
        config: &Config,
        languages: impl Iterator<Item = &'a str>,
    ) -> Self {
        let only_families = if options.only.is_empty() {
            None
        } else {
            packs_for_rule(&options.only)
        };
        let selected_rule_active =
            options.only.is_empty() || rule_active(&options.only, config, &options.finding_group);
        Self {
            languages: languages.collect(),
            only_families,
            selected_rule_active,
        }
    }

    pub fn allows(&self, family: &str) -> bool {
        self.selected_rule_active
            && self
                .only_families
                .is_none_or(|families| families.contains(&family))
    }

    pub fn selects_language(&self, language: &str) -> bool {
        self.languages.contains(language)
    }
}

fn rule_active(code: &str, config: &Config, requested_group: &str) -> bool {
    if config.disabled_rules.contains(code) {
        return false;
    }
    let group = rule_catalog::descriptor(code).map_or("security", |descriptor| descriptor.group);
    (requested_group.is_empty() || requested_group == group)
        && finding_controls::mode_for_code(code, config, group) != "off"
}

fn packs_for_rule(code: &str) -> Option<&'static [&'static str]> {
    rule_catalog::metadata(code).map(|metadata| metadata.packs)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn uses_pack_routing_from_canonical_rule_metadata() {
        assert_eq!(
            packs_for_rule("oop-feature-envy"),
            Some(&["dart-oop", "oop", "csharp", "typescript"][..])
        );
        assert_eq!(
            packs_for_rule("dart-null-assertion"),
            Some(&["dart-null-assertion"][..])
        );
        assert_eq!(packs_for_rule("tab-indent"), Some(&["layout"][..]));
    }
}