Compare commits
5 commits
056211ba05
...
76a047b9ca
Author | SHA1 | Date | |
---|---|---|---|
76a047b9ca | |||
5357bbe4c5 | |||
64ddc6a6e6 | |||
92811bc074 | |||
61351ba07a |
18 changed files with 346 additions and 73 deletions
|
@ -10,3 +10,6 @@ ureq = "2.10"
|
||||||
kxio = "1.2"
|
kxio = "1.2"
|
||||||
ignore = "0.4"
|
ignore = "0.4"
|
||||||
bon = "2.3"
|
bon = "2.3"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
assert2 = "0.3"
|
||||||
|
|
25
src/init.rs
Normal file
25
src/init.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
//
|
||||||
|
use crate::model::Config;
|
||||||
|
use crate::patterns::{issue_pattern, marker_pattern};
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
|
pub fn init_config() -> Result<Config, anyhow::Error> {
|
||||||
|
let config = Config::builder()
|
||||||
|
.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")?)
|
||||||
|
.prefix_pattern(marker_pattern()?)
|
||||||
|
.issue_pattern(issue_pattern()?)
|
||||||
|
.maybe_auth_token(std::env::var("REPO_TOKEN").ok())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
println!("Repo: {}", config.repo());
|
||||||
|
println!("Prefix: {}", config.prefix_pattern());
|
||||||
|
println!("Issues: {}", config.issue_pattern());
|
||||||
|
|
||||||
|
Ok(config)
|
||||||
|
}
|
64
src/main.rs
64
src/main.rs
|
@ -1,43 +1,23 @@
|
||||||
//
|
//
|
||||||
use std::path::Path;
|
use anyhow::Result;
|
||||||
|
use init::init_config;
|
||||||
use anyhow::{Context, Result};
|
use scanner::find_markers;
|
||||||
use model::{Config, FoundMarkers, Line, Marker};
|
|
||||||
use patterns::{issue_pattern, marker_pattern};
|
|
||||||
|
|
||||||
|
mod init;
|
||||||
mod model;
|
mod model;
|
||||||
mod patterns;
|
mod patterns;
|
||||||
|
mod scanner;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
println!("Forgejo TODO Checker!");
|
println!("Forgejo TODO Checker!");
|
||||||
|
|
||||||
let config = Config::builder()
|
let config = init_config()?;
|
||||||
.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")?)
|
|
||||||
.prefix_pattern(marker_pattern()?)
|
|
||||||
.issue_pattern(issue_pattern()?)
|
|
||||||
.maybe_auth_token(std::env::var("REPO_TOKEN").ok())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
println!("Repo: {}", config.repo());
|
let markers = find_markers(config)?;
|
||||||
println!("Prefix: {}", config.prefix_pattern());
|
println!("{markers}");
|
||||||
println!("Issues: {}", config.issue_pattern());
|
|
||||||
|
|
||||||
let mut found_markers = FoundMarkers::default();
|
|
||||||
|
|
||||||
for file in ignore::Walk::new(config.fs().base()).flatten() {
|
|
||||||
let path = file.path();
|
|
||||||
if config.fs().path_is_file(path)? {
|
|
||||||
scan_file(path, &config, &mut found_markers)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("{found_markers}");
|
|
||||||
|
|
||||||
// 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()?;
|
||||||
|
@ -51,25 +31,3 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_file(file: &Path, config: &Config, found_markers: &mut FoundMarkers) -> Result<()> {
|
|
||||||
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)
|
|
||||||
.value(line.to_owned())
|
|
||||||
.build()
|
|
||||||
})
|
|
||||||
.filter_map(|line| line.into_marker().ok())
|
|
||||||
.filter(|marker| !matches!(marker, Marker::Unmarked))
|
|
||||||
.for_each(|marker| found_markers.add_marker(marker));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use bon::Builder;
|
use bon::Builder;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
#[derive(Builder)]
|
#[derive(Debug, Builder)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
fs: kxio::fs::FileSystem,
|
fs: kxio::fs::FileSystem,
|
||||||
repo: String,
|
repo: String,
|
||||||
|
@ -20,12 +20,12 @@ impl Config {
|
||||||
pub fn repo(&self) -> &str {
|
pub fn repo(&self) -> &str {
|
||||||
&self.repo
|
&self.repo
|
||||||
}
|
}
|
||||||
pub fn server(&self) -> &str {
|
// pub fn server(&self) -> &str {
|
||||||
&self.server
|
// &self.server
|
||||||
}
|
// }
|
||||||
pub fn auth_token(&self) -> Option<&str> {
|
// pub fn auth_token(&self) -> Option<&str> {
|
||||||
self.auth_token.as_deref()
|
// self.auth_token.as_deref()
|
||||||
}
|
// }
|
||||||
pub fn prefix_pattern(&self) -> &Regex {
|
pub fn prefix_pattern(&self) -> &Regex {
|
||||||
&self.prefix_pattern
|
&self.prefix_pattern
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use bon::Builder;
|
use bon::Builder;
|
||||||
|
@ -18,15 +18,15 @@ pub struct Line {
|
||||||
value: String,
|
value: String,
|
||||||
}
|
}
|
||||||
impl Line {
|
impl Line {
|
||||||
pub fn file(&self) -> &Path {
|
// pub fn file(&self) -> &Path {
|
||||||
&self.file
|
// &self.file
|
||||||
}
|
// }
|
||||||
pub fn num(&self) -> usize {
|
// pub fn num(&self) -> usize {
|
||||||
self.num
|
// self.num
|
||||||
}
|
// }
|
||||||
pub fn value(&self) -> &str {
|
// pub fn value(&self) -> &str {
|
||||||
&self.value
|
// &self.value
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn into_marker(self) -> Result<Marker> {
|
pub fn into_marker(self) -> Result<Marker> {
|
||||||
if marker_pattern()?.find(&self.value).is_some() {
|
if marker_pattern()?.find(&self.value).is_some() {
|
||||||
|
|
|
@ -13,7 +13,9 @@ impl FoundMarkers {
|
||||||
impl std::fmt::Display for FoundMarkers {
|
impl std::fmt::Display for FoundMarkers {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
for marker in self.markers.iter() {
|
for marker in self.markers.iter() {
|
||||||
write!(f, "- {marker}")?;
|
// if !matches!(marker, Marker::Unmarked) {
|
||||||
|
write!(f, "{marker}")?;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,8 @@ impl std::fmt::Display for Marker {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Marker::Unmarked => Ok(()),
|
Marker::Unmarked => Ok(()),
|
||||||
Marker::Invalid(line) => write!(f, "Invalid: {line}"),
|
Marker::Invalid(line) => write!(f, "- Invalid: {line}"),
|
||||||
Marker::Valid(line, _) => write!(f, "Valid : {line}"),
|
Marker::Valid(line, _) => write!(f, "- Valid : {line}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,5 +3,8 @@ mod found;
|
||||||
mod issue;
|
mod issue;
|
||||||
mod marker;
|
mod marker;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
pub use found::FoundMarkers;
|
pub use found::FoundMarkers;
|
||||||
pub use marker::Marker;
|
pub use marker::Marker;
|
||||||
|
|
57
src/model/markers/tests/found.rs
Normal file
57
src/model/markers/tests/found.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use crate::model::Line;
|
||||||
|
|
||||||
|
//
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn found_when_displayed() -> anyhow::Result<()> {
|
||||||
|
//given
|
||||||
|
let fs = kxio::fs::temp()?;
|
||||||
|
let file = fs.base().join("file-name");
|
||||||
|
let relative = file.strip_prefix(fs.base())?.to_path_buf();
|
||||||
|
|
||||||
|
let mut found = FoundMarkers::default();
|
||||||
|
|
||||||
|
let marker_unmarked = Line::builder()
|
||||||
|
.file(file.clone())
|
||||||
|
.relative_path(relative.clone())
|
||||||
|
.num(10)
|
||||||
|
.value("line with no comment".to_owned())
|
||||||
|
.build()
|
||||||
|
.into_marker()?;
|
||||||
|
let marker_invalid = Line::builder()
|
||||||
|
.file(file.clone())
|
||||||
|
.relative_path(relative.clone())
|
||||||
|
.num(10)
|
||||||
|
.value("line // TODO: comment".to_owned())
|
||||||
|
.build()
|
||||||
|
.into_marker()?;
|
||||||
|
let marker_valid = Line::builder()
|
||||||
|
.file(file)
|
||||||
|
.relative_path(relative)
|
||||||
|
.num(11)
|
||||||
|
.value("line // TODO: (#13) do this".to_owned())
|
||||||
|
.build()
|
||||||
|
.into_marker()?;
|
||||||
|
|
||||||
|
found.add_marker(marker_unmarked);
|
||||||
|
found.add_marker(marker_invalid);
|
||||||
|
found.add_marker(marker_valid);
|
||||||
|
|
||||||
|
//when
|
||||||
|
let markers_as_string = found.to_string();
|
||||||
|
let result = markers_as_string.lines().collect::<Vec<&str>>();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assert_eq!(
|
||||||
|
result,
|
||||||
|
vec![
|
||||||
|
"- Invalid: file-name#10:",
|
||||||
|
" line // TODO: comment",
|
||||||
|
"- Valid : file-name#11:",
|
||||||
|
" line // TODO: (#13) do this"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
0
src/model/markers/tests/issue.rs
Normal file
0
src/model/markers/tests/issue.rs
Normal file
0
src/model/markers/tests/marker.rs
Normal file
0
src/model/markers/tests/marker.rs
Normal file
6
src/model/markers/tests/mod.rs
Normal file
6
src/model/markers/tests/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
//
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
mod found;
|
||||||
|
mod issue;
|
||||||
|
mod marker;
|
|
@ -3,6 +3,9 @@ mod config;
|
||||||
mod line;
|
mod line;
|
||||||
mod markers;
|
mod markers;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
pub use config::Config;
|
pub use config::Config;
|
||||||
pub use line::Line;
|
pub use line::Line;
|
||||||
pub use markers::FoundMarkers;
|
pub use markers::FoundMarkers;
|
||||||
|
|
76
src/model/tests/config.rs
Normal file
76
src/model/tests/config.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use crate::patterns::{issue_pattern, marker_pattern};
|
||||||
|
|
||||||
|
//
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn with_config_get_fs() -> Result<()> {
|
||||||
|
//given
|
||||||
|
let fs = kxio::fs::temp()?;
|
||||||
|
let config = a_config(fs.clone())?;
|
||||||
|
|
||||||
|
//when
|
||||||
|
let result = config.fs();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assert_eq!(result.base(), fs.base());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn with_config_get_prefix_pattern() -> Result<()> {
|
||||||
|
//given
|
||||||
|
let fs = kxio::fs::temp()?;
|
||||||
|
let config = a_config(fs)?;
|
||||||
|
|
||||||
|
//when
|
||||||
|
let result = config.prefix_pattern();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assert_eq!(result.to_string(), marker_pattern()?.to_string());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn with_config_get_issue_pattern() -> Result<()> {
|
||||||
|
//given
|
||||||
|
let fs = kxio::fs::temp()?;
|
||||||
|
let config = a_config(fs)?;
|
||||||
|
|
||||||
|
//when
|
||||||
|
let result = config.issue_pattern();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assert_eq!(result.to_string(), issue_pattern()?.to_string());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn with_config_get_repo() -> Result<()> {
|
||||||
|
//given
|
||||||
|
let fs = kxio::fs::temp()?;
|
||||||
|
let config = a_config(fs)?;
|
||||||
|
|
||||||
|
//when
|
||||||
|
let result = config.repo();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assert_eq!(result, "kemitix/test");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn a_config(fs: kxio::fs::FileSystem) -> Result<Config> {
|
||||||
|
Ok(Config::builder()
|
||||||
|
.fs(fs)
|
||||||
|
.server("https://git.kemitix.net".to_string())
|
||||||
|
.repo("kemitix/test".to_string())
|
||||||
|
.prefix_pattern(marker_pattern()?)
|
||||||
|
.issue_pattern(issue_pattern()?)
|
||||||
|
.build())
|
||||||
|
}
|
4
src/model/tests/mod.rs
Normal file
4
src/model/tests/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
//
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
mod config;
|
38
src/scanner.rs
Normal file
38
src/scanner.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
//
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use crate::model::{Config, FoundMarkers, Line, Marker};
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
pub fn find_markers(config: Config) -> Result<FoundMarkers, anyhow::Error> {
|
||||||
|
let mut markers = FoundMarkers::default();
|
||||||
|
for file in ignore::Walk::new(config.fs().base()).flatten() {
|
||||||
|
let path = file.path();
|
||||||
|
if config.fs().path_is_file(path)? {
|
||||||
|
scan_file(path, &config, &mut markers)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(markers)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn scan_file(file: &Path, config: &Config, found_markers: &mut FoundMarkers) -> Result<()> {
|
||||||
|
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)
|
||||||
|
.value(line.to_owned())
|
||||||
|
.build()
|
||||||
|
})
|
||||||
|
.filter_map(|line| line.into_marker().ok())
|
||||||
|
.filter(|marker| !matches!(marker, Marker::Unmarked))
|
||||||
|
.for_each(|marker| found_markers.add_marker(marker));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
94
src/tests/init.rs
Normal file
94
src/tests/init.rs
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
//
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use assert2::let_assert;
|
||||||
|
use model::Config;
|
||||||
|
use patterns::{issue_pattern, marker_pattern};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn init_when_all_valid() -> anyhow::Result<()> {
|
||||||
|
//given
|
||||||
|
let fs = kxio::fs::temp()?;
|
||||||
|
std::env::set_var("GITHUB_WORKSPACE", fs.base());
|
||||||
|
std::env::set_var("GITHUB_REPOSITORY", "repo");
|
||||||
|
std::env::set_var("GITHUB_SERVER_URL", "server");
|
||||||
|
let expected = Config::builder()
|
||||||
|
.fs(kxio::fs::new(fs.base().to_path_buf()))
|
||||||
|
.repo("repo".to_string())
|
||||||
|
.server("server".to_string())
|
||||||
|
.prefix_pattern(marker_pattern()?)
|
||||||
|
.issue_pattern(issue_pattern()?)
|
||||||
|
.maybe_auth_token(Some("auth".to_string()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//when
|
||||||
|
let result = init_config()?;
|
||||||
|
|
||||||
|
//then
|
||||||
|
assert_eq!(result.fs().base(), expected.fs().base());
|
||||||
|
assert_eq!(result.repo(), expected.repo());
|
||||||
|
// assert_eq!(result.server(), expected.server());
|
||||||
|
assert_eq!(
|
||||||
|
result.prefix_pattern().to_string(),
|
||||||
|
expected.prefix_pattern().to_string()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
result.issue_pattern().to_string(),
|
||||||
|
expected.issue_pattern().to_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn init_when_no_workspace() -> anyhow::Result<()> {
|
||||||
|
//given
|
||||||
|
std::env::remove_var("GITHUB_WORKSPACE");
|
||||||
|
std::env::set_var("GITHUB_REPOSITORY", "repo");
|
||||||
|
std::env::set_var("GITHUB_SERVER_URL", "server");
|
||||||
|
|
||||||
|
//when
|
||||||
|
let result = init_config();
|
||||||
|
|
||||||
|
//then
|
||||||
|
let_assert!(Err(e) = result);
|
||||||
|
assert_eq!(e.to_string(), "GITHUB_WORKSPACE");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn init_when_no_repository() -> anyhow::Result<()> {
|
||||||
|
//given
|
||||||
|
let fs = kxio::fs::temp()?;
|
||||||
|
std::env::set_var("GITHUB_WORKSPACE", fs.base());
|
||||||
|
std::env::remove_var("GITHUB_REPOSITORY");
|
||||||
|
std::env::set_var("GITHUB_SERVER_URL", "server");
|
||||||
|
|
||||||
|
//when
|
||||||
|
let result = init_config();
|
||||||
|
|
||||||
|
//then
|
||||||
|
let_assert!(Err(e) = result);
|
||||||
|
assert_eq!(e.to_string(), "GITHUB_REPOSITORY");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn init_when_no_server_url() -> anyhow::Result<()> {
|
||||||
|
//given
|
||||||
|
let fs = kxio::fs::temp()?;
|
||||||
|
std::env::set_var("GITHUB_WORKSPACE", fs.base());
|
||||||
|
std::env::set_var("GITHUB_REPOSITORY", "repo");
|
||||||
|
std::env::remove_var("GITHUB_SERVER_URL");
|
||||||
|
|
||||||
|
//when
|
||||||
|
let result = init_config();
|
||||||
|
|
||||||
|
//then
|
||||||
|
let_assert!(Err(e) = result);
|
||||||
|
assert_eq!(e.to_string(), "GITHUB_SERVER_URL");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
4
src/tests/mod.rs
Normal file
4
src/tests/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
//
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
mod init;
|
Loading…
Reference in a new issue