forgejo-todo-checker/src/scanner.rs

63 lines
1.7 KiB
Rust
Raw Normal View History

2024-09-19 19:12:41 +01:00
//
use std::{collections::HashSet, path::Path};
2024-09-19 19:12:41 +01:00
use crate::{
issues::Issue,
model::{Config, Line, Marker, Markers},
};
2024-09-19 19:12:41 +01:00
use anyhow::Result;
2024-09-19 20:18:53 +01:00
use ignore::Walk;
2024-09-19 19:12:41 +01:00
pub fn find_markers(config: &Config, issues: HashSet<Issue>) -> Result<Markers, anyhow::Error> {
2024-09-20 14:28:23 +01:00
let mut markers = Markers::default();
2024-09-19 20:18:53 +01:00
for file in Walk::new(config.fs().base()).flatten() {
2024-09-19 19:12:41 +01:00
let path = file.path();
if config.fs().path_is_file(path)? {
2024-09-21 11:14:42 +01:00
// TODO: (#4) ignore non-text files
scan_file(path, config, &mut markers, &issues)?;
2024-09-19 19:12:41 +01:00
}
}
Ok(markers)
}
fn scan_file(
file: &Path,
config: &Config,
found_markers: &mut Markers,
issues: &HashSet<Issue>,
) -> Result<()> {
2024-09-19 19:12:41 +01:00
let relative_path = file.strip_prefix(config.fs().base())?.to_path_buf();
config
.fs()
.file_read_to_string(file)?
.lines()
.enumerate()
.map(|(n, line)| {
Line::builder()
.file(file.to_path_buf())
.relative_path(relative_path.clone())
.num(n + 1) // line numbers are not 0-based, but enumerate is
2024-09-19 19:12:41 +01:00
.value(line.to_owned())
.build()
})
.filter_map(|line| line.into_marker().ok())
.filter(|marker| !matches!(marker, Marker::Unmarked))
.map(|marker| has_open_issue(marker, issues))
2024-09-19 19:12:41 +01:00
.for_each(|marker| found_markers.add_marker(marker));
Ok(())
}
fn has_open_issue(marker: Marker, issues: &HashSet<Issue>) -> Marker {
if let Marker::Valid(_, ref issue) = marker {
let has_open_issue = issues.contains(issue);
if has_open_issue {
marker
} else {
marker.into_closed()
}
} else {
marker
}
}