This commit is contained in:
parent
eea2e14fb0
commit
708bcb0b91
2 changed files with 137 additions and 17 deletions
|
@ -7,3 +7,4 @@ edition = "2021"
|
|||
anyhow = "1.0"
|
||||
regex = "1.10"
|
||||
ureq = "2.10"
|
||||
kxio = "1.2"
|
||||
|
|
149
src/main.rs
149
src/main.rs
|
@ -1,24 +1,18 @@
|
|||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::Context;
|
||||
use anyhow::{Context, Result};
|
||||
use kxio::fs::DirItem;
|
||||
use regex::Regex;
|
||||
|
||||
struct Config {
|
||||
workdir: PathBuf,
|
||||
repo: String,
|
||||
server: String,
|
||||
auth_token: Option<String>,
|
||||
prefix_pattern: Regex,
|
||||
issue_pattern: Regex,
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
fn main() -> Result<()> {
|
||||
println!("Forgejo TODO Checker!");
|
||||
|
||||
let config = Config {
|
||||
workdir: std::env::var("GITHUB_WORKSPACE")
|
||||
fs: kxio::fs::new(
|
||||
std::env::var("GITHUB_WORKSPACE")
|
||||
.context("GITHUB_WORKSPACE")?
|
||||
.into(),
|
||||
),
|
||||
repo: std::env::var("GITHUB_REPOSITORY").context("GITHUB_REPOSITORY")?,
|
||||
server: std::env::var("GITHUB_SERVER_URL").context("GITHUB_SERVER_URL")?,
|
||||
auth_token: std::env::var("REPO_TOKEN").ok(),
|
||||
|
@ -33,8 +27,12 @@ fn main() -> anyhow::Result<()> {
|
|||
|
||||
// TODO: scan files in workdir
|
||||
// TODO: ignore files listed in .rgignore .ignore or .gitignore
|
||||
// TODO: scan for malformed TODO and FIXME comments (e.g. no issue number) - add to error list
|
||||
// TODO: build list of expected open issues with file locations where found
|
||||
|
||||
let mut found_markers = FoundMarkers::default();
|
||||
|
||||
scan_files(&config, &mut found_markers)?;
|
||||
|
||||
println!("{found_markers:?}");
|
||||
|
||||
// list files in current directory to get a feel for what we have access to
|
||||
// std::fs::read_dir(workdir)?
|
||||
|
@ -60,3 +58,124 @@ fn main() -> anyhow::Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct Config {
|
||||
fs: kxio::fs::FileSystem,
|
||||
repo: String,
|
||||
server: String,
|
||||
auth_token: Option<String>,
|
||||
prefix_pattern: Regex,
|
||||
issue_pattern: Regex,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct FoundMarkers {
|
||||
markers: Vec<Marker>,
|
||||
issue_markers: Vec<IssueMarker>,
|
||||
}
|
||||
impl FoundMarkers {
|
||||
fn add_marker(&mut self, marker: Marker) {
|
||||
self.markers.push(marker);
|
||||
}
|
||||
fn add_issue_marker(&mut self, issue_marker: IssueMarker) {
|
||||
self.issue_markers.push(issue_marker);
|
||||
}
|
||||
}
|
||||
|
||||
fn scan_files(config: &Config, found_markers: &mut FoundMarkers) -> Result<()> {
|
||||
scan_dir(config.fs.base(), config, found_markers)
|
||||
}
|
||||
|
||||
fn scan_dir(dir: &Path, config: &Config, found_markers: &mut FoundMarkers) -> Result<()> {
|
||||
let read_dir = config.fs.dir_read(dir)?;
|
||||
for entry in read_dir {
|
||||
match entry? {
|
||||
DirItem::File(file) => scan_file(&file, config, found_markers),
|
||||
DirItem::Dir(dir) => scan_dir(&dir, config, found_markers),
|
||||
DirItem::SymLink(_) | DirItem::Fifo(_) | DirItem::Unsupported(_) => Ok(()),
|
||||
}?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn scan_file(path: &Path, config: &Config, found_markers: &mut FoundMarkers) -> Result<()> {
|
||||
config
|
||||
.fs
|
||||
.file_read_to_string(path)?
|
||||
.lines()
|
||||
.enumerate()
|
||||
.filter_map(|(n, line)| prefix_match(n, line, path, config))
|
||||
.for_each(|marker| {
|
||||
if let Some(issue) = config
|
||||
.issue_pattern
|
||||
.find(&marker.line.value)
|
||||
.map(|issue| issue.as_str())
|
||||
.and_then(|issue| issue.parse::<usize>().ok())
|
||||
{
|
||||
found_markers.add_issue_marker(marker.into_issue_marker(issue));
|
||||
} else {
|
||||
found_markers.add_marker(marker);
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prefix_match(num: usize, line: &str, path: &Path, config: &Config) -> Option<Marker> {
|
||||
let find = config.prefix_pattern.find(line)?;
|
||||
let marker_type = match find.as_str() {
|
||||
"TODO" => Some(MarkerType::Todo),
|
||||
"FIXME" => Some(MarkerType::Fixme),
|
||||
_ => None,
|
||||
}?;
|
||||
Some(Marker {
|
||||
marker_type,
|
||||
file: path.to_path_buf(),
|
||||
line: Line {
|
||||
num,
|
||||
value: line.to_owned(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/// What type of comment
|
||||
#[derive(Debug)]
|
||||
enum MarkerType {
|
||||
Todo,
|
||||
Fixme,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Line {
|
||||
num: usize,
|
||||
value: String,
|
||||
}
|
||||
|
||||
/// Represents a TODO or FIXME comment that doesn't have any issue number
|
||||
#[derive(Debug)]
|
||||
struct Marker {
|
||||
/// What type of marker
|
||||
marker_type: MarkerType,
|
||||
|
||||
/// Path of the file
|
||||
file: PathBuf,
|
||||
|
||||
/// The line from the file
|
||||
line: Line,
|
||||
}
|
||||
impl Marker {
|
||||
fn into_issue_marker(self, issue: usize) -> IssueMarker {
|
||||
IssueMarker {
|
||||
marker: self,
|
||||
issue,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct IssueMarker {
|
||||
/// The marker
|
||||
marker: Marker,
|
||||
|
||||
/// The issue number
|
||||
issue: usize,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue