Skip to content

Commit 2bdce12

Browse files
committed
Implement rule match reporter (fixes #4)
1 parent 50d3646 commit 2bdce12

File tree

4 files changed

+98
-10
lines changed

4 files changed

+98
-10
lines changed

src/applier.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,44 @@
1+
use crate::location::*;
2+
use crate::reporter::Reporter;
13
use crate::ruleset::{Rule, Ruleset};
24
use glob;
35
use std::fs;
46
use std::path::Path;
57
use walkdir::WalkDir;
68

7-
fn apply_rule_to_path(rule: &Rule, path: &Path) {
8-
let text = fs::read_to_string(path).unwrap();
9+
fn apply_rule_to_path(loc: &FileMatchLocation, rule: &Rule, reporter: &mut Reporter) {
10+
let text = fs::read_to_string(loc.file).unwrap();
911

1012
for (nline, line) in text.lines().enumerate() {
1113
if rule.regex.is_match(line) {
12-
println!("{}:{}: {}", path.display(), nline + 1, rule.title);
14+
reporter.report(
15+
&MatchLocation::Line(LineMatchLocation::from_file(loc, nline + 1)),
16+
&rule.title,
17+
);
1318
}
1419
}
1520
}
1621

17-
fn apply_rule_to_target(rule: &Rule, target: &Path) {
22+
fn apply_rule_to_target(loc: &RootMatchLocation, rule: &Rule, reporter: &mut Reporter) {
1823
let mut match_options = glob::MatchOptions::new();
1924
match_options.require_literal_separator = true;
2025

21-
for path in WalkDir::new(target)
26+
for path in WalkDir::new(loc.root)
2227
.into_iter()
2328
.filter_map(|e| e.ok())
2429
.filter(|e| e.file_type().is_file())
2530
.map(|e| e.into_path())
2631
{
27-
let path = path.strip_prefix(&target).unwrap();
32+
let path = path.strip_prefix(&loc.root).unwrap();
2833
if rule.glob.matches_path_with(path, match_options) {
29-
apply_rule_to_path(rule, path);
34+
apply_rule_to_path(&FileMatchLocation::from_root(loc, path), rule, reporter);
3035
}
3136
}
3237
}
3338

34-
pub fn apply_ruleset_to_target(ruleset: &Ruleset, target: &Path) {
39+
pub fn apply_ruleset_to_target(ruleset: &Ruleset, target: &Path, reporter: &mut Reporter) {
40+
let loc = &RootMatchLocation { root: target };
3541
for rule in &ruleset.rules {
36-
apply_rule_to_target(&rule, target);
42+
apply_rule_to_target(&loc, &rule, reporter);
3743
}
3844
}

src/location.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use std::path::Path;
2+
3+
pub struct RootMatchLocation<'a> {
4+
pub root: &'a Path,
5+
}
6+
7+
pub struct FileMatchLocation<'a> {
8+
pub root: &'a Path,
9+
pub file: &'a Path,
10+
}
11+
12+
impl<'a> FileMatchLocation<'a> {
13+
pub fn from_root(root: &RootMatchLocation<'a>, file: &'a Path) -> FileMatchLocation<'a> {
14+
FileMatchLocation {
15+
root: root.root,
16+
file,
17+
}
18+
}
19+
}
20+
21+
pub struct LineMatchLocation<'a> {
22+
pub root: &'a Path,
23+
pub file: &'a Path,
24+
pub line: usize,
25+
}
26+
27+
impl<'a> LineMatchLocation<'a> {
28+
pub fn from_file(file: &FileMatchLocation<'a>, line: usize) -> LineMatchLocation<'a> {
29+
LineMatchLocation {
30+
root: file.root,
31+
file: file.file,
32+
line,
33+
}
34+
}
35+
}
36+
37+
pub enum MatchLocation<'a> {
38+
Root(RootMatchLocation<'a>),
39+
File(FileMatchLocation<'a>),
40+
Line(LineMatchLocation<'a>),
41+
}

src/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
mod applier;
2+
mod location;
23
mod parser;
4+
mod reporter;
35
mod ruleset;
46

57
use crate::applier::apply_ruleset_to_target;
68
use crate::parser::parse_config_from_file;
9+
use crate::reporter::Reporter;
710
use clap::Parser;
811
use std::path::PathBuf;
912

@@ -24,7 +27,9 @@ fn main() {
2427

2528
let config = parse_config_from_file(&args.config);
2629

30+
let mut reporter = Reporter::new();
31+
2732
for target in args.targets {
28-
apply_ruleset_to_target(&config, &target);
33+
apply_ruleset_to_target(&config, &target, &mut reporter);
2934
}
3035
}

src/reporter.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use crate::location::MatchLocation;
2+
use std::path::PathBuf;
3+
4+
pub struct Reporter {
5+
prev_root: PathBuf,
6+
}
7+
8+
impl Reporter {
9+
pub fn new() -> Reporter {
10+
Reporter {
11+
prev_root: Default::default(),
12+
}
13+
}
14+
15+
pub fn report(&mut self, location: &MatchLocation, message: &str) {
16+
let current_root = match location {
17+
MatchLocation::Root(loc) => loc.root,
18+
MatchLocation::File(loc) => loc.root,
19+
MatchLocation::Line(loc) => loc.root,
20+
};
21+
22+
if current_root != self.prev_root {
23+
println!("in {}", current_root.display());
24+
self.prev_root = current_root.to_path_buf();
25+
}
26+
27+
match location {
28+
MatchLocation::Root(loc) => println!("- {}", message),
29+
MatchLocation::File(loc) => println!("- {}: {}", loc.file.display(), message),
30+
31+
MatchLocation::Line(loc) => {
32+
println!("- {}:{}: {}", loc.file.display(), loc.line, message)
33+
}
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)