-
Notifications
You must be signed in to change notification settings - Fork 88
/
count_loc.rs
69 lines (61 loc) · 2.41 KB
/
count_loc.rs
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
use std::path::PathBuf;
use anstream::println;
use glob::glob;
use regex::Regex;
use tokei::LanguageType;
use crate::{BOLD, GREEN, RED, RESET, Result};
pub fn count_loc() -> Result<()> {
let mut results = Vec::new();
let config = tokei::Config::default();
let mut longest_path = 0;
for entry in glob("./*.rs")?.chain(glob("./src/**/*.rs")?) {
let path = entry?;
let source = filter_lines(&path)?;
let stats = LanguageType::Rust.parse_from_str(source, &config);
longest_path = longest_path.max(path.display().to_string().len());
results.push((path, stats.code));
}
print_summary(&results, longest_path, &["unix", "wasi", "windows"])
}
/// Filter out lines that contain `clippy` lints and anything after
/// `#[cfg(test)]` attributes.
pub fn filter_lines(path: &std::path::PathBuf) -> Result<String> {
let regex = Regex::new(r"^\s*#!?\[(?:allow|warn|deny)\(clippy::")?;
let content = std::fs::read_to_string(path)?;
let lines = content
.lines()
.filter(|line| !regex.is_match(line))
.take_while(|line| !line.contains("#[cfg(test)]"));
let filtered_content = lines.collect::<Vec<_>>().join("\n");
Ok(filtered_content)
}
pub fn print_summary(results: &[(PathBuf, usize)], width: usize, platforms: &[&str]) -> Result<()> {
let platform_counts = platforms.iter().map(|platform| filter_count(results, platform));
let other_count = results.iter().map(|(_, count)| count).sum::<usize>()
- platform_counts.clone().sum::<usize>();
for (path, count) in results {
println!("{:width$} {:4}", path.display(), count, width = width);
}
let mut too_high = false;
for (platform, platform_count) in platforms.iter().zip(platform_counts) {
let header = format!("Total ({platform})");
let total = platform_count + other_count;
if total > 1024 {
too_high = true;
println!("{BOLD}{header:width$} {total:4}{RESET} {RED}(> 1024){RESET}");
} else {
println!("{BOLD}{header:width$} {total:4}{RESET} {GREEN}(≤ 1024){RESET}");
}
}
if too_high {
Err("Total count is too high")?;
}
Ok(())
}
pub fn filter_count(results: &[(std::path::PathBuf, usize)], pattern: &str) -> usize {
results
.iter()
.filter(|(path, _)| path.display().to_string().contains(pattern))
.map(|(_, count)| count)
.sum::<usize>()
}