repopilot 0.10.0

Local-first CLI for repository audit, architecture risk detection, baseline tracking, and CI-friendly code review.
Documentation
mod file_audits;
mod framework_audits;
mod project_audits;
mod registration;

pub use file_audits::{build_file_audits, registered_file_audits};
pub use framework_audits::{registered_framework_audits, run_framework_audits};
pub use project_audits::{registered_project_audits, run_project_audits};
pub use registration::{
    FileAuditRegistration, FrameworkAuditRegistration, ProjectAuditRegistration,
};

#[cfg(test)]
mod tests {
    use super::*;
    use crate::audits::metadata::AuditKind;
    use crate::frameworks::DetectedFramework;
    use crate::rules::lookup_rule_metadata;
    use crate::scan::config::ScanConfig;
    use crate::scan::facts::ScanFacts;
    use std::collections::HashSet;

    #[test]
    fn registered_file_audits_have_rule_metadata() {
        let config = ScanConfig {
            detect_secret_like_names: true,
            ..ScanConfig::default()
        };

        assert_registrations_have_rule_metadata(
            registered_file_audits(&config)
                .iter()
                .map(|registration| registration.metadata.clone()),
            AuditKind::File,
        );
    }

    #[test]
    fn registered_project_audits_have_rule_metadata() {
        let config = ScanConfig {
            detect_missing_tests: true,
            ..ScanConfig::default()
        };

        assert_registrations_have_rule_metadata(
            registered_project_audits(&config)
                .iter()
                .map(|registration| registration.metadata.clone()),
            AuditKind::Project,
        );
    }

    #[test]
    fn registered_framework_audits_have_rule_metadata() {
        let facts = ScanFacts {
            detected_frameworks: vec![
                DetectedFramework::ReactNative { version: None },
                DetectedFramework::React { version: None },
            ],
            ..ScanFacts::default()
        };

        assert_registrations_have_rule_metadata(
            registered_framework_audits(&facts)
                .iter()
                .map(|registration| registration.metadata.clone()),
            AuditKind::Framework,
        );
    }

    #[test]
    fn registered_audit_ids_are_unique_within_each_scope() {
        let config = ScanConfig {
            detect_missing_tests: true,
            detect_secret_like_names: true,
            ..ScanConfig::default()
        };
        let framework_facts = ScanFacts {
            detected_frameworks: vec![
                DetectedFramework::ReactNative { version: None },
                DetectedFramework::React { version: None },
            ],
            ..ScanFacts::default()
        };

        assert_unique_audit_ids(
            registered_file_audits(&config)
                .iter()
                .map(|registration| registration.metadata.clone()),
        );
        assert_unique_audit_ids(
            registered_project_audits(&config)
                .iter()
                .map(|registration| registration.metadata.clone()),
        );
        assert_unique_audit_ids(
            registered_framework_audits(&framework_facts)
                .iter()
                .map(|registration| registration.metadata.clone()),
        );
    }

    fn assert_registrations_have_rule_metadata(
        registrations: impl Iterator<Item = crate::audits::metadata::AuditMetadata>,
        expected_kind: AuditKind,
    ) {
        for metadata in registrations {
            assert_eq!(
                metadata.kind, expected_kind,
                "audit {} has unexpected kind",
                metadata.audit_id
            );
            assert!(
                !metadata.rule_ids.is_empty(),
                "audit {} should declare at least one rule_id",
                metadata.audit_id
            );

            for rule_id in metadata.rule_ids {
                let rule = lookup_rule_metadata(rule_id).unwrap_or_else(|| {
                    panic!(
                        "audit {} references missing rule metadata: {}",
                        metadata.audit_id, rule_id
                    )
                });
                assert_eq!(
                    rule.category, metadata.category,
                    "audit {} category does not match rule {}",
                    metadata.audit_id, rule_id
                );
            }
        }
    }

    fn assert_unique_audit_ids(
        registrations: impl Iterator<Item = crate::audits::metadata::AuditMetadata>,
    ) {
        let mut seen = HashSet::new();

        for metadata in registrations {
            assert!(
                seen.insert(metadata.audit_id),
                "duplicate audit_id: {}",
                metadata.audit_id
            );
        }
    }
}