This commit is contained in:
parent
ed0b1c4535
commit
21ff321402
10 changed files with 183 additions and 112 deletions
|
@ -9,3 +9,4 @@ regex = "1.10"
|
||||||
ureq = "2.10"
|
ureq = "2.10"
|
||||||
kxio = "1.2"
|
kxio = "1.2"
|
||||||
ignore = "0.4"
|
ignore = "0.4"
|
||||||
|
bon = "2.3"
|
||||||
|
|
148
src/main.rs
148
src/main.rs
|
@ -1,53 +1,44 @@
|
||||||
use std::path::{Path, PathBuf};
|
//
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use kxio::fs::DirItem;
|
use model::{Config, FoundMarkers, Line, Marker, MarkerKind};
|
||||||
use regex::Regex;
|
|
||||||
|
mod model;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
println!("Forgejo TODO Checker!");
|
println!("Forgejo TODO Checker!");
|
||||||
|
|
||||||
let config = Config {
|
let config = Config::builder()
|
||||||
fs: kxio::fs::new(
|
.fs(kxio::fs::new(
|
||||||
std::env::var("GITHUB_WORKSPACE")
|
std::env::var("GITHUB_WORKSPACE")
|
||||||
.context("GITHUB_WORKSPACE")?
|
.context("GITHUB_WORKSPACE")?
|
||||||
.into(),
|
.into(),
|
||||||
),
|
))
|
||||||
repo: std::env::var("GITHUB_REPOSITORY").context("GITHUB_REPOSITORY")?,
|
.repo(std::env::var("GITHUB_REPOSITORY").context("GITHUB_REPOSITORY")?)
|
||||||
server: std::env::var("GITHUB_SERVER_URL").context("GITHUB_SERVER_URL")?,
|
.server(std::env::var("GITHUB_SERVER_URL").context("GITHUB_SERVER_URL")?)
|
||||||
auth_token: std::env::var("REPO_TOKEN").ok(),
|
.prefix_pattern(regex::Regex::new(r"(#|//)\s*(TODO|FIXME)").context("prefix regex")?)
|
||||||
prefix_pattern: regex::Regex::new(r"(#|//)\s*(TODO|FIXME)").context("prefix regex")?,
|
.issue_pattern(
|
||||||
issue_pattern: regex::Regex::new(r"( |)(\(|\(#)(?P<ISSUE_NUMBER>\d+)(\))")
|
regex::Regex::new(r"( |)(\(|\(#)(?P<ISSUE_NUMBER>\d+)(\))").context("issue regex")?,
|
||||||
.context("issue regex")?,
|
)
|
||||||
};
|
.maybe_auth_token(std::env::var("REPO_TOKEN").ok())
|
||||||
|
.build();
|
||||||
|
|
||||||
println!("Repo: {}", config.repo);
|
println!("Repo: {}", config.repo());
|
||||||
println!("Prefix: {}", config.prefix_pattern);
|
println!("Prefix: {}", config.prefix_pattern());
|
||||||
println!("Issues: {}", config.issue_pattern);
|
println!("Issues: {}", config.issue_pattern());
|
||||||
|
|
||||||
let mut found_markers = FoundMarkers::default();
|
let mut found_markers = FoundMarkers::default();
|
||||||
|
|
||||||
for file in ignore::Walk::new(config.fs.base()).flatten() {
|
for file in ignore::Walk::new(config.fs().base()).flatten() {
|
||||||
let path = file.path();
|
let path = file.path();
|
||||||
if config.fs.path_is_file(path)? {
|
if config.fs().path_is_file(path)? {
|
||||||
scan_file(path, &config, &mut found_markers)?;
|
scan_file(path, &config, &mut found_markers)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{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)?
|
|
||||||
// .filter_map(Result::ok)
|
|
||||||
// .map(|e| e.path())
|
|
||||||
// .for_each(|e| println!("{e:?}"));
|
|
||||||
|
|
||||||
// Collect open issues:
|
|
||||||
// let limit = 10;
|
|
||||||
// let page = 0;
|
|
||||||
// let api = format!(
|
|
||||||
// "{ci_server_url}/api/v1/repos/{ci_repo}/issues?state=open&limit=${limit}&page=${page}"
|
|
||||||
// );
|
|
||||||
// TODO: add authentication when provided
|
// TODO: add authentication when provided
|
||||||
// let issues = ureq::get(&api).call()?.into_string()?;
|
// let issues = ureq::get(&api).call()?.into_string()?;
|
||||||
// TODO: parse issues to get list of open issue numbers
|
// TODO: parse issues to get list of open issue numbers
|
||||||
|
@ -61,42 +52,19 @@ fn main() -> Result<()> {
|
||||||
Ok(())
|
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_file(file: &Path, config: &Config, found_markers: &mut FoundMarkers) -> Result<()> {
|
fn scan_file(file: &Path, config: &Config, found_markers: &mut FoundMarkers) -> Result<()> {
|
||||||
println!("file: {}", file.to_string_lossy());
|
println!("file: {}", file.to_string_lossy());
|
||||||
config
|
config
|
||||||
.fs
|
.fs()
|
||||||
.file_read_to_string(file)?
|
.file_read_to_string(file)?
|
||||||
.lines()
|
.lines()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(n, line)| prefix_match(n, line, file, config))
|
.filter_map(|(n, line)| prefix_match(n, line, file, config))
|
||||||
.for_each(|marker| {
|
.for_each(|marker| {
|
||||||
println!("- {}", marker.line.value);
|
println!("- {}", marker.line().value());
|
||||||
if let Some(issue) = config
|
if let Some(issue) = config
|
||||||
.issue_pattern
|
.issue_pattern()
|
||||||
.find(&marker.line.value)
|
.find(marker.line().value())
|
||||||
.map(|issue| issue.as_str())
|
.map(|issue| issue.as_str())
|
||||||
.and_then(|issue| issue.parse::<usize>().ok())
|
.and_then(|issue| issue.parse::<usize>().ok())
|
||||||
{
|
{
|
||||||
|
@ -109,61 +77,17 @@ fn scan_file(file: &Path, config: &Config, found_markers: &mut FoundMarkers) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefix_match(num: usize, line: &str, path: &Path, config: &Config) -> Option<Marker> {
|
fn prefix_match(num: usize, line: &str, path: &Path, config: &Config) -> Option<Marker> {
|
||||||
let find = config.prefix_pattern.find(line)?;
|
let find = config.prefix_pattern().find(line)?;
|
||||||
let marker_type = match find.as_str() {
|
let kind = match find.as_str() {
|
||||||
"TODO" => Some(MarkerType::Todo),
|
"TODO" => Some(MarkerKind::Todo),
|
||||||
"FIXME" => Some(MarkerType::Fixme),
|
"FIXME" => Some(MarkerKind::Fixme),
|
||||||
_ => None,
|
_ => None,
|
||||||
}?;
|
}?;
|
||||||
Some(Marker {
|
Some(
|
||||||
marker_type,
|
Marker::builder()
|
||||||
file: path.to_path_buf(),
|
.kind(kind)
|
||||||
line: Line {
|
.file(path.to_path_buf())
|
||||||
num,
|
.line(Line::builder().num(num).value(line.to_owned()).build())
|
||||||
value: line.to_owned(),
|
.build(),
|
||||||
},
|
)
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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,
|
|
||||||
}
|
}
|
||||||
|
|
35
src/model/config.rs
Normal file
35
src/model/config.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
//
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use bon::Builder;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
#[derive(Builder)]
|
||||||
|
pub struct Config {
|
||||||
|
fs: kxio::fs::FileSystem,
|
||||||
|
repo: String,
|
||||||
|
server: String,
|
||||||
|
auth_token: Option<String>,
|
||||||
|
prefix_pattern: Regex,
|
||||||
|
issue_pattern: Regex,
|
||||||
|
}
|
||||||
|
impl Config {
|
||||||
|
pub fn fs(&self) -> &kxio::fs::FileSystem {
|
||||||
|
&self.fs
|
||||||
|
}
|
||||||
|
pub fn repo(&self) -> &str {
|
||||||
|
&self.repo
|
||||||
|
}
|
||||||
|
pub fn server(&self) -> &str {
|
||||||
|
&self.server
|
||||||
|
}
|
||||||
|
pub fn auth_token(&self) -> Option<&str> {
|
||||||
|
self.auth_token.as_deref()
|
||||||
|
}
|
||||||
|
pub fn prefix_pattern(&self) -> &Regex {
|
||||||
|
&self.prefix_pattern
|
||||||
|
}
|
||||||
|
pub fn issue_pattern(&self) -> &Regex {
|
||||||
|
&self.issue_pattern
|
||||||
|
}
|
||||||
|
}
|
18
src/model/line.rs
Normal file
18
src/model/line.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
//
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use bon::Builder;
|
||||||
|
|
||||||
|
#[derive(Debug, Builder)]
|
||||||
|
pub struct Line {
|
||||||
|
num: usize,
|
||||||
|
value: String,
|
||||||
|
}
|
||||||
|
impl Line {
|
||||||
|
pub fn num(&self) -> usize {
|
||||||
|
self.num
|
||||||
|
}
|
||||||
|
pub fn value(&self) -> &str {
|
||||||
|
&self.value
|
||||||
|
}
|
||||||
|
}
|
16
src/model/markers/found.rs
Normal file
16
src/model/markers/found.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
use super::{IssueMarker, Marker};
|
||||||
|
|
||||||
|
//
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct FoundMarkers {
|
||||||
|
markers: Vec<Marker>,
|
||||||
|
issue_markers: Vec<IssueMarker>,
|
||||||
|
}
|
||||||
|
impl FoundMarkers {
|
||||||
|
pub fn add_marker(&mut self, marker: Marker) {
|
||||||
|
self.markers.push(marker);
|
||||||
|
}
|
||||||
|
pub fn add_issue_marker(&mut self, issue_marker: IssueMarker) {
|
||||||
|
self.issue_markers.push(issue_marker);
|
||||||
|
}
|
||||||
|
}
|
15
src/model/markers/issue.rs
Normal file
15
src/model/markers/issue.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use super::Marker;
|
||||||
|
|
||||||
|
use bon::Builder;
|
||||||
|
|
||||||
|
#[derive(Debug, Builder)]
|
||||||
|
pub struct IssueMarker {
|
||||||
|
/// The marker
|
||||||
|
marker: Marker,
|
||||||
|
|
||||||
|
/// The issue number
|
||||||
|
issue: usize,
|
||||||
|
}
|
7
src/model/markers/kind.rs
Normal file
7
src/model/markers/kind.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//
|
||||||
|
/// What type of comment #[derive(Debug)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum MarkerKind {
|
||||||
|
Todo,
|
||||||
|
Fixme,
|
||||||
|
}
|
37
src/model/markers/marker.rs
Normal file
37
src/model/markers/marker.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
//
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use bon::Builder;
|
||||||
|
|
||||||
|
use crate::model::Line;
|
||||||
|
|
||||||
|
use super::{IssueMarker, MarkerKind};
|
||||||
|
|
||||||
|
/// Represents a TODO or FIXME comment that doesn't have any issue number
|
||||||
|
#[derive(Debug, Builder)]
|
||||||
|
pub struct Marker {
|
||||||
|
/// What type of marker
|
||||||
|
kind: MarkerKind,
|
||||||
|
|
||||||
|
/// Path of the file
|
||||||
|
file: PathBuf,
|
||||||
|
|
||||||
|
/// The line from the file
|
||||||
|
line: Line,
|
||||||
|
}
|
||||||
|
impl Marker {
|
||||||
|
pub fn kind(&self) -> &MarkerKind {
|
||||||
|
&self.kind
|
||||||
|
}
|
||||||
|
pub fn file(&self) -> &Path {
|
||||||
|
&self.file
|
||||||
|
}
|
||||||
|
pub fn line(&self) -> &Line {
|
||||||
|
&self.line
|
||||||
|
}
|
||||||
|
pub fn into_issue_marker(self, issue: usize) -> IssueMarker {
|
||||||
|
IssueMarker::builder().marker(self).issue(issue).build()
|
||||||
|
}
|
||||||
|
}
|
10
src/model/markers/mod.rs
Normal file
10
src/model/markers/mod.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
//
|
||||||
|
mod found;
|
||||||
|
mod issue;
|
||||||
|
mod kind;
|
||||||
|
mod marker;
|
||||||
|
|
||||||
|
pub use found::FoundMarkers;
|
||||||
|
pub use issue::IssueMarker;
|
||||||
|
pub use kind::MarkerKind;
|
||||||
|
pub use marker::Marker;
|
8
src/model/mod.rs
Normal file
8
src/model/mod.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
//
|
||||||
|
mod config;
|
||||||
|
mod line;
|
||||||
|
mod markers;
|
||||||
|
|
||||||
|
pub use config::Config;
|
||||||
|
pub use line::Line;
|
||||||
|
pub use markers::*;
|
Loading…
Reference in a new issue