Compare commits

...

5 commits

Author SHA1 Message Date
76a047b9ca tests: add tests for init module
All checks were successful
Test / test (push) Successful in 7s
2024-09-19 20:19:05 +01:00
5357bbe4c5 refactor: split up main
All checks were successful
Test / test (push) Successful in 7s
2024-09-19 19:30:07 +01:00
64ddc6a6e6 tests: add tests for Config
All checks were successful
Test / test (push) Successful in 5s
2024-09-19 19:12:15 +01:00
92811bc074 refactor: comment out unused code in line
All checks were successful
Test / test (push) Successful in 7s
It will probably be uncommented again soon.
2024-09-19 18:30:33 +01:00
61351ba07a test: add tests for markers
All checks were successful
Test / test (push) Successful in 3m21s
2024-09-19 18:26:04 +01:00
18 changed files with 346 additions and 73 deletions

View file

@ -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
View 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)
}

View file

@ -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(())
}

View file

@ -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
} }

View file

@ -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() {

View file

@ -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(())
} }

View file

@ -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}"),
} }
} }
} }

View file

@ -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;

View 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(())
}

View file

View file

View file

@ -0,0 +1,6 @@
//
use super::*;
mod found;
mod issue;
mod marker;

View file

@ -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
View 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
View file

@ -0,0 +1,4 @@
//
use super::*;
mod config;

38
src/scanner.rs Normal file
View 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
View 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
View file

@ -0,0 +1,4 @@
//
use super::*;
mod init;