1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//! # Rules Module
//!
//! This module provides the audit rules engine and finding management for RepoLens.
//!
//! ## Architecture
//!
//! The rules system is organized as follows:
//!
//! - [`engine`] - The main rules evaluation engine that orchestrates rule execution
//! - [`categories`] - Individual rule category implementations (secrets, files, docs, etc.)
//! - [`results`] - Finding and severity types for audit results
//! - [`patterns`] - Secret detection patterns and matching utilities
//! - [`constants`] - Rule category constants and filtering
//!
//! ## Rule Categories
//!
//! Each category implements the [`engine::RuleCategory`] trait:
//!
//! | Category | Description |
//! |----------|-------------|
//! | `secrets` | Detect exposed secrets and credentials |
//! | `files` | Check for required files (README, LICENSE, etc.) |
//! | `docs` | Documentation quality checks |
//! | `security` | Security best practices |
//! | `workflows` | CI/CD and GitHub Actions checks |
//! | `quality` | Code quality standards |
//! | `dependencies` | Dependency security and licensing |
//! | `docker` | Docker configuration checks |
//! | `git` | Git configuration and history checks |
//! | `custom` | User-defined custom rules |
//!
//! ## Examples
//!
//! ### Running the Rules Engine
//!
//! ```rust,no_run
//! use repolens::{config::Config, rules::engine::RulesEngine, scanner::Scanner};
//! use std::path::PathBuf;
//!
//! # async fn example() -> Result<(), repolens::RepoLensError> {
//! let config = Config::default();
//! let scanner = Scanner::new(PathBuf::from("."));
//! let engine = RulesEngine::new(config);
//!
//! let results = engine.run(&scanner).await?;
//!
//! for finding in results.findings() {
//! println!("[{:?}] {}: {}", finding.severity, finding.rule_id, finding.message);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ### Filtering Categories
//!
//! ```rust,no_run
//! use repolens::{config::Config, rules::engine::RulesEngine, scanner::Scanner};
//! use std::path::PathBuf;
//!
//! # async fn example() -> Result<(), repolens::RepoLensError> {
//! let config = Config::default();
//! let scanner = Scanner::new(PathBuf::from("."));
//! let mut engine = RulesEngine::new(config);
//!
//! // Only run secrets detection
//! engine.set_only_categories(vec!["secrets".to_string()]);
//!
//! let results = engine.run(&scanner).await?;
//! # Ok(())
//! # }
//! ```
//!
//! ### Working with Findings
//!
//! ```rust
//! use repolens::rules::{Finding, Severity};
//!
//! let finding = Finding::new("SEC001", "secrets", Severity::Critical, "API key detected")
//! .with_location("src/config.rs:42")
//! .with_description("A hardcoded API key was found in the source code")
//! .with_remediation("Move the API key to environment variables");
//!
//! assert_eq!(finding.severity, Severity::Critical);
//! ```
pub use filter_valid_categories;
pub use ;